@cnbcool/cnb-cli 1.10.11 → 1.10.12

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.
Files changed (2) hide show
  1. package/dist/index.js +2 -2
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -87,7 +87,7 @@ ${s}
87
87
  CNB_PULL_REQUEST_IID - PR 编号(PR 相关快捷命令)
88
88
 
89
89
  默认只输出摘要信息,添加 --v 可输出全部信息
90
- `)}}function Sm(e,t){let r=process.env.CNB_REPO_SLUG||"";if(t)return{repo:r};let i=e==="issues"?process.env.CNB_ISSUE_IID||"":process.env.CNB_PULL_REQUEST_IID||"";return{repo:r,number:i}}function Im(e,t){if(!e||!t)return null;let r=e==="issues"?nt:e==="pulls"?ot:null;if(!r)return null;let i=r.find((a)=>a.shortName===t);if(!i)return null;let s=i.realTool,p=Sm(e,!!i.repoOnly),n=i.autoData||null;if(e==="pulls"&&i.realTool==="post-pull-comment"&&process.env.CNB_REVIEW_ID)s="post-pull-request-review-reply",p.review_id=process.env.CNB_REVIEW_ID,n={...n||{},reply_to_comment_id:process.env.CNB_REVIEW_ID};return{module:e,tool:s,autoPath:p,autoData:n,upload:!!i.upload,kind:i.kind}}});var To=o((he)=>{Object.defineProperty(he,"__esModule",{value:!0});he.handleIssueCreateUpload=Em;he.handleUpload=Fm;var ct=No(require("fs")),wo=No(require("path"));function No(e){return e&&e.__esModule?e:{default:e}}var Wm={".txt":"text/plain",".html":"text/html",".htm":"text/html",".css":"text/css",".csv":"text/csv",".js":"application/javascript",".mjs":"application/javascript",".json":"application/json",".xml":"application/xml",".pdf":"application/pdf",".zip":"application/zip",".gz":"application/gzip",".gzip":"application/gzip",".tar":"application/x-tar",".7z":"application/x-7z-compressed",".rar":"application/vnd.rar",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".webp":"image/webp",".ico":"image/x-icon",".bmp":"image/bmp",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".mp4":"video/mp4",".webm":"video/webm",".avi":"video/x-msvideo",".mov":"video/quicktime",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".md":"text/markdown",".yaml":"text/yaml",".yml":"text/yaml",".sh":"application/x-sh",".py":"text/x-python",".rb":"text/x-ruby",".go":"text/x-go",".rs":"text/x-rust",".ts":"text/typescript",".tsx":"text/typescript",".jsx":"text/jsx",".java":"text/x-java-source",".c":"text/x-c",".h":"text/x-c",".cpp":"text/x-c++src",".hpp":"text/x-c++hdr",".log":"text/plain",".patch":"text/x-diff",".diff":"text/x-diff"};function Vm(e){let t=wo.default.extname(e).toLowerCase();return Wm[t]||"application/octet-stream"}var zo=104857600;function qo(e){if(!e)return{ok:!1,result:{status:400,data:{error:`上传命令需要指定文件路径,如: --data '{"file":"./path/to/file"}'`}}};if(!ct.default.existsSync(e))return{ok:!1,result:{status:400,data:{error:`文件不存在: ${e}`}}};let t=ct.default.statSync(e);if(!t.isFile())return{ok:!1,result:{status:400,data:{error:`不是文件: ${e}`}}};let r=t.size;if(r===0)return{ok:!1,result:{status:400,data:{error:"文件为空"}}};if(r>zo)return{ok:!1,result:{status:400,data:{error:`文件过大 (${(r/1024/1024).toFixed(1)}MB),上限 ${zo/1024/1024}MB`}}};return{ok:!0,info:{filePath:e,fileName:wo.default.basename(e),fileSize:r,contentType:Vm(e)}}}async function Uo(e,t,r,i){let s=ct.default.createReadStream(e),p;try{p=await fetch(t,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(i)},body:s,duplex:"half"})}catch(n){throw s.destroy(),n}if(!p.ok){s.destroy();let n=await p.text().catch(()=>"");return{status:p.status,data:{error:`文件上传失败: ${p.statusText}`,detail:n}}}return}async function Em(e,t,r,i){let s=qo(t);if(!s.ok)return s.result;let{filePath:p,fileName:n,fileSize:a,contentType:y}=s.info,l=e.kind==="image"?"image":"file",u={name:n,size:a,content_type:y},g=l==="image"?{image_assets:[u]}:{file_assets:[u]},v=await r(i.repo,g),b=v?.data,f=(l==="image"?b?.image_upload_urls:b?.file_upload_urls)?.[0],m=f?.upload_url;if(!m)return v;let h=await Uo(p,m,y,a);if(h)return h;return{status:200,data:{asset_link:f?.asset_link,name:f?.name||n,path:f?.path,size:a,asset_group_id:b?.asset_group_id}}}async function Fm(e,t,r,i){let s=qo(t);if(!s.ok)return s.result;let{filePath:p,fileName:n,fileSize:a,contentType:y}=s.info,l,u;if(e.module==="issues"){if(!i.number)return{status:400,data:{error:"缺少 issue number(请确认 CNB_ISSUE_IID 是否已设置)"}};let v=await r({repo:i.repo,number:i.number},{name:n,size:a,content_type:y}),b=v?.data;if(l=b?.upload_url,!l)return v;u={asset_link:b?.asset_link,name:b?.name||n,path:b?.path,size:a}}else{let v=await r(i.repo,{name:n,size:a}),b=v?.data;if(l=b?.upload_url,!l)return v;u={name:b?.assets?.name||n,path:b?.assets?.path,size:a,token:b?.token}}let g=await Uo(p,l,y,a);if(g)return g;return{status:200,data:u}}});var So=o((dt)=>{Object.defineProperty(dt,"__esModule",{value:!0});dt.getTokenEnvKey=Jm;var Mm="cnb-app";function Jm(){return`WORKBUDDY_TOKEN_URL_${Mm.toUpperCase().replace(/-/g,"_")}`}});var Io=o((yt)=>{Object.defineProperty(yt,"__esModule",{value:!0});yt.isWorkBuddySandbox=Ym;function Ym(){return!!process.env.AGENTOS_RUNTIME_ID}});var te=o((lt)=>{Object.defineProperty(lt,"__esModule",{value:!0});lt.getTokenPath=Xm;var Zm=Wo(require("path")),$m=Wo(require("os"));function Wo(e){return e&&e.__esModule?e:{default:e}}function Xm(){return Zm.default.join($m.default.homedir(),".cnb","token")}});var ne=o((ut)=>{Object.defineProperty(ut,"__esModule",{value:!0});ut.loadToken=Bm;var Vo=Hm(require("fs")),Qm=te();function Hm(e){return e&&e.__esModule?e:{default:e}}function Bm(){let e=(0,Qm.getTokenPath)();if(!Vo.default.existsSync(e))return null;try{return JSON.parse(Vo.default.readFileSync(e,"utf-8"))}catch{return null}}});var gt=o((mt)=>{Object.defineProperty(mt,"__esModule",{value:!0});mt.resolveTokenSource=Rm;var Eo=So(),Gm=Io(),Om=ne();async function Rm(){if((0,Gm.isWorkBuddySandbox)()){let t=process.env[(0,Eo.getTokenEnvKey)()];if(!t)return{source:"none",reason:`未找到环境变量 ${(0,Eo.getTokenEnvKey)()},无法在 WorkBuddy 沙箱环境中获取 token。`};try{let r=await fetch(t,{method:"GET",headers:{Accept:"application/json"}});if(!r.ok)return{source:"none",reason:`从 WorkBuddy 获取 token 失败,HTTP 状态码: ${r.status} ${r.statusText}`};let i=await r.json();if(i?.code!==0||!i?.data?.access_token)return{source:"none",reason:`从 WorkBuddy 获取 token 失败,响应内容异常: ${JSON.stringify(i)}`};return{source:"workbuddy",access_token:i.data.access_token}}catch(r){return{source:"none",reason:`从 WorkBuddy 获取 token 失败: ${r?.message||r}`}}}if(process.env.CNB_TOKEN_FOR_CODEBUDDY){if(!process.env.CNB_NPC_SLUG&&process.env.CNB_NPC_NAME==="CodeBuddy")return{source:"codebuddy_env",access_token:process.env.CNB_TOKEN_FOR_CODEBUDDY}}if(process.env.CNB_TOKEN)return{source:"env",access_token:process.env.CNB_TOKEN};let e=(0,Om.loadToken)();if(!e||!e.access_token)return{source:"none"};return{source:"file",access_token:e.access_token,store:e}}});var _t=o((ht)=>{Object.defineProperty(ht,"__esModule",{value:!0});ht.saveToken=Cm;var bt=Fo(require("fs")),Lm=Fo(require("path")),Dm=te();function Fo(e){return e&&e.__esModule?e:{default:e}}function Cm(e){let t=(0,Dm.getTokenPath)(),r=Lm.default.dirname(t);if(!bt.default.existsSync(r))bt.default.mkdirSync(r,{recursive:!0});bt.default.writeFileSync(t,JSON.stringify(e,null,2),{mode:384})}});var _e=o((ft)=>{Object.defineProperty(ft,"__esModule",{value:!0});ft.refreshAccessToken=eg;var xm=_t();async function eg(e){if(!e.refresh_token)throw Error("no refresh_token");let t=e.platform_url||"https://cnb.cool",r=e.client_id||process.env.OAUTH2_CLIENT_ID||"cnb_cli",i=`${t.replace(/\/+$/,"")}/oauth2/token`,s=new URLSearchParams;s.set("grant_type","refresh_token"),s.set("refresh_token",e.refresh_token),s.set("client_id",r);let p=Math.floor(Date.now()/1000),n=await fetch(i,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()});if(n.status!==200){let l=await n.text();throw Error(`refresh token failed: status=${n.status} body=${l}`)}let a=await n.json(),y={access_token:a.access_token,expires_at:p+a.expires_in,refresh_token:a.refresh_token||e.refresh_token,platform_url:e.platform_url,client_id:e.client_id,login_host:e.login_host};return(0,xm.saveToken)(y),a.access_token}});var fe=o((vt)=>{Object.defineProperty(vt,"__esModule",{value:!0});vt.resolveToken=ig;var tg=gt(),rg=_e();async function ig(){let e=await(0,tg.resolveTokenSource)();if(e.source==="none")console.error(e.reason||"未找到有效的登录凭证,请先执行 `cnb login` 进行授权。"),process.exit(1);if(e.source==="workbuddy"||e.source==="codebuddy_env"||e.source==="env")return e.access_token;let t=e.store;if(Math.floor(Date.now()/1000)<t.expires_at)return e.access_token;if(t.refresh_token)try{return await(0,rg.refreshAccessToken)(t)}catch(i){console.error(`Token 已过期,刷新失败: ${i.message}`),console.error("请重新执行 `cnb login` 进行授权。"),process.exit(1)}console.error("Token 已过期且无 refresh_token,请重新执行 `cnb login` 进行授权。"),process.exit(1)}});var jt=o((Pt)=>{Object.defineProperty(Pt,"__esModule",{value:!0});Pt.resolveApiDomain=pg;var sg=ne();function pg(){let e=process.env.CNB_API_ENDPOINT||"https://api.cnb.cool";if(process.env.CNB_TOKEN_FOR_CODEBUDDY||process.env.CNB_TOKEN)return e;let t=(0,sg.loadToken)();if(t?.login_host)return t.login_host;return e}});var kt=o((V)=>{Object.defineProperty(V,"__esModule",{value:!0});V.SN_PATTERN=void 0;V.apiRequest=Jo;V.apiRequestText=ag;V.extractSnFromStatuses=Yo;V.extractSnFromUrl=At;V.invalidSnMessage=Mo;V.resolveBuildContext=cg;var ng=fe(),og=jt(),Kt=V.SN_PATTERN=/^cnb-[a-z0-9]+-[a-z0-9]+$/i;function Mo(e){return[`参数 --sn 的值不是合法的构建号: "${e}"`,"","构建号(sn)格式应为 cnb-xxx-xxxxxxxxx,例如 cnb-9p9-1jnfh8rv5。","常见错误:把 `cnb pulls check-status` 返回的 context 字段(形如",'"cnb/pull_request/common-lint")当成 sn 传入,这是 CI 状态的检查项名,',"不是构建号。","","请去掉 --sn 参数重试,工具会自动从当前 PR 的 CI 状态中解析失败构建的 sn。"].join(`
90
+ `)}}function Sm(e,t){let r=process.env.CNB_REPO_SLUG||"";if(t)return{repo:r};let i=e==="issues"?process.env.CNB_ISSUE_IID||"":process.env.CNB_PULL_REQUEST_IID||"";return{repo:r,number:i}}function Im(e,t){if(!e||!t)return null;let r=e==="issues"?nt:e==="pulls"?ot:null;if(!r)return null;let i=r.find((a)=>a.shortName===t);if(!i)return null;let s=i.realTool,p=Sm(e,!!i.repoOnly),n=i.autoData||null;if(e==="pulls"&&i.realTool==="post-pull-comment"&&process.env.CNB_REVIEW_ID)s="post-pull-request-review-reply",p.review_id=process.env.CNB_REVIEW_ID,n={...n||{},reply_to_comment_id:process.env.CNB_REVIEW_ID};return{module:e,tool:s,autoPath:p,autoData:n,upload:!!i.upload,kind:i.kind}}});var To=o((he)=>{Object.defineProperty(he,"__esModule",{value:!0});he.handleIssueCreateUpload=Em;he.handleUpload=Fm;var ct=No(require("fs")),wo=No(require("path"));function No(e){return e&&e.__esModule?e:{default:e}}var Wm={".txt":"text/plain",".html":"text/html",".htm":"text/html",".css":"text/css",".csv":"text/csv",".js":"application/javascript",".mjs":"application/javascript",".json":"application/json",".xml":"application/xml",".pdf":"application/pdf",".zip":"application/zip",".gz":"application/gzip",".gzip":"application/gzip",".tar":"application/x-tar",".7z":"application/x-7z-compressed",".rar":"application/vnd.rar",".doc":"application/msword",".docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document",".xls":"application/vnd.ms-excel",".xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",".ppt":"application/vnd.ms-powerpoint",".pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".webp":"image/webp",".ico":"image/x-icon",".bmp":"image/bmp",".mp3":"audio/mpeg",".wav":"audio/wav",".ogg":"audio/ogg",".mp4":"video/mp4",".webm":"video/webm",".avi":"video/x-msvideo",".mov":"video/quicktime",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".md":"text/markdown",".yaml":"text/yaml",".yml":"text/yaml",".sh":"application/x-sh",".py":"text/x-python",".rb":"text/x-ruby",".go":"text/x-go",".rs":"text/x-rust",".ts":"text/typescript",".tsx":"text/typescript",".jsx":"text/jsx",".java":"text/x-java-source",".c":"text/x-c",".h":"text/x-c",".cpp":"text/x-c++src",".hpp":"text/x-c++hdr",".log":"text/plain",".patch":"text/x-diff",".diff":"text/x-diff"};function Vm(e){let t=wo.default.extname(e).toLowerCase();return Wm[t]||"application/octet-stream"}var zo=104857600;function qo(e){if(!e)return{ok:!1,result:{status:400,data:{error:`上传命令需要指定文件路径,如: --data '{"file":"./path/to/file"}'`}}};if(!ct.default.existsSync(e))return{ok:!1,result:{status:400,data:{error:`文件不存在: ${e}`}}};let t=ct.default.statSync(e);if(!t.isFile())return{ok:!1,result:{status:400,data:{error:`不是文件: ${e}`}}};let r=t.size;if(r===0)return{ok:!1,result:{status:400,data:{error:"文件为空"}}};if(r>zo)return{ok:!1,result:{status:400,data:{error:`文件过大 (${(r/1024/1024).toFixed(1)}MB),上限 ${zo/1024/1024}MB`}}};return{ok:!0,info:{filePath:e,fileName:wo.default.basename(e),fileSize:r,contentType:Vm(e)}}}async function Uo(e,t,r,i){let s=ct.default.createReadStream(e),p;try{p=await fetch(t,{method:"PUT",headers:{"Content-Type":r,"Content-Length":String(i)},body:s,duplex:"half"})}catch(n){throw s.destroy(),n}if(!p.ok){s.destroy();let n=await p.text().catch(()=>"");return{status:p.status,data:{error:`文件上传失败: ${p.statusText}`,detail:n}}}return}async function Em(e,t,r,i){let s=qo(t);if(!s.ok)return s.result;let{filePath:p,fileName:n,fileSize:a,contentType:y}=s.info,l=e.kind==="image"?"image":"file",u={name:n,size:a,content_type:y},g=l==="image"?{image_assets:[u]}:{file_assets:[u]},v=await r(i.repo,g),b=v?.data,f=(l==="image"?b?.image_upload_urls:b?.file_upload_urls)?.[0],m=f?.upload_url;if(!m)return v;let h=await Uo(p,m,y,a);if(h)return h;return{status:200,data:{asset_link:f?.asset_link,name:f?.name||n,path:f?.path,size:a,asset_group_id:b?.asset_group_id,download_url:f?.download_url}}}async function Fm(e,t,r,i){let s=qo(t);if(!s.ok)return s.result;let{filePath:p,fileName:n,fileSize:a,contentType:y}=s.info,l,u;if(e.module==="issues"){if(!i.number)return{status:400,data:{error:"缺少 issue number(请确认 CNB_ISSUE_IID 是否已设置)"}};let v=await r({repo:i.repo,number:i.number},{name:n,size:a,content_type:y}),b=v?.data;if(l=b?.upload_url,!l)return v;u={asset_link:b?.asset_link,name:b?.name||n,path:b?.path,size:a,download_url:b?.download_url}}else{let v=await r(i.repo,{name:n,size:a}),b=v?.data;if(l=b?.upload_url,!l)return v;u={name:b?.assets?.name||n,path:b?.assets?.path,size:a,token:b?.token}}let g=await Uo(p,l,y,a);if(g)return g;return{status:200,data:u}}});var So=o((dt)=>{Object.defineProperty(dt,"__esModule",{value:!0});dt.getTokenEnvKey=Jm;var Mm="cnb-app";function Jm(){return`WORKBUDDY_TOKEN_URL_${Mm.toUpperCase().replace(/-/g,"_")}`}});var Io=o((yt)=>{Object.defineProperty(yt,"__esModule",{value:!0});yt.isWorkBuddySandbox=Ym;function Ym(){return!!process.env.AGENTOS_RUNTIME_ID}});var te=o((lt)=>{Object.defineProperty(lt,"__esModule",{value:!0});lt.getTokenPath=Xm;var Zm=Wo(require("path")),$m=Wo(require("os"));function Wo(e){return e&&e.__esModule?e:{default:e}}function Xm(){return Zm.default.join($m.default.homedir(),".cnb","token")}});var ne=o((ut)=>{Object.defineProperty(ut,"__esModule",{value:!0});ut.loadToken=Bm;var Vo=Hm(require("fs")),Qm=te();function Hm(e){return e&&e.__esModule?e:{default:e}}function Bm(){let e=(0,Qm.getTokenPath)();if(!Vo.default.existsSync(e))return null;try{return JSON.parse(Vo.default.readFileSync(e,"utf-8"))}catch{return null}}});var gt=o((mt)=>{Object.defineProperty(mt,"__esModule",{value:!0});mt.resolveTokenSource=Rm;var Eo=So(),Gm=Io(),Om=ne();async function Rm(){if((0,Gm.isWorkBuddySandbox)()){let t=process.env[(0,Eo.getTokenEnvKey)()];if(!t)return{source:"none",reason:`未找到环境变量 ${(0,Eo.getTokenEnvKey)()},无法在 WorkBuddy 沙箱环境中获取 token。`};try{let r=await fetch(t,{method:"GET",headers:{Accept:"application/json"}});if(!r.ok)return{source:"none",reason:`从 WorkBuddy 获取 token 失败,HTTP 状态码: ${r.status} ${r.statusText}`};let i=await r.json();if(i?.code!==0||!i?.data?.access_token)return{source:"none",reason:`从 WorkBuddy 获取 token 失败,响应内容异常: ${JSON.stringify(i)}`};return{source:"workbuddy",access_token:i.data.access_token}}catch(r){return{source:"none",reason:`从 WorkBuddy 获取 token 失败: ${r?.message||r}`}}}if(process.env.CNB_TOKEN_FOR_CODEBUDDY){if(!process.env.CNB_NPC_SLUG&&process.env.CNB_NPC_NAME==="CodeBuddy")return{source:"codebuddy_env",access_token:process.env.CNB_TOKEN_FOR_CODEBUDDY}}if(process.env.CNB_TOKEN)return{source:"env",access_token:process.env.CNB_TOKEN};let e=(0,Om.loadToken)();if(!e||!e.access_token)return{source:"none"};return{source:"file",access_token:e.access_token,store:e}}});var _t=o((ht)=>{Object.defineProperty(ht,"__esModule",{value:!0});ht.saveToken=Cm;var bt=Fo(require("fs")),Lm=Fo(require("path")),Dm=te();function Fo(e){return e&&e.__esModule?e:{default:e}}function Cm(e){let t=(0,Dm.getTokenPath)(),r=Lm.default.dirname(t);if(!bt.default.existsSync(r))bt.default.mkdirSync(r,{recursive:!0});bt.default.writeFileSync(t,JSON.stringify(e,null,2),{mode:384})}});var _e=o((ft)=>{Object.defineProperty(ft,"__esModule",{value:!0});ft.refreshAccessToken=eg;var xm=_t();async function eg(e){if(!e.refresh_token)throw Error("no refresh_token");let t=e.platform_url||"https://cnb.cool",r=e.client_id||process.env.OAUTH2_CLIENT_ID||"cnb_cli",i=`${t.replace(/\/+$/,"")}/oauth2/token`,s=new URLSearchParams;s.set("grant_type","refresh_token"),s.set("refresh_token",e.refresh_token),s.set("client_id",r);let p=Math.floor(Date.now()/1000),n=await fetch(i,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:s.toString()});if(n.status!==200){let l=await n.text();throw Error(`refresh token failed: status=${n.status} body=${l}`)}let a=await n.json(),y={access_token:a.access_token,expires_at:p+a.expires_in,refresh_token:a.refresh_token||e.refresh_token,platform_url:e.platform_url,client_id:e.client_id,login_host:e.login_host};return(0,xm.saveToken)(y),a.access_token}});var fe=o((vt)=>{Object.defineProperty(vt,"__esModule",{value:!0});vt.resolveToken=ig;var tg=gt(),rg=_e();async function ig(){let e=await(0,tg.resolveTokenSource)();if(e.source==="none")console.error(e.reason||"未找到有效的登录凭证,请先执行 `cnb login` 进行授权。"),process.exit(1);if(e.source==="workbuddy"||e.source==="codebuddy_env"||e.source==="env")return e.access_token;let t=e.store;if(Math.floor(Date.now()/1000)<t.expires_at)return e.access_token;if(t.refresh_token)try{return await(0,rg.refreshAccessToken)(t)}catch(i){console.error(`Token 已过期,刷新失败: ${i.message}`),console.error("请重新执行 `cnb login` 进行授权。"),process.exit(1)}console.error("Token 已过期且无 refresh_token,请重新执行 `cnb login` 进行授权。"),process.exit(1)}});var jt=o((Pt)=>{Object.defineProperty(Pt,"__esModule",{value:!0});Pt.resolveApiDomain=pg;var sg=ne();function pg(){let e=process.env.CNB_API_ENDPOINT||"https://api.cnb.cool";if(process.env.CNB_TOKEN_FOR_CODEBUDDY||process.env.CNB_TOKEN)return e;let t=(0,sg.loadToken)();if(t?.login_host)return t.login_host;return e}});var kt=o((V)=>{Object.defineProperty(V,"__esModule",{value:!0});V.SN_PATTERN=void 0;V.apiRequest=Jo;V.apiRequestText=ag;V.extractSnFromStatuses=Yo;V.extractSnFromUrl=At;V.invalidSnMessage=Mo;V.resolveBuildContext=cg;var ng=fe(),og=jt(),Kt=V.SN_PATTERN=/^cnb-[a-z0-9]+-[a-z0-9]+$/i;function Mo(e){return[`参数 --sn 的值不是合法的构建号: "${e}"`,"","构建号(sn)格式应为 cnb-xxx-xxxxxxxxx,例如 cnb-9p9-1jnfh8rv5。","常见错误:把 `cnb pulls check-status` 返回的 context 字段(形如",'"cnb/pull_request/common-lint")当成 sn 传入,这是 CI 状态的检查项名,',"不是构建号。","","请去掉 --sn 参数重试,工具会自动从当前 PR 的 CI 状态中解析失败构建的 sn。"].join(`
91
91
  `)}async function Jo(e,t){let r=await fetch(e,{headers:t});if(!r.ok)throw Error(`请求失败: ${r.status} ${r.statusText} — ${e}`);return r.json()}async function ag(e,t){let r=await fetch(e,{headers:t});if(!r.ok)throw Error(`请求失败: ${r.status} ${r.statusText} — ${e}`);return r.text()}function Yo(e){let t=e?.statuses||e;if(!Array.isArray(t)||t.length===0)return null;let r=t.find((i)=>i.state==="error"||i.state==="failure");if(!r)return null;return At(r.target_url||"")}function At(e){if(!e)return null;let t=e.match(/\/-\/build\/logs\/([^/?#]+)/);if(t&&Kt.test(t[1]))return t[1];let r=e.match(/\/-\/build\/([^/?#]+)/);if(r&&Kt.test(r[1]))return r[1];return null}async function cg(e){let t=(0,og.resolveApiDomain)(),{repo:r}=e,i=e.sn;if(i&&!Kt.test(i))return{ok:!1,message:Mo(i)};let p={Accept:"application/vnd.cnb.api+json",Authorization:`Bearer ${await(0,ng.resolveToken)()}`};if(!i&&e.prNumber)try{let n=`${t}/${r}/-/pulls/${e.prNumber}/commit-statuses`,a=await Jo(n,p);if(i=Yo(a)??void 0,!i&&e.fallbackToLatestStatus){let y=a?.statuses||a;if(Array.isArray(y))for(let l of y){let u=At(l?.target_url||"");if(u){i=u;break}}}}catch(n){return{ok:!1,message:`获取 PR CI 状态失败: ${n.message}`}}if(!i){if(e.prNumber)return{ok:!1,message:e.fallbackToLatestStatus?"未从 PR CI 状态中找到任何可分析的构建。":"未从 PR CI 状态中找到失败的构建,所有构建均为成功状态。"};return{ok:!1,message:"缺少构建号(sn):未传入 --sn 且未检测到 PR 上下文(CNB_PULL_REQUEST_IID)。"}}return{ok:!0,ctx:{sn:i,domain:t,baseUrl:`${t}/${r}`,headers:p}}}});var Zo=o((zt)=>{Object.defineProperty(zt,"__esModule",{value:!0});zt.diagnoseBuild=yg;var ve=kt();async function dg(e,t,r){let i=await(0,ve.apiRequestText)(`${e}/-/build/logs/${t}`,r);try{let s=JSON.parse(i);if(s.data&&typeof s.data==="string")return Buffer.from(s.data,"base64").toString("utf-8");if(s.data?.data&&typeof s.data.data==="string")return Buffer.from(s.data.data,"base64").toString("utf-8");return JSON.stringify(s,null,2)}catch{return i}}async function yg(e){let t=await(0,ve.resolveBuildContext)(e);if(!t.ok)return t.message;let{sn:r,baseUrl:i,headers:s}=t.ctx,p=[];p.push(`查询构建 sn=${r} 的流水线状态...
