@round2ai/r2-cli 1.0.9 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -44
- package/dist/README.md +23 -44
- package/dist/package.json +3 -1
- package/dist/pages/login.html +2 -7
- package/dist/pages/xianyu-auth.html +3 -9
- package/dist/r2-cli.js +39 -43
- package/package.json +3 -1
- package/scripts/build.js +176 -0
- package/scripts/dev.js +22 -0
- package/scripts/install-skills.js +54 -0
- package/skills/r2-auth/SKILL.md +98 -30
- package/skills/r2-cli/SKILL.md +21 -21
- package/skills/r2-goods/SKILL.md +125 -25
package/dist/r2-cli.js
CHANGED
|
@@ -1,51 +1,47 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
`;process.stdout.write(
|
|
3
|
+
var Ue=Object.defineProperty;var Y=(e,t)=>()=>(e&&(t=e(e=0)),t);var V=(e,t)=>{for(var o in t)Ue(e,o,{get:t[o],enumerable:!0})};var Kt={};V(Kt,{UserInfoCard:()=>Ve});import{Box as Q,Text as E}from"ink";import{jsx as O,jsxs as _}from"react/jsx-runtime";function Ve({userInfo:e,lastLogin:t,daysSinceLogin:o}){let r=e.mobile?e.mobile.replace(/(\d{3})\d{4}(\d{4})/,"$1****$2"):"-";return _(Q,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[O(E,{bold:!0,color:"cyan",children:"\u7528\u6237\u4FE1\u606F"}),_(Q,{flexDirection:"row",marginTop:1,children:[O(Q,{width:10,children:O(E,{color:"gray",children:"\u6635\u79F0"})}),O(E,{color:"yellow",children:e.nickname})]}),_(Q,{flexDirection:"row",children:[O(Q,{width:10,children:O(E,{color:"gray",children:"\u624B\u673A\u53F7"})}),O(E,{color:"yellow",children:r})]}),t&&_(Q,{flexDirection:"column",marginTop:1,children:[_(E,{color:"gray",children:["\u6700\u540E\u767B\u5F55: ",t.toLocaleString()]}),o!==void 0&&_(E,{color:"gray",children:[" \u8DDD\u4ECA: ",o," \u5929"]})]})]})}var Yt=Y(()=>{"use strict"});var ot={};V(ot,{renderComponent:()=>oo,renderOnce:()=>Vt});import Ze from"react";import Tt from"chalk";import{render as to}from"ink";import{Writable as eo}from"node:stream";function Vt(e){let t=Tt.level;process.env.NO_COLOR||(Tt.level=3);try{let o=[],r=new eo({write(l,d,g){o.push(Buffer.from(l)),g()}});r.isTTY=!0,r.columns=process.stdout.columns||80,r.rows=process.stdout.rows||24,to(e,{stdout:r,patchConsole:!1}).unmount();let s=Buffer.concat(o).toString("utf8"),a=(s.split(/\x1B\[2J\x1B\[3J\x1B\[H/).at(-1)||s).replace(/\x1B\[\?[\d;]+[hl]/g,"").trimEnd()+`
|
|
4
|
+
`;process.stdout.write(a)}finally{Tt.level=t}}function oo(e,t){Vt(Ze.createElement(e,t))}var rt=Y(()=>{"use strict"});var pe={};V(pe,{ShopsTable:()=>yo});import{Box as w,Text as C}from"ink";import{jsx as p,jsxs as M}from"react/jsx-runtime";function go(e){return e.map(t=>"shopName"in t?{id:t.shopId,name:t.shopName,platform:t.platform,expiresIn:t.expiresIn}:{id:t.id,name:t.name,platform:t.thirdUserId,expiresIn:t.expiresIn})}function fo({hasPlatform:e,fillWidth:t}){return M(w,{flexDirection:"row",paddingBottom:0,children:[e&&p(w,{width:Ut,children:p(C,{bold:!0,color:"white",children:"\u5E73\u53F0"})}),p(w,{width:t,children:p(C,{bold:!0,color:"white",children:"\u5E97\u94FA\u540D"})}),p(w,{width:Dt,children:p(C,{bold:!0,color:"white",children:"ID"})}),p(w,{width:$t,children:p(C,{bold:!0,color:"white",children:"\u72B6\u6001"})})]})}function ho({shop:e,hasPlatform:t,fillWidth:o}){let r=de[e.platform]??e.platform;return M(w,{flexDirection:"row",children:[t&&p(w,{width:Ut,children:p(C,{color:"cyan",children:r})}),p(w,{width:o,children:p(C,{bold:!0,children:e.name})}),p(w,{width:Dt,children:p(C,{color:"gray",children:e.id})}),p(w,{width:$t,children:p(C,{color:"green",children:"\u25CF \u6388\u6743\u4E2D"})})]})}function yo({shops:e,platform:t}){let o=go(e),r=t==="all",n=t==="all"?"\u6240\u6709\u6388\u6743\u5E97\u94FA":`${de[t]??t}\u6388\u6743\u5E97\u94FA`,s=process.stdout.columns||80,i=4,a=Dt+$t+(r?Ut:0),l=Math.max(s-i-a,20),d=a+l;return M(w,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[M(w,{flexDirection:"row",children:[p(C,{bold:!0,color:"cyan",children:n}),M(C,{color:"gray",children:[" \xB7 ",o.length," \u5BB6"]})]}),M(w,{flexDirection:"column",marginTop:1,children:[p(fo,{hasPlatform:r,fillWidth:l}),p(C,{color:"gray",children:"\u2500".repeat(d)}),o.map(g=>p(ho,{shop:g,hasPlatform:r,fillWidth:l},g.id))]})]})}var de,Ut,Dt,$t,ge=Y(()=>{"use strict";de={xianyu:"\u95F2\u9C7C",douyin:"\u6296\u97F3"},Ut=8,Dt=16,$t=10});var ye={};V(ye,{StocksTable:()=>Co});import{Box as h,Text as x}from"ink";import{jsx as u,jsxs as X}from"react/jsx-runtime";function xo({fillWidth:e}){return X(h,{flexDirection:"row",paddingBottom:0,children:[u(h,{width:jt,children:u(x,{bold:!0,color:"white",children:"ID"})}),u(h,{width:Gt,children:u(x,{bold:!0,color:"white",children:"\u7528\u6237ID"})}),u(h,{width:Bt,children:u(x,{bold:!0,color:"white",children:"\u4ED3\u5E93ID"})}),u(h,{width:e,children:u(x,{bold:!0,color:"white",children:"\u4ED3\u5E93\u540D\u79F0"})}),u(h,{width:Jt,children:u(x,{bold:!0,color:"white",children:"\u521B\u5EFA\u65F6\u95F4"})})]})}function So({stock:e,fillWidth:t}){let o=new Date(e.gmtCreate).toLocaleString("zh-CN");return X(h,{flexDirection:"row",children:[u(h,{width:jt,children:u(x,{color:"gray",children:e.id})}),u(h,{width:Gt,children:u(x,{color:"gray",children:e.userId})}),u(h,{width:Bt,children:u(x,{color:"gray",children:e.stockId})}),u(h,{width:t,children:u(x,{bold:!0,children:e.stockName})}),u(h,{width:Jt,children:u(x,{color:"gray",children:o})})]})}function Co({stocks:e}){let t=process.stdout.columns||80,o=4,r=jt+Gt+Bt+Jt,n=Math.max(t-o-r,20),s=r+n;return X(h,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[X(h,{flexDirection:"row",children:[u(x,{bold:!0,color:"cyan",children:"\u4ED3\u5E93\u5217\u8868"}),X(x,{color:"gray",children:[" \xB7 ",e.length," \u4E2A"]})]}),X(h,{flexDirection:"column",marginTop:1,children:[u(xo,{fillWidth:n}),u(x,{color:"gray",children:"\u2500".repeat(s)}),e.map(i=>u(So,{stock:i,fillWidth:n},i.id))]})]})}var jt,Gt,Bt,Jt,we=Y(()=>{"use strict";jt=6,Gt=10,Bt=10,Jt=22});import{Command as qo}from"commander";import{readFileSync as Qo}from"node:fs";import Re from"node:path";import z from"chalk";import"commander";import{Command as ne}from"commander";import f from"chalk";var G=class e extends Error{constructor(o,r,n){super(o);this.code=r;this.details=n;this.name="R2Error",Error.captureStackTrace&&Error.captureStackTrace(this,e)}code;details},v=class extends G{constructor(o,r,n){super(o,"API_ERROR",n);this.status=r;this.response=n;this.name="ApiError"}status;response},N=class extends G{constructor(o,r,n){super(o,"STORAGE_ERROR",{path:r,code:n});this.path=r;this.code=n;this.name="StorageError"}path;code},y=class extends G{constructor(t){super(t,"AUTH_ERROR"),this.name="AuthError"}},b=class extends G{constructor(o,r,n){super(o,"POLLING_ERROR",{attempts:r,timeout:n});this.attempts=r;this.timeout=n;this.name="PollingError"}attempts;timeout};async function De(e,t,o){let r=new AbortController,n=()=>r.abort();o?.addEventListener("abort",n,{once:!0});let s=setTimeout(()=>r.abort(),t);try{return await e()}catch(i){throw r.signal.aborted&&!o?.aborted?new b("\u5355\u6B21\u8F6E\u8BE2\u8BF7\u6C42\u8D85\u65F6"):i}finally{clearTimeout(s),o?.removeEventListener("abort",n)}}async function B(e,t,o){let{interval:r,timeout:n,condition:s}=t,i=Date.now(),a=0;for(;Date.now()-i<n;){if(o?.aborted)throw new b("\u8F6E\u8BE2\u88AB\u4E2D\u6B62");a++;let l=n-(Date.now()-i),d=await De(e,l,o);if(s(d,a))return d;await $e(r,o)}throw new b(`\u8F6E\u8BE2\u8D85\u65F6 (\u5DF2\u7B49\u5F85 ${Date.now()-i}ms, \u5171 ${a} \u6B21)`)}function $e(e,t){return new Promise((o,r)=>{if(t?.aborted){r(new b("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"));return}let n=()=>{clearTimeout(s),r(new b("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"))},s=setTimeout(()=>{t?.removeEventListener("abort",n),o()},e);t?.addEventListener("abort",n,{once:!0})})}import Be from"node:fs";import{fileURLToPath as Je}from"node:url";import{createRequire as qe}from"node:module";import Xt from"node:path";import{exec as Qe}from"node:child_process";import je from"node:http";var gt=class e{server=null;pages=new Map;port=0;idleTimer=null;static IDLE_TIMEOUT_MS=1e4;async start(){return this.server?this.port:new Promise((t,o)=>{this.server=je.createServer((r,n)=>this.handleRequest(r,n)),this.server.listen(0,"127.0.0.1",()=>{let r=this.server.address();typeof r=="object"&&r?(this.port=r.port,t(this.port)):o(new Error("Failed to get server address"))}),this.server.on("error",o)})}registerPage(t,o,r,n){let s=this.pages.get(t);if(s){s.qrBuffer=r,s.status="waiting",s.config=n;let i=`data: ${JSON.stringify({status:"waiting"})}
|
|
5
5
|
|
|
6
|
-
`;for(let
|
|
6
|
+
`;for(let a of s.sseClients)a.write(i)}else this.pages.set(t,{html:o,qrBuffer:r,status:"waiting",sseClients:[],config:n});this.resetIdleTimer()}unregisterPage(t){let o=this.pages.get(t);if(o){for(let r of o.sseClients)r.end();o.sseClients.length=0,this.pages.delete(t),this.pages.size===0&&this.close()}}setStatus(t,o){let r=this.pages.get(t);if(!r)return;r.status=o;let n=`data: ${JSON.stringify({status:o})}
|
|
7
7
|
|
|
8
|
-
`;for(let s of r.sseClients)s.write(n)}close(){if(this.server){for(let t of this.pages.values()){for(let
|
|
8
|
+
`;for(let s of r.sseClients)s.write(n)}close(){if(this.server){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null);for(let t of this.pages.values()){for(let o of t.sseClients)o.end();t.sseClients.length=0}this.pages.clear(),this.server.close(),this.server=null,this.port=0,J=null}}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>{[...this.pages.values()].some(o=>o.sseClients.length>0)||this.close()},e.IDLE_TIMEOUT_MS)}handleRequest(t,o){let r=t.url??"/";for(let[n,s]of this.pages){if(r===n){o.writeHead(302,{Location:n+"/"}),o.end();return}if(r===n+"/"){o.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),o.end(s.html);return}if(r===n+"/qr.png"){o.writeHead(200,{"Content-Type":"image/png","Content-Length":s.qrBuffer.length}),o.end(s.qrBuffer);return}if(r===n+"/events"){o.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),o.write(`data: ${JSON.stringify({status:s.status})}
|
|
9
9
|
|
|
10
|
-
`),s.sseClients.push(
|
|
11
|
-
|
|
12
|
-
\
|
|
13
|
-
\
|
|
14
|
-
\
|
|
15
|
-
\u{
|
|
16
|
-
|
|
17
|
-
`)),console.log(
|
|
18
|
-
|
|
19
|
-
`),console.log(r),console.log(h.cyan(` \u6216\u6253\u5F00\u94FE\u63A5: ${n}`)),console.log(h.yellow(`
|
|
20
|
-
\u23F3 \u7B49\u5F85\u626B\u7801...
|
|
21
|
-
`));let c=Number.parseInt(e.expireTime,10),l=Number.parseInt(e.pollInterval,10);try{let p=await this.waitForLogin(e.qrToken,c,l,t,s);return console.log(h.green(`
|
|
10
|
+
`),s.sseClients.push(o),t.on("close",()=>{let i=s.sseClients.indexOf(o);i>=0&&s.sseClients.splice(i,1)});return}if(r===n+"/config"){o.writeHead(200,{"Content-Type":"application/json"}),o.end(JSON.stringify(s.config??{}));return}}o.writeHead(404,{"Content-Type":"text/plain"}),o.end("Not Found")}},J=null,_t=!1;function Z(){J&&J.close()}function Ge(){_t||(_t=!0,process.on("exit",Z),process.on("SIGINT",Z),process.on("SIGTERM",Z),setInterval(()=>{process.stdin?.destroyed&&Z()},3e3).unref())}function Mt(){return J||(J=new gt,Ge()),J}var _e=Xt.dirname(Je(import.meta.url)),Me="/login",Xe="/login-xianyu",ft=null;async function Fe(e){return Be.promises.readFile(Xt.join(_e,"pages",e),"utf-8")}async function ze(e){return ft||(ft=qe(import.meta.url)),ft("qrcode").toBuffer(e,{width:300,margin:2})}function P(e){let t=process.platform==="win32"?`start "" "${e}"`:process.platform==="darwin"?`open "${e}"`:`xdg-open "${e}"`;Qe(t)}async function Ft(e,t,o,r){let[n,s]=await Promise.all([Fe(t),ze(o)]),i=Mt(),a=await i.start();i.registerPage(e,n,s,r);let l=`http://127.0.0.1:${a}${e}/`;return{url:o,qrUrl:l,setStatus:d=>i.setStatus(e,d),closeServer:()=>i.unregisterPage(e)}}function ht(e){return Ft(Me,"login.html",e)}function yt(e,t){return Ft(Xe,"xianyu-auth.html",e,{authUrl:t})}import{promises as q}from"node:fs";import wt from"node:path";import We from"node:os";var He=".r2-cli",tt=class{configPath;config;configLoaded=!1;dirEnsured=!1;constructor(){let t=We.homedir(),o=wt.join(t,He);this.configPath=wt.join(o,"config.json"),this.config={credentials:null}}getConfigPath(){return this.configPath}async loadConfig(){if(this.configLoaded)return this.config;try{let t=await q.readFile(this.configPath,"utf-8");return this.config=JSON.parse(t),this.configLoaded=!0,this.config}catch{return this.config={credentials:null},this.configLoaded=!0,this.config}}async ensureDir(){if(this.dirEnsured)return;let t=wt.dirname(this.configPath);try{await q.stat(t)}catch(o){if(o.code==="ENOENT")await q.mkdir(t,{recursive:!0});else throw new N("Failed to create directory",t,o.code)}this.dirEnsured=!0}async saveConfig(t){this.config=t,await this.ensureDir();let o=JSON.stringify(t,null,2),r=this.configPath+".tmp";try{await q.writeFile(r,o,"utf-8"),await q.rename(r,this.configPath),this.configLoaded=!0}catch(n){throw await q.unlink(r).catch(s=>{typeof process.env.DEBUG<"u"&&console.error("[config] cleanup tmp failed:",s)}),new N("Failed to save config",this.configPath,n.code)}}},xt=null;function St(){return xt||(xt=new tt),xt}var It=300*1e3,et=class{store=St();isTokenExpired(t){return t.expire?Date.now()>=t.expire-It:!1}async saveCredentials(t,o){let r=Date.now(),n=o.expire?Number.parseInt(o.expire,10):0,s={token:t,userInfo:o,timestamp:r,...n>0&&{expire:r+n}},i=await this.store.loadConfig();i.credentials=s,await this.store.saveConfig(i)}async getCredentials(){let t=await this.store.loadConfig();return!t.credentials||this.isTokenExpired(t.credentials)?null:t.credentials}async clearCredentials(){let t=await this.store.loadConfig();t.credentials=null,await this.store.saveConfig(t)}async getToken(){return(await this.getCredentials())?.token??null}async getUserInfo(){return(await this.getCredentials())?.userInfo??null}async isLoggedIn(){return await this.getCredentials()!==null}},Ct=null;function W(){return Ct||(Ct=new et),Ct}var Ke="https://api.puresnake.com",A=class{config;authStorage=null;cachedToken=null;tokenExpiry=0;constructor(t={}){this.config={baseUrl:t.baseUrl??Ke,version:t.version??"v3",debug:t.debug??!1},this.authStorage=t.auth===!1?null:W()}buildUrl(t){let o=t.startsWith("/")?t.slice(1):t;return`${this.config.baseUrl}/${this.config.version}/${o}`}async getAuthToken(){if(!this.authStorage)return;if(this.cachedToken&&Date.now()<this.tokenExpiry)return this.cachedToken;let t=await this.authStorage.getCredentials();if(!t)throw new y("\u8BF7\u5148\u8FD0\u884C r2-cli auth login \u767B\u5F55");return this.cachedToken=t.token,this.tokenExpiry=t.expire?t.expire-It:Date.now()+1800*1e3,t.token}async requestFull(t,o){let r=this.buildUrl(t),{method:n,headers:s,body:i,timeout:a=3e4}=o,l=await this.getAuthToken(),d={...s,...l?{token:l}:{}},g=new AbortController,$=setTimeout(()=>g.abort(),a),K={method:n,headers:{"Content-Type":"application/json",...d},signal:g.signal};i!==void 0&&(K.body=JSON.stringify(i)),this.config.debug&&console.error(`[API ${n}]`,r,i);try{let c=await fetch(r,K);if(!c.ok){if(c.status===401)throw this.authStorage&&(this.cachedToken=null,await this.authStorage.clearCredentials().catch(j=>{console.error("[API] \u6E05\u9664\u51ED\u8BC1\u5931\u8D25:",j instanceof Error?j.message:String(j))})),new y("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");let dt=await c.text();throw new v(dt||`${c.status} ${c.statusText}`,c.status)}let S=await c.json();if(this.config.debug&&console.error("[API Response]",S),!S.success||S.status!==0)throw new v(S.msg||"\u672A\u77E5\u9519\u8BEF",S.status,S);return S}catch(c){throw c instanceof DOMException&&c.name==="AbortError"?new v(`\u8BF7\u6C42\u8D85\u65F6 (${a}ms)`,408):c}finally{clearTimeout($)}}async request(t,o){return(await this.requestFull(t,o)).data}async get(t,o,r){let n=o&&o.size>0?`${t}?${o.toString()}`:t;return this.request(n,{method:"GET",headers:r})}async post(t,o,r){return this.request(t,{method:"POST",body:o,headers:r})}async put(t,o,r){return this.request(t,{method:"PUT",body:o,headers:r})}async delete(t,o){return this.request(t,{method:"DELETE",headers:o})}};var zt=new A({auth:!1});async function Wt(){return zt.post("app/qrcode/generate")}async function Ht(e){let t=new URLSearchParams;t.append("qrToken",e);let o=`app/qrcode/status?${t.toString()}`,r=await zt.requestFull(o,{method:"GET"});return r.token&&typeof r.data=="object"&&r.data!==null&&(r.data.token=r.token),r.data}async function Zt(e,t,o){let{UserInfoCard:r}=await Promise.resolve().then(()=>(Yt(),Kt)),{renderComponent:n}=await Promise.resolve().then(()=>(rt(),ot)),s=t!=null?{userInfo:e,lastLogin:t,daysSinceLogin:o??0}:{userInfo:e};n(r,s)}var nt=class{storage;constructor(t){this.storage=t??W()}async generateQR(){let t=await Wt(),o=`https://m.puresnake.com/r2/auth/login?qrToken=${t.qrContent}&from=wechat`,r=await ht(o);return{qrData:t,...r}}async waitForLogin(t,o,r,n,s,i){let a=await B(()=>Ht(t),{interval:r,timeout:o,condition:l=>{switch(l.status){case"scanned":return i||(console.log(f.cyan(`
|
|
11
|
+
\u{1F50D} \u5DF2\u626B\u7801: ${l.userInfo?.nickname||"\u672A\u77E5\u7528\u6237"}`)),console.log(f.yellow("\u8BF7\u5728 APP \u4E0A\u786E\u8BA4\u767B\u5F55"))),s?.("scanning"),!1;case"confirmed":return i||console.log(f.green(`
|
|
12
|
+
\u2705 \u7528\u6237\u5DF2\u786E\u8BA4\u767B\u5F55`)),s?.("success"),!0;case"expired":return i||console.log(f.red(`
|
|
13
|
+
\u23F0 \u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F`)),s?.("expired"),!0;case"canceled":return i||console.log(f.red(`
|
|
14
|
+
\u{1F6AB} \u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55`)),s?.("expired"),!0;default:return!1}}},n??void 0);if(a.status==="confirmed"&&a.token&&a.userInfo)return await this.storage.saveCredentials(a.token,a.userInfo),{userInfo:a.userInfo,token:a.token};throw a.status==="expired"?new y("\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55"):a.status==="canceled"?new y("\u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55"):new y("\u767B\u5F55\u5931\u8D25: \u672A\u83B7\u53D6\u5230\u51ED\u8BC1")}async login(t){console.log(f.cyan(`
|
|
15
|
+
\u{1F510} \u6B63\u5728\u542F\u52A8\u626B\u7801\u767B\u5F55...`));let{qrData:o,qrUrl:r,setStatus:n,closeServer:s}=await this.generateQR();console.log(f.green(`\u2705 \u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
|
|
16
|
+
`)),console.log(f.cyan(` \u94FE\u63A5: ${r}
|
|
17
|
+
`)),P(r),console.log(f.yellow(`\u23F3 \u7B49\u5F85\u626B\u7801...
|
|
18
|
+
`));let i=Number.parseInt(o.expireTime,10),a=Number.parseInt(o.pollInterval,10);try{let l=await this.waitForLogin(o.qrToken,i,a,t,n);return console.log(f.green(`
|
|
22
19
|
\u2705 \u767B\u5F55\u6210\u529F\uFF01
|
|
23
|
-
`)),
|
|
20
|
+
`)),Zt(l.userInfo),l}catch(l){throw console.log(f.red(`
|
|
24
21
|
\u274C \u767B\u5F55\u5931\u8D25
|
|
25
|
-
`)),
|
|
26
|
-
\u{1F6AA} \u6B63\u5728\u9000\u51FA\u767B\u5F55...`)),await this.storage.clearCredentials(),console.log(
|
|
27
|
-
`))}async status(){if(!await this.storage.isLoggedIn()){console.log(
|
|
28
|
-
`));return}let
|
|
29
|
-
`)),await
|
|
30
|
-
\u2705 \u6388\u6743\u6210\u529F\uFF01\u5E97\u94FA: ${s.shopName} (${s.shopId})`)),n?.("success"),!0):s.status==="expired"?(console.log(
|
|
31
|
-
\u23F0 \u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F`)),n?.("expired"),!0):!1},r)}async function
|
|
32
|
-
\u{1F517} \u6B63\u5728\u83B7\u53D6\u95F2\u9C7C\u6388\u6743\u5730\u5740...`));let{authData:t,
|
|
33
|
-
`)),console.log(
|
|
34
|
-
`),console.log(e),console.log(G.cyan(` \u6216\u6253\u5F00\u94FE\u63A5: ${r}`)),console.log(G.gray(` \u6216\u590D\u5236\u94FE\u63A5\u6253\u5F00: ${t.url}`)),console.log(G.yellow(`
|
|
22
|
+
`)),l}finally{s()}}async logout(){console.log(f.cyan(`
|
|
23
|
+
\u{1F6AA} \u6B63\u5728\u9000\u51FA\u767B\u5F55...`)),await this.storage.clearCredentials(),console.log(f.green(`\u2705 \u5DF2\u9000\u51FA\u767B\u5F55
|
|
24
|
+
`))}async status(){if(!await this.storage.isLoggedIn()){console.log(f.yellow(`\u26A0\uFE0F \u5C1A\u672A\u767B\u5F55\u6216\u51ED\u8BC1\u5DF2\u8FC7\u671F
|
|
25
|
+
`));return}let o=await this.storage.getCredentials(),r=o.userInfo,n=new Date(o.timestamp),s=Math.floor((Date.now()-o.timestamp)/(1e3*60*60*24));console.log(f.green(`\u2705 \u5DF2\u767B\u5F55
|
|
26
|
+
`)),await Zt(r,n,s)}},Pt=null;function k(){return Pt||(Pt=new nt),Pt}import U from"chalk";var te=new A;async function ee(){return te.get("mms/xianyu/auth/url")}async function oe(e){let t=new URLSearchParams({state:e});return te.get("mms/xianyu/auth/status",t)}async function st(){let e=await ee(),t=await yt(e.url,e.url);return{authData:e,...t}}async function H(e,t,o,r,n){return B(()=>oe(e),{interval:o,timeout:t,condition:s=>s.status==="success"?(console.log(U.green(`
|
|
27
|
+
\u2705 \u6388\u6743\u6210\u529F\uFF01\u5E97\u94FA: ${s.shopName} (${s.shopId})`)),n?.("success"),!0):s.status==="expired"?(console.log(U.red(`
|
|
28
|
+
\u23F0 \u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F`)),n?.("expired"),!0):!1},r)}async function kt(e){console.log(U.cyan(`
|
|
29
|
+
\u{1F517} \u6B63\u5728\u83B7\u53D6\u95F2\u9C7C\u6388\u6743\u5730\u5740...`));let{authData:t,qrUrl:o,setStatus:r,closeServer:n}=await st();console.log(U.green(`\u2705 \u6388\u6743\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
|
|
30
|
+
`)),console.log(U.cyan(` \u94FE\u63A5: ${o}`)),console.log(U.gray(` \u6216\u590D\u5236\u94FE\u63A5\u6253\u5F00: ${t.url}`)),P(o),console.log(U.yellow(`
|
|
35
31
|
\u23F3 \u7B49\u5F85\u6388\u6743...
|
|
36
|
-
`));let
|
|
37
|
-
\u25B2 ${
|
|
38
|
-
`));else if(
|
|
39
|
-
`));else{let t=o instanceof Error?o.message:String(o);console.error(A.red(`\u25B2 ${t}`))}process.exit(1)}function g(o){console.log(A.yellow(`\u25B2 "${o}" \u529F\u80FD\u5F00\u53D1\u4E2D\uFF0C\u6682\u4E0D\u53EF\u7528`))}function Rt(o){console.log(JSON.stringify({success:!1,error:o})),process.exit(1)}function z(o){return async(...t)=>{try{await o(...t)}catch(e){let r=e instanceof Error?e.message:String(e);Rt(r)}}}var se=new Set(["accessToken","refreshExpireIn"]);function uo(o){return o.map(t=>{let e={};for(let[r,n]of Object.entries(t))se.has(r)||(e[r]=n);return e})}function Et(){let o=new Nt("login");o.description("\u626B\u7801\u767B\u5F55 Round2AI \u8D26\u6237");let t=new Nt("qr").description("\u751F\u6210\u767B\u5F55\u4E8C\u7EF4\u7801\uFF08\u8FD4\u56DE JSON\uFF0C\u4F9B AI Agent \u4F7F\u7528\uFF09").action(z(async()=>{let r=v(),{qrData:n,...s}=await r.generateQR(),i=Number.parseInt(n.expireTime,10),c=Number.parseInt(n.pollInterval,10);console.log(JSON.stringify({qrToken:n.qrToken,expireTimeMs:i,pollIntervalMs:c,...s},null,2)),r.pollPageStatus(n.qrToken,i,c,s.setStatus).then(()=>{setTimeout(s.closeServer,3e3)}).catch(()=>{s.closeServer()})})),e=new Nt("poll").description("\u8F6E\u8BE2\u767B\u5F55\u72B6\u6001\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").requiredOption("--token <qrToken>","\u4E8C\u7EF4\u7801 token").option("--expire <ms>","\u8FC7\u671F\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09","300000").option("--interval <ms>","\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09","1000").action(z(async r=>{let s=await v().waitForLogin(r.token,Number.parseInt(r.expire,10),Number.parseInt(r.interval,10));console.log(JSON.stringify({success:!0,...s}))}));return o.addCommand(t),o.addCommand(e),o.action(async()=>{try{await v().login()}catch(r){m(r)}}),o}import{Command as ie}from"commander";function Ut(){let o=new ie("logout");return o.description("\u9000\u51FA\u767B\u5F55"),o.action(async()=>{try{await v().logout()}catch(t){m(t)}}),o}import{Command as ae}from"commander";function Dt(){let o=new ae("status");return o.description("\u67E5\u770B\u767B\u5F55\u72B6\u6001"),o.action(async()=>{try{await v().status()}catch(t){m(t)}}),o}import{Command as Ot}from"commander";function $t(){let o=new Ot("xianyu");o.description("\u95F2\u9C7C\u5E97\u94FA\u6388\u6743");let t=new Ot("qr").description("\u83B7\u53D6\u95F2\u9C7C\u6388\u6743\u4E8C\u7EF4\u7801\uFF08\u8FD4\u56DE JSON\uFF0C\u4F9B AI Agent \u4F7F\u7528\uFF09").action(z(async()=>{let{authData:r,...n}=await ct(),s=r.expireTime?Number.parseInt(r.expireTime,10):3e5,i=r.pollInterval?Number.parseInt(r.pollInterval,10):1e3;console.log(JSON.stringify({state:r.state,expireTimeMs:s,pollIntervalMs:i,...n},null,2)),mo(r.state,s,i,n.setStatus).then(()=>{setTimeout(n.closeServer,3e3)}).catch(()=>{n.closeServer()})})),e=new Ot("poll").description("\u8F6E\u8BE2\u95F2\u9C7C\u6388\u6743\u72B6\u6001\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").requiredOption("--state <state>","\u6388\u6743\u8F6E\u8BE2 token").option("--expire <ms>","\u8FC7\u671F\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09","300000").option("--interval <ms>","\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09","1000").action(z(async r=>{let n=await lt(r.state,Number.parseInt(r.expire,10),Number.parseInt(r.interval,10));n.status==="success"?console.log(JSON.stringify({success:!0,shopId:n.shopId,shopName:n.shopName})):Rt(`\u6388\u6743\u72B6\u6001: ${n.status}`)}));return o.addCommand(t),o.addCommand(e),o.action(async()=>{try{await Lt()}catch(r){m(r)}}),o}import{Command as ce}from"commander";function po(){let o=new ce("analyze");return o.description("\u5206\u6790\u5546\u54C1\u4EF7\u683C\u5EFA\u8BAE"),o.option("--sku <sku>","\u5546\u54C1SKU"),o.option("--condition <condition>","\u5546\u54C1\u6210\u8272"),o.action(()=>g("pricing analyze")),o}import{Command as le}from"commander";function go(){let o=new le("generate");return o.description("\u751F\u6210\u7ECF\u8425\u62A5\u544A"),o.option("--type <type>","\u62A5\u544A\u7C7B\u578B: daily, weekly","daily"),o.action(()=>g("report generate")),o}import{Command as me}from"commander";function fo(){let o=new me("risk");return o.description("\u5E93\u5B58\u98CE\u9669\u8BC6\u522B"),o.option("--warehouse <warehouse>","\u4ED3\u5E93\u4EE3\u7801"),o.action(()=>g("inventory risk")),o}import{Command as de}from"commander";function ho(){let o=new de("chat");return o.description("\u4E0E AI \u52A9\u624B\u804A\u5929\uFF0C\u83B7\u53D6\u7ECF\u8425\u5EFA\u8BAE"),o.action(()=>g("ai chat")),o}import{Command as ue}from"commander";function yo(){let o=new ue("skills");return o.description("AI Agent \u6280\u80FD\u7BA1\u7406"),o.action(()=>g("ai skills")),o}import{Command as De}from"commander";import{Command as pe}from"commander";import k from"chalk";import{select as Jt,input as ge,confirm as fe}from"@inquirer/prompts";var R=new L;function Gt(o){let t=new URLSearchParams;for(let[e,r]of Object.entries(o))r!=null&&r!==""&&t.append(e,String(r));return t}async function Bt(o){return R.post("mms/goods/listing/up/xianyu",o)}async function wo(o){return R.get("mms/goods/listing/get",Gt({...o}))}async function jt(o){return R.post("mms/goods/listing/down/xianyu",o)}async function qt(o){return R.post("mms/goods/listing/update/xyPrice",o)}async function Qt(o){return R.get("mms/goods/listing/list",o?Gt({...o}):void 0)}async function mt(){return await R.get("mms/user/shop/list")??[]}async function dt(){return await R.get("mms/user/stock/list")??[]}async function Y(o){return R.get("mms/seller/goods/select/list",o?Gt({...o}):void 0)}var he=2e3,ye=1e4;function we(o){let t=o.status?.toLowerCase()??"";return t===""||t==="init"||t==="pending"||t==="processing"}async function xo(o,t,e,r){r||process.stdout.write(k.cyan("\u23F3 \u6B63\u5728\u67E5\u8BE2\u4E0A\u67B6\u8FDB\u5EA6..."));let n=await T(()=>wo({stockGoodsId:o,shopId:t,platform:e}),{interval:he,timeout:ye,condition:s=>!we(s)});return r||process.stdout.write("\r"+" ".repeat(30)+"\r"),n}function So(){let o=new pe("up");return o.description("\u4E0A\u67B6\u5546\u54C1\u5230\u95F2\u9C7C"),o.option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1ID\uFF08\u4ECE goods list \u83B7\u53D6\uFF09").option("--shop-id <id>","\u5E97\u94FAID\uFF08\u4ECE goods shops \u83B7\u53D6\uFF09").option("--price <amount>","\u4E0A\u67B6\u4EF7\u683C").option("-p, --platform <platform>","\u5E73\u53F0","xianyu").option("--json","\u8F93\u51FA JSON\uFF08Agent \u7528\uFF09").action(async t=>{try{if(t.stockGoodsId&&t.shopId&&t.price){let a=Number(t.stockGoodsId),C=t.shopId,gt=Number(t.price),q=t.platform,Qo=await Bt({stockGoodsId:a,shopId:C,price:gt,platform:q}),ft=await xo(a,C,q,t.json);if(t.json)console.log(JSON.stringify({success:!0,data:{submit:Qo,listing:ft}},null,2));else{let Jo=ft.status?.toLowerCase()!=="failed";console.log(Jo?k.green("\u2713 \u4E0A\u67B6\u6210\u529F"):k.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(ft,null,2))}return}let e=await mt();if(e.length===0){console.log(k.yellow("\u6CA1\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF0C\u8BF7\u5148\u8FD0\u884C r2-cli auth xianyu \u6388\u6743"));return}let r=await Jt({message:"\u9009\u62E9\u5E97\u94FA",choices:e.map(a=>({name:`${a.shopName} (${a.platform})`,value:a.shopId}))}),n=await dt();if(n.length===0){console.log(k.yellow("\u6CA1\u6709\u53EF\u7528\u7684\u4ED3\u5E93"));return}let s=await Jt({message:"\u9009\u62E9\u4ED3\u5E93",choices:n.map(a=>({name:a.stockName,value:a.stockId}))}),i=await Y({stockId:s,size:100});if(!i.items?.length){console.log(k.yellow("\u8BE5\u4ED3\u5E93\u6CA1\u6709\u53EF\u9009\u7684\u5546\u54C1"));return}let c=await Jt({message:"\u9009\u62E9\u5546\u54C1",choices:i.items.map(a=>({name:`${a.goodsName} ${a.size?`| ${a.size}`:""} | \xA5${a.salePrice}`,value:a.stockGoodsId}))}),l=await ge({message:"\u8F93\u5165\u4E0A\u67B6\u4EF7\u683C",default:i.items.find(a=>a.stockGoodsId===c)?.salePrice?.toString()??"",validate:a=>Number(a)>0?!0:"\u4EF7\u683C\u5FC5\u987B\u4E3A\u6B63\u6570"});if(!await fe({message:`\u786E\u8BA4\u4E0A\u67B6\uFF1F\u4EF7\u683C \xA5${l}`,default:!0})){console.log(k.gray("\u5DF2\u53D6\u6D88"));return}let f=Number(c);await Bt({stockGoodsId:f,shopId:r,price:Number(l),platform:"xianyu"}),console.log(k.green("\u2713 \u4E0A\u67B6\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u67E5\u8BE2\u8FDB\u5EA6..."));let N=await xo(f,r,"xianyu"),E=N.status?.toLowerCase()!=="failed";console.log(E?k.green("\u2713 \u4E0A\u67B6\u6210\u529F"):k.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(N,null,2))}catch(e){m(e)}}),o}import{Command as ke}from"commander";import Po from"chalk";function vo(){let o=new ke("shops");return o.description("\u67E5\u770B\u6240\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF08\u8DE8\u5E73\u53F0\uFF09"),o.option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(async t=>{try{let e=await mt();if(t.json){console.log(JSON.stringify(uo(e),null,2));return}if(!e.length){console.log(Po.yellow("\u672A\u627E\u5230\u5DF2\u6388\u6743\u7684\u5E97\u94FA")),console.log(Po.gray(" \u63D0\u793A: \u8BF7\u5148\u5728\u7B2C\u4E8C\u56DE\u5408 APP \u4E2D\u6388\u6743\u5E97\u94FA"));return}let{ShopsTable:r}=await Promise.resolve().then(()=>(ko(),Io)),{renderComponent:n}=await Promise.resolve().then(()=>(it(),st));n(r,{shops:e,platform:"all"})}catch(e){m(e)}}),o}import{Command as be}from"commander";import Te from"chalk";function To(){let o=new be("stocks");return o.description("\u67E5\u770B\u6240\u6709\u4ED3\u5E93"),o.option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(async t=>{try{let e=await dt();if(t.json){console.log(JSON.stringify(e,null,2));return}if(!e.length){console.log(Te.yellow("\u672A\u627E\u5230\u4ED3\u5E93\u4FE1\u606F"));return}let{StocksTable:r}=await Promise.resolve().then(()=>(bo(),Ao)),{renderComponent:n}=await Promise.resolve().then(()=>(it(),st));n(r,{stocks:e})}catch(e){m(e)}}),o}import{Command as Le}from"commander";import j from"chalk";function Lo(){let o=new Le("list");return o.description("\u67E5\u770B\u4ED3\u5E93\u4E2D\u7684\u9009\u54C1\u5546\u54C1"),o.option("--stock-id <id>","\u4ED3\u5E93 ID\uFF08\u4ECE goods stocks \u83B7\u53D6\uFF09").option("--page <n>","\u9875\u7801","1").option("--size <n>","\u6BCF\u9875\u6570\u91CF","20").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(async t=>{if(t.json){try{let r=await Y({stockId:t.stockId??"",page:Number(t.page)||1,size:Number(t.size)||20})??{items:[],total:0};r.items?.length?console.log(JSON.stringify(r,null,2)):console.log(JSON.stringify({...r,hint:"\u9009\u54C1\u5546\u54C1\u4E3A\u7A7A\uFF0C\u8BF7\u5148\u5728\u540E\u53F0\u751F\u6210\u9009\u54C1\u8868\u6570\u636E\u540E\u518D\u8BD5"},null,2))}catch(e){let r=e instanceof Error?e.message:String(e);console.log(JSON.stringify({success:!1,error:r})),process.exit(1)}return}try{if(!t.stockId){console.log(j.yellow("\u8BF7\u6307\u5B9A\u4ED3\u5E93 ID: r2-cli goods list --stock-id <id>"));return}let e=await Y({stockId:t.stockId,page:Number(t.page)||1,size:Number(t.size)||20});if(!e.items?.length){console.log(j.yellow("\u8BE5\u4ED3\u5E93\u6CA1\u6709\u9009\u54C1\u5546\u54C1\uFF0C\u8BF7\u5148\u5728\u540E\u53F0\u751F\u6210\u9009\u54C1\u8868\u6570\u636E\u540E\u518D\u8BD5"));return}console.log(j.cyan(`
|
|
40
|
-
\u9009\u54C1\u5546\u54C1\uFF08\u5171 ${
|
|
41
|
-
`));for(let
|
|
42
|
-
`));for(let
|
|
43
|
-
\u26A0\uFE0F \u5373\u5C06\u6267\u884C\u4EE5\u4E0B\u64CD\u4F5C\uFF1A`)),console.log(
|
|
44
|
-
`));let{confirm:t}=await import("@inquirer/prompts");if(!await t({message:"\u786E\u8BA4\u5378\u8F7D\uFF1F",default:!1})){console.log(
|
|
45
|
-
\u2705 ${
|
|
46
|
-
\u26A0\uFE0F npm \u5378\u8F7D\u5931\u8D25 (exit code: ${s})`)),console.log(
|
|
47
|
-
Update available: ${
|
|
48
|
-
Run: npm update -g ${
|
|
49
|
-
`))}async function
|
|
50
|
-
`))}function
|
|
51
|
-
\u64CD\u4F5C\u5DF2\u53D6\u6D88`)),process.exit(130)}process.on("SIGINT",
|
|
32
|
+
`));let s=t.expireTime?Number.parseInt(t.expireTime,10):3e5,i=t.pollInterval?Number.parseInt(t.pollInterval,10):1e3;try{let a=await H(t.state,s,i,e,r);if(a.status==="success")return a;throw new y("\u95F2\u9C7C\u6388\u6743\u5931\u8D25: "+(a.status==="expired"?"\u94FE\u63A5\u5DF2\u8FC7\u671F":"\u672A\u77E5\u72B6\u6001"))}finally{n()}}import L from"chalk";function m(e){if(e instanceof y)console.error(L.red(`
|
|
33
|
+
\u25B2 ${e.message}`)),console.error(L.gray(`\u2192 \u8BF7\u5148\u8FD0\u884C: r2-cli auth login
|
|
34
|
+
`));else if(e instanceof v)console.error(L.red(`\u25B2 \u64CD\u4F5C\u5931\u8D25: ${e.message}`)),e.status&&console.error(L.gray(` \u72B6\u6001\u7801: ${e.status}`));else if(e instanceof N)console.error(L.red(`\u25B2 \u914D\u7F6E\u6587\u4EF6\u5F02\u5E38: ${e.message}`)),e.path&&console.error(L.gray(` \u8DEF\u5F84: ${e.path}`)),console.error(L.gray(`\u2192 \u8BF7\u5C1D\u8BD5\u91CD\u65B0\u767B\u5F55: r2-cli auth login
|
|
35
|
+
`));else{let t=e instanceof Error?e.message:String(e);console.error(L.red(`\u25B2 ${t}`))}process.exit(1)}function vt(e){console.log(JSON.stringify({success:!1,error:e})),process.exit(1)}function it(e){return async(...t)=>{try{await e(...t)}catch(o){let r=o instanceof Error?o.message:String(o);vt(r)}}}var no=new Set(["accessToken","refreshExpireIn"]);function re(e){return e.map(t=>{let o={};for(let[r,n]of Object.entries(t))no.has(r)||(o[r]=n);return o})}function bt(){let e=new ne("login");e.description("\u626B\u7801\u767B\u5F55 Round2AI \u8D26\u6237").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new ne("poll").description("\u8F6E\u8BE2\u767B\u5F55\u72B6\u6001\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").requiredOption("--token <qrToken>","\u4E8C\u7EF4\u7801 token").option("--expire <ms>","\u8FC7\u671F\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09","300000").option("--interval <ms>","\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09","1000").action(it(async o=>{let n=await k().waitForLogin(o.token,Number.parseInt(o.expire,10),Number.parseInt(o.interval,10));console.log(JSON.stringify({success:!0,...n}))}));return e.addCommand(t),e.action(async o=>{try{if(o.json){let r=k(),{qrData:n,qrUrl:s,setStatus:i,closeServer:a}=await r.generateQR(),l=Number.parseInt(n.expireTime,10),d=Number.parseInt(n.pollInterval,10);console.log(JSON.stringify({qrToken:n.qrToken,expireTimeMs:l,pollIntervalMs:d,url:`https://m.puresnake.com/r2/auth/login?qrToken=${n.qrContent}&from=wechat`,qrUrl:s},null,2)),P(s);try{let g=await r.waitForLogin(n.qrToken,l,d,void 0,i,!0);console.log(JSON.stringify({success:!0,userInfo:g.userInfo}))}catch(g){let $=g instanceof Error?g.message:String(g);console.log(JSON.stringify({success:!1,error:$}))}finally{setTimeout(a,1e3)}}else await k().login()}catch(r){if(o.json){let n=r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:n})),process.exit(1)}m(r)}}),e}import{Command as so}from"commander";function At(){let e=new so("logout");return e.description("\u9000\u51FA\u767B\u5F55"),e.action(async()=>{try{await k().logout()}catch(t){m(t)}}),e}import{Command as io}from"commander";function Lt(){let e=new io("status");return e.description("\u67E5\u770B\u767B\u5F55\u72B6\u6001"),e.action(async()=>{try{await k().status()}catch(t){m(t)}}),e}import{Command as se}from"commander";function Rt(){let e=new se("xianyu");e.description("\u95F2\u9C7C\u5E97\u94FA\u6388\u6743").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new se("poll").description("\u8F6E\u8BE2\u95F2\u9C7C\u6388\u6743\u72B6\u6001\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").requiredOption("--state <state>","\u6388\u6743\u8F6E\u8BE2 token").option("--expire <ms>","\u8FC7\u671F\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09","300000").option("--interval <ms>","\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09","1000").action(it(async o=>{let r=await H(o.state,Number.parseInt(o.expire,10),Number.parseInt(o.interval,10));r.status==="success"?console.log(JSON.stringify({success:!0,shopId:r.shopId,shopName:r.shopName})):vt(`\u6388\u6743\u72B6\u6001: ${r.status}`)}));return e.addCommand(t),e.action(async o=>{try{if(o.json){let{authData:r,qrUrl:n,setStatus:s,closeServer:i}=await st(),a=r.expireTime?Number.parseInt(r.expireTime,10):3e5,l=r.pollInterval?Number.parseInt(r.pollInterval,10):1e3;console.log(JSON.stringify({state:r.state,expireTimeMs:a,pollIntervalMs:l,qrUrl:n},null,2)),P(n);try{let d=await H(r.state,a,l,void 0,s);d.status==="success"?console.log(JSON.stringify({success:!0,shopId:d.shopId,shopName:d.shopName})):(console.log(JSON.stringify({success:!1,error:`\u6388\u6743\u72B6\u6001: ${d.status}`})),process.exit(1))}catch(d){let g=d instanceof Error?d.message:String(d);console.log(JSON.stringify({success:!1,error:g})),process.exit(1)}finally{setTimeout(i,1e3)}}else await kt()}catch(r){if(o.json){let n=r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:n})),process.exit(1)}m(r)}}),e}import{Command as Lo}from"commander";import{Command as ao}from"commander";import I from"chalk";import{select as Ot,input as co,confirm as lo}from"@inquirer/prompts";var R=new A;function Nt(e){let t=new URLSearchParams;for(let[o,r]of Object.entries(e))r!=null&&r!==""&&t.append(o,String(r));return t}async function Et(e){return R.post("mms/goods/listing/up/xianyu",e)}async function ie(e){return R.get("mms/goods/listing/get",Nt({...e}))}async function ae(e){return R.post("mms/goods/listing/down/xianyu",e)}async function ce(e){return R.post("mms/goods/listing/update/xyPrice",e)}async function le(e){return R.get("mms/goods/listing/list",e?Nt({...e}):void 0)}async function at(){return await R.get("mms/user/shop/list")??[]}async function ct(){return await R.get("mms/user/stock/list")??[]}async function lt(e){let t=e?Nt({...e}):void 0;return R.get("mms/seller/goods/select/list",t)}var mo=2e3,uo=1e4;function po(e){let t=e.status?.toLowerCase()??"";return t===""||t==="init"||t==="pending"||t==="processing"}async function me(e,t,o,r){r||process.stdout.write(I.cyan("\u23F3 \u6B63\u5728\u67E5\u8BE2\u4E0A\u67B6\u8FDB\u5EA6..."));let n=await B(()=>ie({stockGoodsId:e,shopId:t,platform:o}),{interval:mo,timeout:uo,condition:s=>!po(s)});return r||process.stdout.write("\r"+" ".repeat(30)+"\r"),n}function ue(){let e=new ao("up");return e.description("\u4E0A\u67B6\u5546\u54C1\u5230\u95F2\u9C7C"),e.option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1ID\uFF08\u4ECE goods list \u83B7\u53D6\uFF09").option("--shop-id <id>","\u5E97\u94FAID\uFF08\u4ECE goods shops \u83B7\u53D6\uFF09").option("--price <amount>","\u4E0A\u67B6\u4EF7\u683C").option("-p, --platform <platform>","\u5E73\u53F0","xianyu").option("--json","\u8F93\u51FA JSON\uFF08Agent \u7528\uFF09").action(async t=>{try{if(t.stockGoodsId&&t.shopId&&t.price){let c=Number(t.stockGoodsId),S=t.shopId,dt=Number(t.price),j=t.platform,Ee=await Et({stockGoodsId:c,shopId:S,price:dt,platform:j}),pt=await me(c,S,j,t.json);if(t.json)console.log(JSON.stringify({success:!0,data:{submit:Ee,listing:pt}},null,2));else{let Oe=pt.status?.toLowerCase()!=="failed";console.log(Oe?I.green("\u2713 \u4E0A\u67B6\u6210\u529F"):I.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(pt,null,2))}return}let o=await at();if(o.length===0){console.log(I.yellow("\u6CA1\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF0C\u8BF7\u5148\u8FD0\u884C r2-cli auth xianyu \u6388\u6743"));return}let r=await Ot({message:"\u9009\u62E9\u5E97\u94FA",choices:o.map(c=>({name:`${c.shopName} (${c.platform})`,value:c.shopId}))}),n=await ct();if(n.length===0){console.log(I.yellow("\u6CA1\u6709\u53EF\u7528\u7684\u4ED3\u5E93"));return}let s=await Ot({message:"\u9009\u62E9\u4ED3\u5E93",choices:n.map(c=>({name:c.stockName,value:c.stockId}))}),i=await lt({stockId:s,size:100});if(!i.items?.length){console.log(I.yellow("\u8BE5\u4ED3\u5E93\u6CA1\u6709\u53EF\u9009\u7684\u5546\u54C1"));return}let a=await Ot({message:"\u9009\u62E9\u5546\u54C1",choices:i.items.map(c=>({name:`${c.goodsName} ${c.size?`| ${c.size}`:""} | \xA5${c.salePrice}`,value:c.stockGoodsId}))}),l=await co({message:"\u8F93\u5165\u4E0A\u67B6\u4EF7\u683C",default:i.items.find(c=>c.stockGoodsId===a)?.salePrice?.toString()??"",validate:c=>Number(c)>0?!0:"\u4EF7\u683C\u5FC5\u987B\u4E3A\u6B63\u6570"});if(!await lo({message:`\u786E\u8BA4\u4E0A\u67B6\uFF1F\u4EF7\u683C \xA5${l}`,default:!0})){console.log(I.gray("\u5DF2\u53D6\u6D88"));return}let g=Number(a);await Et({stockGoodsId:g,shopId:r,price:Number(l),platform:"xianyu"}),console.log(I.green("\u2713 \u4E0A\u67B6\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u67E5\u8BE2\u8FDB\u5EA6..."));let $=await me(g,r,"xianyu"),K=$.status?.toLowerCase()!=="failed";console.log(K?I.green("\u2713 \u4E0A\u67B6\u6210\u529F"):I.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify($,null,2))}catch(o){m(o)}}),e}import{Command as wo}from"commander";import fe from"chalk";function he(){let e=new wo("shops");return e.description("\u67E5\u770B\u6240\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF08\u8DE8\u5E73\u53F0\uFF09"),e.option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{let o=await at();if(t.json){console.log(JSON.stringify(re(o),null,2));return}if(!o.length){console.log(fe.yellow("\u672A\u627E\u5230\u5DF2\u6388\u6743\u7684\u5E97\u94FA")),console.log(fe.gray(" \u63D0\u793A: \u8BF7\u5148\u5728\u7B2C\u4E8C\u56DE\u5408 APP \u4E2D\u6388\u6743\u5E97\u94FA"));return}let{ShopsTable:r}=await Promise.resolve().then(()=>(ge(),pe)),{renderComponent:n}=await Promise.resolve().then(()=>(rt(),ot));n(r,{shops:o,platform:"all"})}catch(o){m(o)}}),e}import{Command as Io}from"commander";import To from"chalk";function xe(){let e=new Io("stocks");return e.description("\u67E5\u770B\u6240\u6709\u4ED3\u5E93"),e.option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{let o=await ct();if(t.json){console.log(JSON.stringify(o,null,2));return}if(!o.length){console.log(To.yellow("\u672A\u627E\u5230\u4ED3\u5E93\u4FE1\u606F"));return}let{StocksTable:r}=await Promise.resolve().then(()=>(we(),ye)),{renderComponent:n}=await Promise.resolve().then(()=>(rt(),ot));n(r,{stocks:o})}catch(o){m(o)}}),e}import{Command as Po}from"commander";import F from"chalk";function Se(){let e=new Po("list");return e.description("\u67E5\u770B\u4ED3\u5E93\u4E2D\u7684\u9009\u54C1\u5546\u54C1"),e.option("--stock-id <id>","\u4ED3\u5E93 ID\uFF08\u4ECE goods stocks \u83B7\u53D6\uFF09").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--page <n>","\u9875\u7801","1").option("--size <n>","\u6BCF\u9875\u6570\u91CF","20").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{let r=await lt({stockId:t.stockId||void 0,stockGoodsId:t.stockGoodsId||void 0,page:Number(t.page)||1,size:Number(t.size)||20})??{items:[],total:0};if(t.json){r.items?.length?console.log(JSON.stringify(r,null,2)):console.log(JSON.stringify({...r,hint:"\u9009\u54C1\u5546\u54C1\u4E3A\u7A7A\uFF0C\u8BF7\u5148\u5728\u540E\u53F0\u751F\u6210\u9009\u54C1\u8868\u6570\u636E\u540E\u518D\u8BD5"},null,2));return}if(!r.items?.length){console.log(F.yellow("\u6682\u65E0\u9009\u54C1\u5546\u54C1\uFF0C\u8BF7\u5148\u7ED1\u5B9A\u4ED3\u5E93\u6216\u5728\u540E\u53F0\u751F\u6210\u9009\u54C1\u8868\u6570\u636E"));return}console.log(F.cyan(`
|
|
36
|
+
\u9009\u54C1\u5546\u54C1\uFF08\u5171 ${r.total} \u4EF6\uFF0C\u7B2C ${r.page} \u9875\uFF09
|
|
37
|
+
`));for(let n of r.items)console.log(` ${F.bold(n.goodsName)} ${n.size?F.gray(`| ${n.size}`):""}`),console.log(` \u54C1\u724C: ${n.brand} \u5EFA\u8BAE\u552E\u4EF7: \xA5${n.salePrice} stockGoodsId: ${F.green(n.stockGoodsId)}`),console.log(F.gray(` \u5206\u7C7B: ${n.cate1Name} > ${n.cate2Name} > ${n.cate3Name}`)),console.log()}catch(o){if(t.json){let r=o instanceof Error?o.message:String(o);console.log(JSON.stringify({success:!1,error:r})),process.exit(1)}m(o)}}),e}import{Command as ko}from"commander";import Ce from"chalk";var vo={init:"\u5F85\u4E0A\u67B6",up:"\u5DF2\u4E0A\u67B6",down:"\u5DF2\u4E0B\u67B6",fail:"\u5931\u8D25"};function Ie(){let e=new ko("listing");return e.description("\u67E5\u8BE2\u4E0A\u67B6\u5546\u54C1\u5217\u8868"),e.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--stock-id <id>","\u4ED3\u5E93 ID").option("-s, --status <status>","\u72B6\u6001\u8FC7\u6EE4\uFF08init/up/down/fail\uFF09").option("-p, --platform <platform>","\u5E73\u53F0","xianyu").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{let r=await le({id:t.id,stockGoodsId:t.stockGoodsId?Number(t.stockGoodsId):void 0,shopId:t.shopId,stockId:t.stockId,status:t.status,platform:t.platform})??{list:[],total:0};if(t.json){r.list?.length?console.log(JSON.stringify(r,null,2)):console.log(JSON.stringify({...r,hint:"\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55"},null,2));return}if(!r.list?.length){console.log(Ce.yellow("\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55"));return}console.log(Ce.green(`\u2705 \u5171 ${r.total} \u6761\u8BB0\u5F55
|
|
38
|
+
`));for(let n of r.list){let s=vo[n.status]??n.status;console.log(` ID: ${n.id} | \u72B6\u6001: ${s} | \u4EF7\u683C: ${n.price} | stockGoodsId: ${n.stockGoodsId}`)}}catch(o){if(t.json){let r=o instanceof Error?o.message:String(o);console.log(JSON.stringify({success:!1,error:r})),process.exit(1)}m(o)}}),e}import{Command as bo}from"commander";import qt from"chalk";function Te(){let e=new bo("down");return e.description("\u4E0B\u67B6\u95F2\u9C7C\u5546\u54C1"),e.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{if(!t.id&&!(t.stockGoodsId&&t.shopId)){t.json&&(console.log(JSON.stringify({success:!1,error:"\u8BF7\u6307\u5B9A\u4E0B\u67B6\u6761\u4EF6\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"})),process.exit(1)),console.log(qt.yellow("\u8BF7\u6307\u5B9A\u4E0B\u67B6\u6761\u4EF6\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let o={};t.id&&(o.id=t.id),t.stockGoodsId&&(o.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(o.shopId=t.shopId),t.json||console.log(qt.cyan("\u{1F4E6} \u6B63\u5728\u4E0B\u67B6\u5546\u54C1..."));let r=await ae(o);t.json?console.log(JSON.stringify({success:!0,data:r},null,2)):(console.log(qt.green("\u2705 \u4E0B\u67B6\u6210\u529F")),console.log(JSON.stringify(r,null,2)))}catch(o){if(t.json){let r=o instanceof Error?o.message:String(o);console.log(JSON.stringify({success:!1,error:r})),process.exit(1)}m(o)}}),e}import{Command as Ao}from"commander";import mt from"chalk";function Pe(){let e=new Ao("price");return e.description("\u4FEE\u6539\u95F2\u9C7C\u4E0A\u67B6\u5546\u54C1\u4EF7\u683C"),e.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--price <amount>","\u65B0\u4EF7\u683C\uFF08\u5FC5\u586B\uFF09").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{if(!t.price){t.json&&(console.log(JSON.stringify({success:!1,error:"--price <amount> \u4E3A\u5FC5\u586B\u53C2\u6570"})),process.exit(1)),console.log(mt.yellow("--price <amount> \u4E3A\u5FC5\u586B\u53C2\u6570"));return}if(!t.id&&!(t.stockGoodsId&&t.shopId)){t.json&&(console.log(JSON.stringify({success:!1,error:"\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"})),process.exit(1)),console.log(mt.yellow("\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let o={price:Number(t.price)};t.id&&(o.id=t.id),t.stockGoodsId&&(o.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(o.shopId=t.shopId),t.json||console.log(mt.cyan(`\u{1F4B0} \u6B63\u5728\u4FEE\u6539\u4EF7\u683C\u4E3A ${t.price}...`));let r=await ce(o);t.json?console.log(JSON.stringify({success:!0,data:r},null,2)):(console.log(mt.green("\u2705 \u4EF7\u683C\u4FEE\u6539\u6210\u529F")),console.log(JSON.stringify(r,null,2)))}catch(o){if(t.json){let r=o instanceof Error?o.message:String(o);console.log(JSON.stringify({success:!1,error:r})),process.exit(1)}m(o)}}),e}function ke(){let e=new Lo("goods");return e.description("\u5546\u54C1\u7BA1\u7406"),e.addCommand(he()),e.addCommand(xe()),e.addCommand(Se()),e.addCommand(Ie()),e.addCommand(Te()),e.addCommand(Pe()),e.addCommand(ue()),e}import{Command as Ro}from"commander";import T from"chalk";import{promises as No}from"node:fs";import Eo from"node:path";import Oo from"node:os";import{spawn as Uo}from"node:child_process";var ut="@round2ai/r2-cli";function ve(){let e=new Ro("uninstall");return e.description("\u5378\u8F7D R2-CLI \u5E76\u6E05\u9664\u6240\u6709\u914D\u7F6E"),e.action(async()=>{try{console.log(T.yellow(`
|
|
39
|
+
\u26A0\uFE0F \u5373\u5C06\u6267\u884C\u4EE5\u4E0B\u64CD\u4F5C\uFF1A`)),console.log(T.gray(" 1. \u5220\u9664\u914D\u7F6E\u76EE\u5F55 ~/.r2-cli/")),console.log(T.gray(` 2. \u5168\u5C40\u5378\u8F7D ${ut}
|
|
40
|
+
`));let{confirm:t}=await import("@inquirer/prompts");if(!await t({message:"\u786E\u8BA4\u5378\u8F7D\uFF1F",default:!1})){console.log(T.gray("\u5DF2\u53D6\u6D88\u5378\u8F7D"));return}let r=Eo.join(Oo.homedir(),".r2-cli");try{await No.rm(r,{recursive:!0,force:!0}),console.log(T.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u6E05\u9664"))}catch{console.log(T.yellow("\u26A0\uFE0F \u914D\u7F6E\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u5220\u9664\uFF08\u53EF\u5FFD\u7565\uFF09"))}console.log(T.cyan(`\u6B63\u5728\u5378\u8F7D ${ut}...`)),Uo("npm",["uninstall","-g",ut],{stdio:"inherit",shell:!0}).on("exit",s=>{s===0?console.log(T.green(`
|
|
41
|
+
\u2705 ${ut} \u5DF2\u5378\u8F7D`)):(console.log(T.yellow(`
|
|
42
|
+
\u26A0\uFE0F npm \u5378\u8F7D\u5931\u8D25 (exit code: ${s})`)),console.log(T.gray(" \u5982\u901A\u8FC7 yarn/pnpm \u5B89\u88C5\uFF0C\u8BF7\u624B\u52A8\u5378\u8F7D"))),process.exit(s??1)})}catch(t){m(t)}}),e}function be(e){let t=e.command("auth").description("\u6388\u6743\u7BA1\u7406");t.addCommand(bt()),t.addCommand(At()),t.addCommand(Lt()),t.addCommand(Rt()),e.addCommand(ke()),e.addCommand(ve())}import Ae from"chalk";var Qt="@round2ai/r2-cli",Do=[`https://registry.npmmirror.com/${encodeURIComponent(Qt)}/latest`,`https://registry.npmjs.org/${encodeURIComponent(Qt)}/latest`],$o=5e3;async function jo(e){let t=new AbortController,o=setTimeout(()=>t.abort(),$o);try{let r=await fetch(e,{signal:t.signal});return r.ok?(await r.json()).version??null:null}catch{return null}finally{clearTimeout(o)}}async function Go(){let e=await Promise.allSettled(Do.map(jo));for(let t of e)if(t.status==="fulfilled"&&t.value)return t.value;return null}function Bo(e,t){let o=e.split(".").map(Number),r=t.split(".").map(Number);for(let n=0;n<3;n++)if((o[n]??0)!==(r[n]??0))return(o[n]??0)>(r[n]??0);return!1}async function Le(e){let t=await Go();t&&Bo(t,e)&&Jo(e,t)}function Jo(e,t){console.error(Ae.yellow(`
|
|
43
|
+
Update available: ${e} \u2192 ${t}`)+Ae.gray(`
|
|
44
|
+
Run: npm update -g ${Qt}
|
|
45
|
+
`))}async function _o(){let{default:e}=await import("figlet");console.log(z.cyan.bold(e.textSync("R2-CLI",{font:"Standard",horizontalLayout:"full"}))),console.log(z.gray(` \u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B
|
|
46
|
+
`))}function Mo(){let e=new qo;e.name("r2-cli").description("R2-CLI\uFF0C\u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B");let t=[Re.join(import.meta.dirname,"../../package.json"),Re.join(import.meta.dirname,"package.json")],o="0.0.0";for(let n of t)try{o=JSON.parse(Qo(n,"utf-8")).version;break}catch{}o==="0.0.0"&&console.error(z.yellow("Warning: unable to read version from package.json")),e.version(o,"-v, --version");let r=Le(o);return e.configureOutput({writeErr:n=>{console.error(z.red(n.replace("error:","").trim()))}}),e.action(async()=>{await _o(),e.help()}),be(e),{program:e,updateCheckPromise:r}}function Ne(){console.log(z.gray(`
|
|
47
|
+
\u64CD\u4F5C\u5DF2\u53D6\u6D88`)),process.exit(130)}process.on("SIGINT",Ne);process.on("SIGTERM",Ne);var{program:Xo,updateCheckPromise:Fo}=Mo();Xo.parse(process.argv);Fo.catch(e=>{console.error(z.gray(`[update-check] ${e instanceof Error?e.message:String(e)}`))});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@round2ai/r2-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "R2-CLI,向 AI 开放二手潮奢交易全链路能力",
|
|
5
5
|
"main": "dist/r2-cli.js",
|
|
6
6
|
"type": "module",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"r2-cli": "./dist/r2-cli.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
+
"postinstall": "node scripts/install-skills.js",
|
|
11
12
|
"build": "cross-env NODE_ENV=development node scripts/build.js",
|
|
12
13
|
"build:prod": "cross-env NODE_ENV=production node scripts/build.js",
|
|
13
14
|
"dev": "node scripts/dev.js"
|
|
@@ -24,6 +25,7 @@
|
|
|
24
25
|
],
|
|
25
26
|
"files": [
|
|
26
27
|
"dist",
|
|
28
|
+
"scripts",
|
|
27
29
|
"skills",
|
|
28
30
|
"package.json",
|
|
29
31
|
"README.md"
|
package/scripts/build.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 构建脚本 - 使用 esbuild 打包
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import esbuild from "esbuild";
|
|
7
|
+
import fs from "node:fs/promises";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
import * as dotenv from "dotenv";
|
|
11
|
+
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
const rootDir = path.dirname(__dirname);
|
|
15
|
+
|
|
16
|
+
const nodeEnv = process.env.NODE_ENV || "development";
|
|
17
|
+
const isProd = nodeEnv === "production";
|
|
18
|
+
const envFile = isProd ? ".env.production" : ".env";
|
|
19
|
+
dotenv.config({ path: path.join(rootDir, envFile) });
|
|
20
|
+
const serverBaseUrl = process.env.SERVER_BASEURL || "https://api.qiuxietang.com";
|
|
21
|
+
|
|
22
|
+
// 入口点配置
|
|
23
|
+
const entryPoints = {
|
|
24
|
+
"r2-cli": "src/entrypoints/r2-cli.tsx",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// esbuild 配置
|
|
28
|
+
const esbuildConfig = {
|
|
29
|
+
bundle: true,
|
|
30
|
+
platform: "node",
|
|
31
|
+
format: "esm",
|
|
32
|
+
sourcemap: false,
|
|
33
|
+
minify: isProd,
|
|
34
|
+
external: [
|
|
35
|
+
"commander",
|
|
36
|
+
"chalk",
|
|
37
|
+
"figlet",
|
|
38
|
+
"@inquirer/prompts",
|
|
39
|
+
"@inquirer/core",
|
|
40
|
+
"@inquirer/input",
|
|
41
|
+
"@inquirer/select",
|
|
42
|
+
"@inquirer/confirm",
|
|
43
|
+
"@inquirer/checkbox",
|
|
44
|
+
"mute-stream",
|
|
45
|
+
"qrcode",
|
|
46
|
+
"ora",
|
|
47
|
+
"react",
|
|
48
|
+
"ink",
|
|
49
|
+
"react-dom",
|
|
50
|
+
"react-devtools-core",
|
|
51
|
+
"uuid",
|
|
52
|
+
],
|
|
53
|
+
banner: {
|
|
54
|
+
js: '"use strict";',
|
|
55
|
+
},
|
|
56
|
+
define: {
|
|
57
|
+
"process.env.NODE_ENV": JSON.stringify(nodeEnv),
|
|
58
|
+
"process.env.SERVER_BASEURL": JSON.stringify(serverBaseUrl),
|
|
59
|
+
},
|
|
60
|
+
treeShaking: true,
|
|
61
|
+
splitting: false,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 清理输出目录
|
|
66
|
+
*/
|
|
67
|
+
async function cleanDist() {
|
|
68
|
+
const distDir = path.join(rootDir, "dist");
|
|
69
|
+
try {
|
|
70
|
+
await fs.rm(distDir, { recursive: true, force: true });
|
|
71
|
+
} catch (e) {
|
|
72
|
+
if (e.code === "EBUSY" || e.code === "EPERM") {
|
|
73
|
+
const files = await fs.readdir(distDir);
|
|
74
|
+
for (const file of files) {
|
|
75
|
+
await fs.rm(path.join(distDir, file), { recursive: true, force: true });
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
throw e;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
await fs.mkdir(distDir, { recursive: true });
|
|
82
|
+
console.log("🧹 清理输出目录完成");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* 构建单个入口点
|
|
87
|
+
*/
|
|
88
|
+
async function buildEntryPoint(name, entry) {
|
|
89
|
+
const outputDir = path.join(rootDir, "dist");
|
|
90
|
+
console.log(`🔨 构建 ${name} -> ${path.relative(rootDir, outputDir)}`);
|
|
91
|
+
|
|
92
|
+
const config = { ...esbuildConfig };
|
|
93
|
+
if (name === "r2-cli") {
|
|
94
|
+
config.banner = {
|
|
95
|
+
js: "#!/usr/bin/env node\n",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
await esbuild.build({
|
|
101
|
+
...config,
|
|
102
|
+
entryPoints: [path.join(rootDir, entry)],
|
|
103
|
+
outdir: outputDir,
|
|
104
|
+
// 保持原始文件名,不加 outdir 的 hash 前缀
|
|
105
|
+
// outdir 会自动生成文件名,不需要 outfile
|
|
106
|
+
});
|
|
107
|
+
console.log(`✅ ${name} 构建成功`);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.error(`❌ ${name} 构建失败:`, error.message);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 复制必要文件
|
|
116
|
+
*/
|
|
117
|
+
async function copyFiles() {
|
|
118
|
+
const filesToCopy = ["package.json", "README.md"];
|
|
119
|
+
|
|
120
|
+
for (const file of filesToCopy) {
|
|
121
|
+
const src = path.join(rootDir, file);
|
|
122
|
+
const dest = path.join(rootDir, "dist", file);
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
await fs.copyFile(src, dest);
|
|
126
|
+
console.log(`📄 已复制 ${file}`);
|
|
127
|
+
} catch {
|
|
128
|
+
// file doesn't exist, skip
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 复制 QR 页面 HTML 文件到 dist/pages/
|
|
133
|
+
const pagesDir = path.join(rootDir, "dist", "pages");
|
|
134
|
+
await fs.mkdir(pagesDir, { recursive: true });
|
|
135
|
+
const htmlSrcDir = path.join(rootDir, "src", "qr-server", "pages");
|
|
136
|
+
const htmlFiles = await fs.readdir(htmlSrcDir);
|
|
137
|
+
for (const file of htmlFiles) {
|
|
138
|
+
if (file.endsWith(".html")) {
|
|
139
|
+
await fs.copyFile(path.join(htmlSrcDir, file), path.join(pagesDir, file));
|
|
140
|
+
console.log(`📄 已复制 pages/${file}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 构建项目
|
|
147
|
+
*/
|
|
148
|
+
async function build() {
|
|
149
|
+
console.log("🚀 开始构建 R2-CLI...\n");
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
// 1. 清理输出目录
|
|
153
|
+
await cleanDist();
|
|
154
|
+
|
|
155
|
+
// 2. 构建所有入口点
|
|
156
|
+
console.log("🔨 开始构建入口点...\n");
|
|
157
|
+
for (const [name, entry] of Object.entries(entryPoints)) {
|
|
158
|
+
await buildEntryPoint(name, entry);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 3. 复制必要文件
|
|
162
|
+
await copyFiles();
|
|
163
|
+
|
|
164
|
+
console.log("\n✅ 构建完成!");
|
|
165
|
+
console.log("\n📦 输出文件:");
|
|
166
|
+
Object.keys(entryPoints).forEach((name) => {
|
|
167
|
+
console.log(` • dist/${name}.js`);
|
|
168
|
+
});
|
|
169
|
+
} catch (error) {
|
|
170
|
+
console.error("❌ 构建失败:", error);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 运行构建
|
|
176
|
+
build();
|
package/scripts/dev.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 开发模式 - 直接运行源码
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { spawn } from 'child_process';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
12
|
+
const rootDir = path.dirname(__dirname);
|
|
13
|
+
|
|
14
|
+
const child = spawn('npx', ['tsx', 'src/entrypoints/r2-cli.tsx', ...process.argv.slice(2)], {
|
|
15
|
+
cwd: rootDir,
|
|
16
|
+
stdio: 'inherit',
|
|
17
|
+
shell: true,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
child.on('exit', (code) => {
|
|
21
|
+
process.exit(code ?? 1);
|
|
22
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* postinstall: 将 skills/ 复制到 ~/.agents/skills/ + 确保 ~/.claude/skills/ 符号链接存在
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import os from "node:os";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
|
|
10
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
const pkgSkillsDir = path.join(__dirname, "..", "skills");
|
|
12
|
+
const agentsDir = path.join(os.homedir(), ".agents", "skills");
|
|
13
|
+
const claudeDir = path.join(os.homedir(), ".claude", "skills");
|
|
14
|
+
|
|
15
|
+
if (!fs.existsSync(pkgSkillsDir)) process.exit(0);
|
|
16
|
+
|
|
17
|
+
fs.mkdirSync(agentsDir, { recursive: true });
|
|
18
|
+
|
|
19
|
+
for (const name of fs.readdirSync(pkgSkillsDir)) {
|
|
20
|
+
const rawSrc = path.join(pkgSkillsDir, name);
|
|
21
|
+
// npm 包内是真实目录,本地开发可能是 symlink → 解析真实路径
|
|
22
|
+
let src;
|
|
23
|
+
try { src = fs.realpathSync(rawSrc); } catch { continue; }
|
|
24
|
+
if (!fs.statSync(src).isDirectory()) continue;
|
|
25
|
+
|
|
26
|
+
const dest = path.join(agentsDir, name);
|
|
27
|
+
// 清空目标目录中的旧残留文件
|
|
28
|
+
if (fs.existsSync(dest)) {
|
|
29
|
+
for (const old of fs.readdirSync(dest)) {
|
|
30
|
+
fs.unlinkSync(path.join(dest, old));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
34
|
+
|
|
35
|
+
for (const file of fs.readdirSync(src)) {
|
|
36
|
+
fs.copyFileSync(path.join(src, file), path.join(dest, file));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 确保 ~/.claude/skills/<name> 指向 ~/.agents/skills/<name>
|
|
40
|
+
const link = path.join(claudeDir, name);
|
|
41
|
+
if (!fs.existsSync(link)) {
|
|
42
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
43
|
+
const target = dest;
|
|
44
|
+
try {
|
|
45
|
+
fs.symlinkSync(target, link, "junction");
|
|
46
|
+
} catch {
|
|
47
|
+
// Windows 权限不足时 fallback:直接复制
|
|
48
|
+
fs.mkdirSync(link, { recursive: true });
|
|
49
|
+
for (const file of fs.readdirSync(dest)) {
|
|
50
|
+
fs.copyFileSync(path.join(dest, file), path.join(link, file));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|