92
92
  `);let n;try{n=await(0,ve.apiRequest)(`${i}/-/build/status/${r}`,s)}catch(l){return`获取构建状态失败: ${l.message}`}if(!n.pipelinesStatus||typeof n.pipelinesStatus!=="object")return p.push("未找到流水线状态信息"),p.push("返回数据:"),p.push(JSON.stringify(n,null,2)),p.join(`
93
93
  `);let a=Object.entries(n.pipelinesStatus);if(a.length===0)return"该构建没有流水线";let y=!1;for(let[l,u]of a){let{id:g,status:v,stages:b}=u;if(!Array.isArray(b))continue;let _=b.filter((f)=>f.status==="error");if(_.length===0)continue;y=!0,p.push(`━━━ 流水线: ${l} (status: ${v}) ━━━
@@ -123,4 +123,4 @@ PR 页面路径: ${s}
123
123
  登录成功 \uD83C\uDF89`),r.debug){if(console.log(` token_type : ${n.token_type}`),console.log(` expires_in : ${n.expires_in}`),console.log(` scope : ${n.scope||""}`),console.log(` access_token : ${(0,O.maskToken)(n.access_token)}`),n.refresh_token)console.log(` refresh_token : ${(0,O.maskToken)(n.refresh_token)}`);if(n.id_token)console.log(` id_token : ${(0,O.maskToken)(n.id_token)}`)}let a=Math.floor(Date.now()/1000),l=`https://api.${new URL(r.platformURL).hostname}`,u={access_token:n.access_token,expires_at:a+n.expires_in,platform_url:r.platformURL,client_id:r.clientID,login_host:l};if(n.refresh_token)u.refresh_token=n.refresh_token;if((0,O.saveToken)(u),r.debug)console.log(`Token 已保存到 ${(0,O.getTokenPath)()}`)}catch(s){console.error(`
124
124
  登录失败: ${s.message}`),process.exit(1)}})}});var Lu=o((Rn)=>{Object.defineProperty(Rn,"__esModule",{value:!0});Rn.registerLogoutCommand=II;var qI=SI(require("fs")),UI=te(),TI=ne();function SI(e){return e&&e.__esModule?e:{default:e}}function II(e){e.command("logout").description("退出登录,删除本地保存的 access_token").option("--debug","打印调试信息",!1).helpOption("-h, --help","显示帮助文档").action(async(t)=>{let r=(0,UI.getTokenPath)(),i=(0,TI.loadToken)();if(!i){console.log("当前未登录,无需退出。");return}if(t.debug)console.log(`Token 文件路径: ${r}`),console.log(`Platform URL : ${i.platform_url}`),console.log(`Client ID : ${i.client_id}`);try{qI.default.unlinkSync(r),console.log("已成功退出登录。")}catch(s){console.error(`退出登录失败: ${s.message}`),process.exit(1)}})}});var Du=o((Ln)=>{Object.defineProperty(Ln,"__esModule",{value:!0});Ln.registerStatusCommand=MI;var WI=gt(),VI=_e(),EI=te(),FI={workbuddy:"WorkBuddy 远程获取",codebuddy_env:"CNB_TOKEN_FOR_CODEBUDDY 环境变量",env:"CNB_TOKEN 环境变量"};function MI(e){e.command("status").description("检查当前登录状态(token 是否存在、是否过期)").option("--debug","打印调试信息",!1).helpOption("-h, --help","显示帮助文档").action(async(t)=>{let r=await(0,WI.resolveTokenSource)();if(r.source==="none"){console.log(r.reason?`⚠️ ${r.reason}`:"⚠️ 未登录,请执行 `cnb login` 进行授权。");return}if(r.source!=="file"){if(console.log("✅ 已登录。"),t.debug)console.log(` Token 来源: ${FI[r.source]}`);return}let i=(0,EI.getTokenPath)(),s=r.store;if(t.debug)console.log(`Token 文件路径 : ${i}`),console.log(`Platform URL : ${s.platform_url||"未知"}`),console.log(`Client ID : ${s.client_id||"未知"}`),console.log(`Expires At : ${new Date(s.expires_at*1000).toLocaleString()}`);if(Math.floor(Date.now()/1000)>=s.expires_at)if(s.refresh_token){if(t.debug)console.log("Token 已过期,尝试使用 refresh_token 刷新...");try{if(await(0,VI.refreshAccessToken)(s),console.log("✅ 已登录。"),t.debug)console.log(" (Token 已自动刷新)")}catch(a){if(t.debug)console.log(`刷新失败: ${a.message}`);console.log("⚠️ 未登录,请执行 `cnb login` 重新授权。")}}else console.log("⚠️ 未登录,请执行 `cnb login` 重新授权。");else console.log("✅ 已登录。")})}});var Cu=o((Dn)=>{Object.defineProperty(Dn,"__esModule",{value:!0});Dn.registerGitCredentialCommand=$I;var JI=fe(),YI=["cnb.cool","cnb.woa.com"],ZI=8000;function $I(e){e.command("git-credential <action>").description("作为 git credential helper,向 git 提供 CNB 凭据(仅供 git 内部调用)").allowUnknownOption().allowExcessArguments().helpOption("-h, --help","显示帮助文档").action(async(t,r,i)=>{let s=i.args.slice(0,-1);if(s.length>0)console.error(`[git-credential]: custom args: ${s.join(" ")}`);if(t==="store"||t==="erase")console.error(`[git-credential]: ${t} ignored`),process.exit(0);if(t!=="get")console.error(`[git-credential]: unknown action: ${t}`),process.exit(1);try{let p=await BI(ZI),n=GI(p,"=");HI(n),await XI(n),process.exit(0)}catch(p){console.error(p?.message?p.message:String(p)),process.exit(2)}})}async function XI(e){let{host:t}=e;if(console.error(`[git-credential]: for ${e.protocol}://${e.host}/${e.path??""}`),!t||!YI.includes(t))throw Error(`unknown host: ${t}`);let r=await QI(e);process.stdout.write(`username=${r.username}
125
125
  `),process.stdout.write(`password=${r.password}
126
- `),console.error("[git-credential]: done")}async function QI(e){return{username:"cnb",password:await(0,JI.resolveToken)()}}function HI(e){if(!e.path)return;if(e.path.endsWith(".git"))e.path=e.path.slice(0,-4);else if(e.path.endsWith(".git/info/lfs"))e.path=e.path.slice(0,-13)}function BI(e){return new Promise((t,r)=>{let i=[],s=!1,p=()=>{if(s)return;s=!0,clearTimeout(n),t(Buffer.concat(i).toString("utf-8"))},n=setTimeout(()=>{if(s)return;s=!0,console.error("[git-credential]: timeout occurred"),r(Error("stdin timeout"))},e);process.stdin.on("data",(a)=>{if(i.push(a),a.length===1&&a[0]===10)p()}),process.stdin.on("end",()=>{p()}),process.stdin.on("error",(a)=>{if(s)return;s=!0,clearTimeout(n),r(a)})})}function GI(e,t){return e.split(/(?:\r\n|\r|\n)/).filter(Boolean).map((r)=>{let i=r.indexOf(t),s=i>=0?r.substring(0,i).trim():r.trim(),p=i>=0?r.substring(i+1).trim():"";return{key:s,value:p}}).reduce((r,{key:i,value:s})=>{if(i)r[i]=s;return r},{})}});Object.defineProperty(exports,"__esModule",{value:!0});Object.defineProperty(exports,"parseArguments",{enumerable:!0,get:function(){return r4.parseUnknownOptions}});var OI=tt(),RI=bo(),LI=Zu(),DI=$u(),CI=Ru(),xI=Lu(),e4=Du(),t4=Cu(),r4=St(),R=new OI.Command;R.name("cnb").description("CNB OpenAPI 命令行工具").version("1.10.11","-v, --version","显示版本号").allowUnknownOption().allowExcessArguments().helpOption("-h, --help","显示帮助文档").option("-s, --short","显示当前仓库的快捷命令").addHelpText("after",(0,RI.getExtraHelpText)());(0,CI.registerLoginCommand)(R);(0,xI.registerLogoutCommand)(R);(0,e4.registerStatusCommand)(R);(0,t4.registerGitCredentialCommand)(R);(0,LI.registerModuleCommands)(R);(0,DI.registerFallbackAction)(R);R.parseAsync(process.argv);
126
+ `),console.error("[git-credential]: done")}async function QI(e){return{username:"cnb",password:await(0,JI.resolveToken)()}}function HI(e){if(!e.path)return;if(e.path.endsWith(".git"))e.path=e.path.slice(0,-4);else if(e.path.endsWith(".git/info/lfs"))e.path=e.path.slice(0,-13)}function BI(e){return new Promise((t,r)=>{let i=[],s=!1,p=()=>{if(s)return;s=!0,clearTimeout(n),t(Buffer.concat(i).toString("utf-8"))},n=setTimeout(()=>{if(s)return;s=!0,console.error("[git-credential]: timeout occurred"),r(Error("stdin timeout"))},e);process.stdin.on("data",(a)=>{if(i.push(a),a.length===1&&a[0]===10)p()}),process.stdin.on("end",()=>{p()}),process.stdin.on("error",(a)=>{if(s)return;s=!0,clearTimeout(n),r(a)})})}function GI(e,t){return e.split(/(?:\r\n|\r|\n)/).filter(Boolean).map((r)=>{let i=r.indexOf(t),s=i>=0?r.substring(0,i).trim():r.trim(),p=i>=0?r.substring(i+1).trim():"";return{key:s,value:p}}).reduce((r,{key:i,value:s})=>{if(i)r[i]=s;return r},{})}});Object.defineProperty(exports,"__esModule",{value:!0});Object.defineProperty(exports,"parseArguments",{enumerable:!0,get:function(){return r4.parseUnknownOptions}});var OI=tt(),RI=bo(),LI=Zu(),DI=$u(),CI=Ru(),xI=Lu(),e4=Du(),t4=Cu(),r4=St(),R=new OI.Command;R.name("cnb").description("CNB OpenAPI 命令行工具").version("1.10.12","-v, --version","显示版本号").allowUnknownOption().allowExcessArguments().helpOption("-h, --help","显示帮助文档").option("-s, --short","显示当前仓库的快捷命令").addHelpText("after",(0,RI.getExtraHelpText)());(0,CI.registerLoginCommand)(R);(0,xI.registerLogoutCommand)(R);(0,e4.registerStatusCommand)(R);(0,t4.registerGitCredentialCommand)(R);(0,LI.registerModuleCommands)(R);(0,DI.registerFallbackAction)(R);R.parseAsync(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cnbcool/cnb-cli",
3
- "version": "1.10.11",
3
+ "version": "1.10.12",
4
4
  "description": "CNB OpenAPI 命令行工具,基于 CNB 平台 Swagger 自动生成,支持 Issues、PR、Git、组织管理等全部 API 操作",
5
5
  "main": "skills/cnb-api/scripts/core/index.js",
6
6
  "bin": {
@@ -42,7 +42,7 @@
42
42
  "author": "",
43
43
  "license": "MIT",
44
44
  "devDependencies": {
45
- "@cnbcool/cnb-api-generate": "^2.11.2",
45
+ "@cnbcool/cnb-api-generate": "^2.11.3",
46
46
  "bun": "^1.3.9",
47
47
  "skills": "^1.4.4"
48
48
  }