@round2ai/r2-cli 1.0.13 → 1.0.14

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 CHANGED
@@ -21,7 +21,7 @@ R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com
21
21
  | 类别 | 能力 |
22
22
  |------|------|
23
23
  | 认证登录 | 扫码登录(第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出(Agent 一步式流程) |
24
- | 商品管理 | 商品上架(4 步流程:获取店铺 → 获取仓库 → 获取选品商品 → 提交上架 + 自动轮询上架结果)、商品信息修改(AI 读图识别 → 自动匹配类目/属性 → 提交修改)、店铺查看、仓库查看、选品商品查看、上架列表查询、下架、改价 |
24
+ | 商品管理 | 商品上架(4 步流程:获取店铺 → 获取仓库 → 获取选品商品 → 提交上架 + 自动轮询上架结果)、店铺查看、仓库查看、选品商品查看、上架列表查询、下架、改价 |
25
25
  | 闲鱼挂售 | 图片上传 → AI 读图识别商品信息 → 自动匹配类目/属性 → 提交挂售 |
26
26
 
27
27
  ---
@@ -146,8 +146,8 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
146
146
  |------|------|
147
147
  | `r2-cli goods shops [--json]` | 查看所有已授权店铺(跨平台) |
148
148
  | `r2-cli goods stocks [--json]` | 查看所有仓库 |
149
- | `r2-cli goods list [--stock-id <id>] [--stock-goods-id <id>] [--json]` | 查看选品商品(可按仓库或商品 ID 过滤,支持 `--page` 和 `--size`) |
150
- | `r2-cli goods listing [--json]` | 查询上架列表(支持 `--id` / `--shop-id` / `--stock-goods-id` / `--stock-id` / `--status` / `--platform` 过滤) |
149
+ | `r2-cli goods list [--stock-id <id>] [--stock-goods-id <id>] [--json]` | 查看选品商品(可按仓库或商品 ID 过滤,支持 `--page` 和 `--size`,最大 50) |
150
+ | `r2-cli goods listing [--json]` | 查询上架列表(支持 `--id` / `--shop-id` / `--stock-goods-id` / `--stock-id` / `--status <init|up|down|fail|sold>` / `--platform` 过滤,支持 `--page` / `--size` 分页) |
151
151
 
152
152
  ### 商品上架/下架/改价
153
153
 
@@ -158,19 +158,6 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
158
158
  | `r2-cli goods down --id <id> [--json]` | 下架商品(也可用 `--stock-goods-id <id> --shop-id <id>`) |
159
159
  | `r2-cli goods price --id <id> --price <amount> [--json]` | 修改上架价格(也可用 `--stock-goods-id <id> --shop-id <id>`) |
160
160
 
161
- ### 修改商品信息
162
-
163
- 修改已上架商品的标题、描述、品牌、类目、图片、属性等。Agent 可自动读图识别并填充商品信息。
164
-
165
- | 命令 | 说明 |
166
- |------|------|
167
- | `r2-cli goods edit --id <id> --category-id <id> --channel-cat-id <id> --json` | 修改商品信息(必填:定位参数 + 类目) |
168
- | `r2-cli goods edit --id <id> --category-id <id> --channel-cat-id <id> --image-ids <ids> --item-attrs <json> --brand-name <name> --json` | 带图片和属性修改 |
169
-
170
- **定位商品**:优先使用 `--id <goodsListingId>`(从上架列表 `id` 字段获取),也可用 `--stock-goods-id <id> --account <shopId>`。**必填参数**:定位参数(二选一)+ `--category-id` + `--channel-cat-id`(后端必填)
171
-
172
- **可选参数**:`--title`、`--desc`、`--image-ids`(需先通过 `hang-up upload-images` 上传)、`--item-attrs`(JSON)、`--brand-name`、`--stuff-status`、`--goods-no`、`--original-price`、`--size`
173
-
174
161
  ### 闲鱼挂售(完整商品信息模式)
175
162
 
176
163
  挂售模式支持完整的商品信息:图片、类目、属性、品牌等。Agent 可自动识别图片内容填充商品信息,流程:上传图片 → AI 识别 → 匹配类目/属性 → 提交。
@@ -180,7 +167,6 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
180
167
  | `r2-cli goods hang-up categories [--json]` | 获取闲鱼类目列表(大分类 → 小分类) |
181
168
  | `r2-cli goods hang-up props --channel-cat-id <id> [--json]` | 获取指定类目下的属性列表(含可选值) |
182
169
  | `r2-cli goods hang-up brands --channel-cat-id <id> --prop-id <id> --key <keyword> [--json]` | 品牌搜索 |
183
- | `r2-cli goods hang-up upload-images --shop-id <id> --files <paths> --json` | 批量上传图片到闲鱼(挂售前必须先上传) |
184
170
  | `r2-cli goods hang-up submit --shop-id <id> --title <> --price <> --category-id <> --channel-cat-id <> --image-ids <> --stuff-status <> --desc <> --out-item-no <> --json` | 提交挂售上架 |
185
171
 
186
172
  **挂售必填参数**:`--shop-id`、`--title`、`--price`、`--category-id`(大分类 ID)、`--channel-cat-id`(小分类 ID)、`--image-ids`(图片 ID,逗号分隔)、`--stuff-status`(成色:100 全新 / -1 准新 / 99 99新 / 95 95新 / 90 9新)、`--desc`(商品描述)、`--out-item-no`(商家编码,同店铺唯一)
@@ -204,7 +190,7 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
204
190
 
205
191
  建议:
206
192
  - Agent 收到"上架"指令时,若用户未明确指定方式(选品上架/挂售上架),**必须询问用户**选择哪种上架方式
207
- - Agent 自动识别图片并填充商品信息,缺少必填字段(售价、商家编码)时会向用户询问
193
+ - Agent 自动识别图片并填充商品信息,售价必问用户;商家编码优先让用户自定义,不填则自动生成推荐
208
194
  - Token 存储在本地 `~/.r2-cli/config.json`(原子写入,防止中断导致配置丢失),注意保护
209
195
 
210
196
  ---
package/dist/README.md CHANGED
@@ -21,7 +21,7 @@ R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com
21
21
  | 类别 | 能力 |
22
22
  |------|------|
23
23
  | 认证登录 | 扫码登录(第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出(Agent 一步式流程) |
24
- | 商品管理 | 商品上架(4 步流程:获取店铺 → 获取仓库 → 获取选品商品 → 提交上架 + 自动轮询上架结果)、商品信息修改(AI 读图识别 → 自动匹配类目/属性 → 提交修改)、店铺查看、仓库查看、选品商品查看、上架列表查询、下架、改价 |
24
+ | 商品管理 | 商品上架(4 步流程:获取店铺 → 获取仓库 → 获取选品商品 → 提交上架 + 自动轮询上架结果)、店铺查看、仓库查看、选品商品查看、上架列表查询、下架、改价 |
25
25
  | 闲鱼挂售 | 图片上传 → AI 读图识别商品信息 → 自动匹配类目/属性 → 提交挂售 |
26
26
 
27
27
  ---
@@ -146,8 +146,8 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
146
146
  |------|------|
147
147
  | `r2-cli goods shops [--json]` | 查看所有已授权店铺(跨平台) |
148
148
  | `r2-cli goods stocks [--json]` | 查看所有仓库 |
149
- | `r2-cli goods list [--stock-id <id>] [--stock-goods-id <id>] [--json]` | 查看选品商品(可按仓库或商品 ID 过滤,支持 `--page` 和 `--size`) |
150
- | `r2-cli goods listing [--json]` | 查询上架列表(支持 `--id` / `--shop-id` / `--stock-goods-id` / `--stock-id` / `--status` / `--platform` 过滤) |
149
+ | `r2-cli goods list [--stock-id <id>] [--stock-goods-id <id>] [--json]` | 查看选品商品(可按仓库或商品 ID 过滤,支持 `--page` 和 `--size`,最大 50) |
150
+ | `r2-cli goods listing [--json]` | 查询上架列表(支持 `--id` / `--shop-id` / `--stock-goods-id` / `--stock-id` / `--status <init|up|down|fail|sold>` / `--platform` 过滤,支持 `--page` / `--size` 分页) |
151
151
 
152
152
  ### 商品上架/下架/改价
153
153
 
@@ -158,19 +158,6 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
158
158
  | `r2-cli goods down --id <id> [--json]` | 下架商品(也可用 `--stock-goods-id <id> --shop-id <id>`) |
159
159
  | `r2-cli goods price --id <id> --price <amount> [--json]` | 修改上架价格(也可用 `--stock-goods-id <id> --shop-id <id>`) |
160
160
 
161
- ### 修改商品信息
162
-
163
- 修改已上架商品的标题、描述、品牌、类目、图片、属性等。Agent 可自动读图识别并填充商品信息。
164
-
165
- | 命令 | 说明 |
166
- |------|------|
167
- | `r2-cli goods edit --id <id> --category-id <id> --channel-cat-id <id> --json` | 修改商品信息(必填:定位参数 + 类目) |
168
- | `r2-cli goods edit --id <id> --category-id <id> --channel-cat-id <id> --image-ids <ids> --item-attrs <json> --brand-name <name> --json` | 带图片和属性修改 |
169
-
170
- **定位商品**:优先使用 `--id <goodsListingId>`(从上架列表 `id` 字段获取),也可用 `--stock-goods-id <id> --account <shopId>`。**必填参数**:定位参数(二选一)+ `--category-id` + `--channel-cat-id`(后端必填)
171
-
172
- **可选参数**:`--title`、`--desc`、`--image-ids`(需先通过 `hang-up upload-images` 上传)、`--item-attrs`(JSON)、`--brand-name`、`--stuff-status`、`--goods-no`、`--original-price`、`--size`
173
-
174
161
  ### 闲鱼挂售(完整商品信息模式)
175
162
 
176
163
  挂售模式支持完整的商品信息:图片、类目、属性、品牌等。Agent 可自动识别图片内容填充商品信息,流程:上传图片 → AI 识别 → 匹配类目/属性 → 提交。
@@ -180,7 +167,6 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
180
167
  | `r2-cli goods hang-up categories [--json]` | 获取闲鱼类目列表(大分类 → 小分类) |
181
168
  | `r2-cli goods hang-up props --channel-cat-id <id> [--json]` | 获取指定类目下的属性列表(含可选值) |
182
169
  | `r2-cli goods hang-up brands --channel-cat-id <id> --prop-id <id> --key <keyword> [--json]` | 品牌搜索 |
183
- | `r2-cli goods hang-up upload-images --shop-id <id> --files <paths> --json` | 批量上传图片到闲鱼(挂售前必须先上传) |
184
170
  | `r2-cli goods hang-up submit --shop-id <id> --title <> --price <> --category-id <> --channel-cat-id <> --image-ids <> --stuff-status <> --desc <> --out-item-no <> --json` | 提交挂售上架 |
185
171
 
186
172
  **挂售必填参数**:`--shop-id`、`--title`、`--price`、`--category-id`(大分类 ID)、`--channel-cat-id`(小分类 ID)、`--image-ids`(图片 ID,逗号分隔)、`--stuff-status`(成色:100 全新 / -1 准新 / 99 99新 / 95 95新 / 90 9新)、`--desc`(商品描述)、`--out-item-no`(商家编码,同店铺唯一)
@@ -204,7 +190,7 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
204
190
 
205
191
  建议:
206
192
  - Agent 收到"上架"指令时,若用户未明确指定方式(选品上架/挂售上架),**必须询问用户**选择哪种上架方式
207
- - Agent 自动识别图片并填充商品信息,缺少必填字段(售价、商家编码)时会向用户询问
193
+ - Agent 自动识别图片并填充商品信息,售价必问用户;商家编码优先让用户自定义,不填则自动生成推荐
208
194
  - Token 存储在本地 `~/.r2-cli/config.json`(原子写入,防止中断导致配置丢失),注意保护
209
195
 
210
196
  ---
package/dist/r2-cli.js CHANGED
@@ -1,49 +1,49 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- var me=Object.defineProperty;var at=(o,t)=>()=>(o&&(t=o(o=0)),t);var ct=(o,t)=>{for(var e in t)me(o,e,{get:t[e],enumerable:!0})};var ho={};ct(ho,{UserInfoCard:()=>Re});import{Box as H,Text as G}from"ink";import{jsx as J,jsxs as V}from"react/jsx-runtime";function Re({userInfo:o,lastLogin:t,daysSinceLogin:e}){let r=o.mobile?o.mobile.replace(/(\d{3})\d{4}(\d{4})/,"$1****$2"):"-";return V(H,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[J(G,{bold:!0,color:"cyan",children:"\u7528\u6237\u4FE1\u606F"}),V(H,{flexDirection:"row",marginTop:1,children:[J(H,{width:10,children:J(G,{color:"gray",children:"\u6635\u79F0"})}),J(G,{color:"yellow",children:o.nickname})]}),V(H,{flexDirection:"row",children:[J(H,{width:10,children:J(G,{color:"gray",children:"\u624B\u673A\u53F7"})}),J(G,{color:"yellow",children:r})]}),t&&V(H,{flexDirection:"column",marginTop:1,children:[V(G,{color:"gray",children:["\u6700\u540E\u767B\u5F55: ",t.toLocaleString()]}),e!==void 0&&V(G,{color:"gray",children:[" \u8DDD\u4ECA: ",e," \u5929"]})]})]})}var yo=at(()=>{"use strict"});var pt={};ct(pt,{renderComponent:()=>Bt,renderOnce:()=>wo});import Le from"react";import $t from"chalk";import{render as Oe}from"ink";import{Writable as De}from"node:stream";function wo(o){let t=$t.level;process.env.NO_COLOR||($t.level=3);try{let e=[],r=new De({write(l,w,m){e.push(Buffer.from(l)),m()}});r.isTTY=!0,r.columns=process.stdout.columns||80,r.rows=process.stdout.rows||24,Oe(o,{stdout:r,patchConsole:!1}).unmount();let s=Buffer.concat(e).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{$t.level=t}}function Bt(o,t){wo(Le.createElement(o,t))}var rt=at(()=>{"use strict"});var Go={};ct(Go,{ShopsTable:()=>He});import{Box as T,Text as N}from"ink";import{jsx as f,jsxs as K}from"react/jsx-runtime";function Fe(o){return o.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 ze({hasPlatform:o,fillWidth:t}){return K(T,{flexDirection:"row",paddingBottom:0,children:[o&&f(T,{width:Wt,children:f(N,{bold:!0,color:"white",children:"\u5E73\u53F0"})}),f(T,{width:t,children:f(N,{bold:!0,color:"white",children:"\u5E97\u94FA\u540D"})}),f(T,{width:Ht,children:f(N,{bold:!0,color:"white",children:"ID"})}),f(T,{width:Vt,children:f(N,{bold:!0,color:"white",children:"\u72B6\u6001"})})]})}function We({shop:o,hasPlatform:t,fillWidth:e}){let r=Bo[o.platform]??o.platform;return K(T,{flexDirection:"row",children:[t&&f(T,{width:Wt,children:f(N,{color:"cyan",children:r})}),f(T,{width:e,children:f(N,{bold:!0,children:o.name})}),f(T,{width:Ht,children:f(N,{color:"gray",children:o.id})}),f(T,{width:Vt,children:f(N,{color:"green",children:"\u25CF \u6388\u6743\u4E2D"})})]})}function He({shops:o,platform:t}){let e=Fe(o),r=t==="all",n=t==="all"?"\u6240\u6709\u6388\u6743\u5E97\u94FA":`${Bo[t]??t}\u6388\u6743\u5E97\u94FA`,s=process.stdout.columns||80,i=4,a=Ht+Vt+(r?Wt:0),l=Math.max(s-i-a,20),w=a+l;return K(T,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[K(T,{flexDirection:"row",children:[f(N,{bold:!0,color:"cyan",children:n}),K(N,{color:"gray",children:[" \xB7 ",e.length," \u5BB6"]})]}),K(T,{flexDirection:"column",marginTop:1,children:[f(ze,{hasPlatform:r,fillWidth:l}),f(N,{color:"gray",children:"\u2500".repeat(w)}),e.map(m=>f(We,{shop:m,hasPlatform:r,fillWidth:l},m.id))]})]})}var Bo,Wt,Ht,Vt,Jo=at(()=>{"use strict";Bo={xianyu:"\u95F2\u9C7C",douyin:"\u6296\u97F3"},Wt=8,Ht=16,Vt=10});var _o={};ct(_o,{StocksTable:()=>Ze});import{Box as I,Text as b}from"ink";import{jsx as u,jsxs as Y}from"react/jsx-runtime";function Ke({fillWidth:o}){return Y(I,{flexDirection:"row",paddingBottom:0,children:[u(I,{width:Kt,children:u(b,{bold:!0,color:"white",children:"ID"})}),u(I,{width:Yt,children:u(b,{bold:!0,color:"white",children:"\u7528\u6237ID"})}),u(I,{width:Zt,children:u(b,{bold:!0,color:"white",children:"\u4ED3\u5E93ID"})}),u(I,{width:o,children:u(b,{bold:!0,color:"white",children:"\u4ED3\u5E93\u540D\u79F0"})}),u(I,{width:to,children:u(b,{bold:!0,color:"white",children:"\u521B\u5EFA\u65F6\u95F4"})})]})}function Ye({stock:o,fillWidth:t}){let e=new Date(o.gmtCreate).toLocaleString("zh-CN");return Y(I,{flexDirection:"row",children:[u(I,{width:Kt,children:u(b,{color:"gray",children:o.id})}),u(I,{width:Yt,children:u(b,{color:"gray",children:o.userId})}),u(I,{width:Zt,children:u(b,{color:"gray",children:o.stockId})}),u(I,{width:t,children:u(b,{bold:!0,children:o.stockName})}),u(I,{width:to,children:u(b,{color:"gray",children:e})})]})}function Ze({stocks:o}){let t=process.stdout.columns||80,e=4,r=Kt+Yt+Zt+to,n=Math.max(t-e-r,20),s=r+n;return Y(I,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[Y(I,{flexDirection:"row",children:[u(b,{bold:!0,color:"cyan",children:"\u4ED3\u5E93\u5217\u8868"}),Y(b,{color:"gray",children:[" \xB7 ",o.length," \u4E2A"]})]}),Y(I,{flexDirection:"column",marginTop:1,children:[u(Ke,{fillWidth:n}),u(b,{color:"gray",children:"\u2500".repeat(s)}),o.map(i=>u(Ye,{stock:i,fillWidth:n},i.id))]})]})}var Kt,Yt,Zt,to,Qo=at(()=>{"use strict";Kt=6,Yt=10,Zt=10,to=22});import{Command as Lr}from"commander";import ot from"chalk";import"commander";import{Command as bo}from"commander";import x from"chalk";var M=class o extends Error{constructor(e,r,n){super(e);this.code=r;this.details=n;this.name="R2Error",Error.captureStackTrace&&Error.captureStackTrace(this,o)}code;details},A=class extends M{constructor(e,r,n){super(e,"API_ERROR",n);this.status=r;this.response=n;this.name="ApiError"}status;response},$=class extends M{constructor(e,r,n){super(e,"STORAGE_ERROR",{path:r,code:n});this.path=r;this.code=n;this.name="StorageError"}path;code},S=class extends M{constructor(t){super(t,"AUTH_ERROR"),this.name="AuthError"}},U=class extends M{constructor(e,r,n){super(e,"POLLING_ERROR",{attempts:r,timeout:n});this.attempts=r;this.timeout=n;this.name="PollingError"}attempts;timeout};async function ge(o,t,e){let r=new AbortController,n=()=>r.abort();e?.addEventListener("abort",n,{once:!0});let s=setTimeout(()=>r.abort(),t);try{return await o()}catch(i){throw r.signal.aborted&&!e?.aborted?new U("\u5355\u6B21\u8F6E\u8BE2\u8BF7\u6C42\u8D85\u65F6"):i}finally{clearTimeout(s),e?.removeEventListener("abort",n)}}async function F(o,t,e){let{interval:r,timeout:n,condition:s}=t,i=Date.now(),a=0;for(;Date.now()-i<n;){if(e?.aborted)throw new U("\u8F6E\u8BE2\u88AB\u4E2D\u6B62");a++;let l=n-(Date.now()-i),w=await ge(o,l,e);if(s(w,a))return w;await pe(r,e)}throw new U(`\u8F6E\u8BE2\u8D85\u65F6 (\u5DF2\u7B49\u5F85 ${Date.now()-i}ms, \u5171 ${a} \u6B21)`)}function pe(o,t){return new Promise((e,r)=>{if(t?.aborted){r(new U("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"));return}let n=()=>{clearTimeout(s),r(new U("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"))},s=setTimeout(()=>{t?.removeEventListener("abort",n),e()},o);t?.addEventListener("abort",n,{once:!0})})}import ye from"node:fs";import{fileURLToPath as we}from"node:url";import{createRequire as xe}from"node:module";import lo from"node:path";import{exec as Ie}from"node:child_process";import fe from"node:http";var vt=class o{server=null;pages=new Map;port=0;idleTimer=null;static IDLE_TIMEOUT_MS=1e4;async start(){return this.server?this.port:new Promise((t,e)=>{this.server=fe.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)):e(new Error("Failed to get server address"))}),this.server.on("error",e)})}registerPage(t,e,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"})}
3
+ var ce=Object.defineProperty;var it=(o,t)=>()=>(o&&(t=o(o=0)),t);var at=(o,t)=>{for(var e in t)ce(o,e,{get:t[e],enumerable:!0})};var fo={};at(fo,{UserInfoCard:()=>Ae});import{Box as H,Text as G}from"ink";import{jsx as q,jsxs as V}from"react/jsx-runtime";function Ae({userInfo:o,lastLogin:t,daysSinceLogin:e}){let r=o.mobile?o.mobile.replace(/(\d{3})\d{4}(\d{4})/,"$1****$2"):"-";return V(H,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[q(G,{bold:!0,color:"cyan",children:"\u7528\u6237\u4FE1\u606F"}),V(H,{flexDirection:"row",marginTop:1,children:[q(H,{width:10,children:q(G,{color:"gray",children:"\u6635\u79F0"})}),q(G,{color:"yellow",children:o.nickname})]}),V(H,{flexDirection:"row",children:[q(H,{width:10,children:q(G,{color:"gray",children:"\u624B\u673A\u53F7"})}),q(G,{color:"yellow",children:r})]}),t&&V(H,{flexDirection:"column",marginTop:1,children:[V(G,{color:"gray",children:["\u6700\u540E\u767B\u5F55: ",t.toLocaleString()]}),e!==void 0&&V(G,{color:"gray",children:[" \u8DDD\u4ECA: ",e," \u5929"]})]})]})}var ho=it(()=>{"use strict"});var gt={};at(gt,{renderComponent:()=>$t,renderOnce:()=>yo});import ke from"react";import jt from"chalk";import{render as ve}from"ink";import{Writable as Ne}from"node:stream";function yo(o){let t=jt.level;process.env.NO_COLOR||(jt.level=3);try{let e=[],r=new Ne({write(l,y,m){e.push(Buffer.from(l)),m()}});r.isTTY=!0,r.columns=process.stdout.columns||80,r.rows=process.stdout.rows||24,ve(o,{stdout:r,patchConsole:!1}).unmount();let s=Buffer.concat(e).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{jt.level=t}}function $t(o,t){yo(ke.createElement(o,t))}var et=it(()=>{"use strict"});var jo={};at(jo,{ShopsTable:()=>_e});import{Box as S,Text as N}from"ink";import{jsx as f,jsxs as K}from"react/jsx-runtime";function qe(o){return o.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 Je({hasPlatform:o,fillWidth:t}){return K(S,{flexDirection:"row",paddingBottom:0,children:[o&&f(S,{width:zt,children:f(N,{bold:!0,color:"white",children:"\u5E73\u53F0"})}),f(S,{width:t,children:f(N,{bold:!0,color:"white",children:"\u5E97\u94FA\u540D"})}),f(S,{width:Wt,children:f(N,{bold:!0,color:"white",children:"ID"})}),f(S,{width:Ht,children:f(N,{bold:!0,color:"white",children:"\u72B6\u6001"})})]})}function Xe({shop:o,hasPlatform:t,fillWidth:e}){let r=Eo[o.platform]??o.platform;return K(S,{flexDirection:"row",children:[t&&f(S,{width:zt,children:f(N,{color:"cyan",children:r})}),f(S,{width:e,children:f(N,{bold:!0,children:o.name})}),f(S,{width:Wt,children:f(N,{color:"gray",children:o.id})}),f(S,{width:Ht,children:f(N,{color:"green",children:"\u25CF \u6388\u6743\u4E2D"})})]})}function _e({shops:o,platform:t}){let e=qe(o),r=t==="all",n=t==="all"?"\u6240\u6709\u6388\u6743\u5E97\u94FA":`${Eo[t]??t}\u6388\u6743\u5E97\u94FA`,s=process.stdout.columns||80,i=4,a=Wt+Ht+(r?zt:0),l=Math.max(s-i-a,20),y=a+l;return K(S,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[K(S,{flexDirection:"row",children:[f(N,{bold:!0,color:"cyan",children:n}),K(N,{color:"gray",children:[" \xB7 ",e.length," \u5BB6"]})]}),K(S,{flexDirection:"column",marginTop:1,children:[f(Je,{hasPlatform:r,fillWidth:l}),f(N,{color:"gray",children:"\u2500".repeat(y)}),e.map(m=>f(Xe,{shop:m,hasPlatform:r,fillWidth:l},m.id))]})]})}var Eo,zt,Wt,Ht,$o=it(()=>{"use strict";Eo={xianyu:"\u95F2\u9C7C",douyin:"\u6296\u97F3"},zt=8,Wt=16,Ht=10});var qo={};at(qo,{StocksTable:()=>ze});import{Box as x,Text as C}from"ink";import{jsx as u,jsxs as Y}from"react/jsx-runtime";function Me({fillWidth:o}){return Y(x,{flexDirection:"row",paddingBottom:0,children:[u(x,{width:Vt,children:u(C,{bold:!0,color:"white",children:"ID"})}),u(x,{width:Kt,children:u(C,{bold:!0,color:"white",children:"\u7528\u6237ID"})}),u(x,{width:Yt,children:u(C,{bold:!0,color:"white",children:"\u4ED3\u5E93ID"})}),u(x,{width:o,children:u(C,{bold:!0,color:"white",children:"\u4ED3\u5E93\u540D\u79F0"})}),u(x,{width:Zt,children:u(C,{bold:!0,color:"white",children:"\u521B\u5EFA\u65F6\u95F4"})})]})}function Fe({stock:o,fillWidth:t}){let e=new Date(o.gmtCreate).toLocaleString("zh-CN");return Y(x,{flexDirection:"row",children:[u(x,{width:Vt,children:u(C,{color:"gray",children:o.id})}),u(x,{width:Kt,children:u(C,{color:"gray",children:o.userId})}),u(x,{width:Yt,children:u(C,{color:"gray",children:o.stockId})}),u(x,{width:t,children:u(C,{bold:!0,children:o.stockName})}),u(x,{width:Zt,children:u(C,{color:"gray",children:e})})]})}function ze({stocks:o}){let t=process.stdout.columns||80,e=4,r=Vt+Kt+Yt+Zt,n=Math.max(t-e-r,20),s=r+n;return Y(x,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[Y(x,{flexDirection:"row",children:[u(C,{bold:!0,color:"cyan",children:"\u4ED3\u5E93\u5217\u8868"}),Y(C,{color:"gray",children:[" \xB7 ",o.length," \u4E2A"]})]}),Y(x,{flexDirection:"column",marginTop:1,children:[u(Me,{fillWidth:n}),u(C,{color:"gray",children:"\u2500".repeat(s)}),o.map(i=>u(Fe,{stock:i,fillWidth:n},i.id))]})]})}var Vt,Kt,Yt,Zt,Jo=it(()=>{"use strict";Vt=6,Kt=10,Yt=10,Zt=22});import{Command as br}from"commander";import tt from"chalk";import"commander";import{Command as To}from"commander";import w from"chalk";var M=class o extends Error{constructor(e,r,n){super(e);this.code=r;this.details=n;this.name="R2Error",Error.captureStackTrace&&Error.captureStackTrace(this,o)}code;details},P=class extends M{constructor(e,r,n){super(e,"API_ERROR",n);this.status=r;this.response=n;this.name="ApiError"}status;response},$=class extends M{constructor(e,r,n){super(e,"STORAGE_ERROR",{path:r,code:n});this.path=r;this.code=n;this.name="StorageError"}path;code},I=class extends M{constructor(t){super(t,"AUTH_ERROR"),this.name="AuthError"}},U=class extends M{constructor(e,r,n){super(e,"POLLING_ERROR",{attempts:r,timeout:n});this.attempts=r;this.timeout=n;this.name="PollingError"}attempts;timeout};async function le(o,t,e){let r=new AbortController,n=()=>r.abort();e?.addEventListener("abort",n,{once:!0});let s=setTimeout(()=>r.abort(),t);try{return await o()}catch(i){throw r.signal.aborted&&!e?.aborted?new U("\u5355\u6B21\u8F6E\u8BE2\u8BF7\u6C42\u8D85\u65F6"):i}finally{clearTimeout(s),e?.removeEventListener("abort",n)}}async function F(o,t,e){let{interval:r,timeout:n,condition:s}=t,i=Date.now(),a=0;for(;Date.now()-i<n;){if(e?.aborted)throw new U("\u8F6E\u8BE2\u88AB\u4E2D\u6B62");a++;let l=n-(Date.now()-i),y=await le(o,l,e);if(s(y,a))return y;await de(r,e)}throw new U(`\u8F6E\u8BE2\u8D85\u65F6 (\u5DF2\u7B49\u5F85 ${Date.now()-i}ms, \u5171 ${a} \u6B21)`)}function de(o,t){return new Promise((e,r)=>{if(t?.aborted){r(new U("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"));return}let n=()=>{clearTimeout(s),r(new U("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"))},s=setTimeout(()=>{t?.removeEventListener("abort",n),e()},o);t?.addEventListener("abort",n,{once:!0})})}import ge from"node:fs";import{fileURLToPath as pe}from"node:url";import{createRequire as fe}from"node:module";import co from"node:path";import{exec as he}from"node:child_process";import ue from"node:http";var kt=class o{server=null;pages=new Map;port=0;idleTimer=null;static IDLE_TIMEOUT_MS=1e4;async start(){return this.server?this.port:new Promise((t,e)=>{this.server=ue.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)):e(new Error("Failed to get server address"))}),this.server.on("error",e)})}registerPage(t,e,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
6
  `;for(let a of s.sseClients)a.write(i)}else this.pages.set(t,{html:e,qrBuffer:r,status:"waiting",sseClients:[],config:n});this.resetIdleTimer()}unregisterPage(t){let e=this.pages.get(t);if(e){for(let r of e.sseClients)r.end();e.sseClients.length=0,this.pages.delete(t),this.pages.size===0&&this.close()}}setStatus(t,e){let r=this.pages.get(t);if(!r)return;r.status=e;let n=`data: ${JSON.stringify({status:e})}
7
7
 
8
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 e of t.sseClients)e.end();t.sseClients.length=0}this.pages.clear(),this.server.close(),this.server=null,this.port=0,z=null}}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>{[...this.pages.values()].some(e=>e.sseClients.length>0)||this.close()},o.IDLE_TIMEOUT_MS)}handleRequest(t,e){let r=t.url??"/";for(let[n,s]of this.pages){if(r===n){e.writeHead(302,{Location:n+"/"}),e.end();return}if(r===n+"/"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(s.html);return}if(r===n+"/qr.png"){e.writeHead(200,{"Content-Type":"image/png","Content-Length":s.qrBuffer.length}),e.end(s.qrBuffer);return}if(r===n+"/events"){e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),e.write(`data: ${JSON.stringify({status:s.status})}
9
9
 
10
- `),s.sseClients.push(e),t.on("close",()=>{let i=s.sseClients.indexOf(e);i>=0&&s.sseClients.splice(i,1)});return}if(r===n+"/config"){e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(s.config??{}));return}}e.writeHead(404,{"Content-Type":"text/plain"}),e.end("Not Found")}},z=null,ao=!1;function lt(){z&&z.close()}function he(){ao||(ao=!0,process.on("exit",lt),process.on("SIGINT",lt),process.on("SIGTERM",lt),setInterval(()=>{process.stdin?.destroyed&&lt()},3e3).unref())}function co(){return z||(z=new vt,he()),z}var Se=lo.dirname(we(import.meta.url)),Ce="/login",Te="/login-xianyu",Nt=null;async function be(o){return ye.promises.readFile(lo.join(Se,"pages",o),"utf-8")}async function Pe(o){return Nt||(Nt=xe(import.meta.url)),Nt("qrcode").toBuffer(o,{width:300,margin:2})}function B(o){let t=process.platform==="win32"?`start "" "${o}"`:process.platform==="darwin"?`open "${o}"`:`xdg-open "${o}"`;Ie(t)}async function uo(o,t,e,r){let[n,s]=await Promise.all([be(t),Pe(e)]),i=co(),a=await i.start();i.registerPage(o,n,s,r);let l=`http://127.0.0.1:${a}${o}/`;return{url:e,qrUrl:l,setStatus:w=>i.setStatus(o,w),closeServer:()=>i.unregisterPage(o)}}function Rt(o){return uo(Ce,"login.html",o)}function Lt(o,t){return uo(Te,"xianyu-auth.html",o,{authUrl:t})}import{promises as W}from"node:fs";import Ot from"node:path";import Ae from"node:os";var ke=".r2-cli",dt=class{configPath;config;configLoaded=!1;dirEnsured=!1;constructor(){let t=Ae.homedir(),e=Ot.join(t,ke);this.configPath=Ot.join(e,"config.json"),this.config={credentials:null}}getConfigPath(){return this.configPath}async loadConfig(){if(this.configLoaded)return this.config;try{let t=await W.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=Ot.dirname(this.configPath);try{await W.stat(t)}catch(e){if(e.code==="ENOENT")await W.mkdir(t,{recursive:!0});else throw new $("Failed to create directory",t,e.code)}this.dirEnsured=!0}async saveConfig(t){this.config=t,await this.ensureDir();let e=JSON.stringify(t,null,2),r=this.configPath+".tmp";try{await W.writeFile(r,e,"utf-8"),await W.rename(r,this.configPath),this.configLoaded=!0}catch(n){throw await W.unlink(r).catch(s=>{typeof process.env.DEBUG<"u"&&console.error("[config] cleanup tmp failed:",s)}),new $("Failed to save config",this.configPath,n.code)}}},Dt=null;function Ut(){return Dt||(Dt=new dt),Dt}var Et=300*1e3,ut=class{store=Ut();isTokenExpired(t){return t.expire?Date.now()>=t.expire-Et:!1}async saveCredentials(t,e){let r=Date.now(),n=e.expire?Number.parseInt(e.expire,10):0,s={token:t,userInfo:e,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}},jt=null;function et(){return jt||(jt=new ut),jt}var ve="https://api.puresnake.com",mt=class{config;authStorage=null;cachedToken=null;tokenExpiry=0;constructor(t={}){this.config={baseUrl:t.baseUrl??ve,version:t.version??"v3",debug:t.debug??!1},this.authStorage=t.auth===!1?null:et()}buildUrl(t){let e=t.startsWith("/")?t.slice(1):t;return`${this.config.baseUrl}/${this.config.version}/${e}`}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 S("\u8BF7\u5148\u8FD0\u884C r2-cli auth login \u767B\u5F55");return this.cachedToken=t.token,this.tokenExpiry=t.expire?t.expire-Et:Date.now()+1800*1e3,t.token}async requestFull(t,e){let r=this.buildUrl(t),{method:n,headers:s,body:i,timeout:a=3e4}=e,l=await this.getAuthToken(),w={...s,...l?{token:l}:{}},m=new AbortController,P=setTimeout(()=>m.abort(),a),_={method:n,headers:{"Content-Type":"application/json",...w},signal:m.signal};i!==void 0&&(_.body=JSON.stringify(i)),this.config.debug&&console.error(`[API ${n}]`,r,i);try{let d=await fetch(r,_);if(!d.ok){if(d.status===401)throw this.authStorage&&(this.cachedToken=null,await this.authStorage.clearCredentials().catch(Q=>{console.error("[API] \u6E05\u9664\u51ED\u8BC1\u5931\u8D25:",Q instanceof Error?Q.message:String(Q))})),new S("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");let At=await d.text();throw new A(At||`${d.status} ${d.statusText}`,d.status)}let k=await d.json();if(this.config.debug&&console.error("[API Response]",k),!k.success||k.status!==0)throw new A(k.msg||"\u672A\u77E5\u9519\u8BEF",k.status,k);return k}catch(d){throw d instanceof DOMException&&d.name==="AbortError"?new A(`\u8BF7\u6C42\u8D85\u65F6 (${a}ms)`,408):d}finally{clearTimeout(P)}}async request(t,e){return(await this.requestFull(t,e)).data}async get(t,e,r){let n=e&&e.size>0?`${t}?${e.toString()}`:t;return this.request(n,{method:"GET",headers:r})}async post(t,e,r){return this.request(t,{method:"POST",body:e,headers:r})}async put(t,e,r){return this.request(t,{method:"PUT",body:e,headers:r})}async delete(t,e){return this.request(t,{method:"DELETE",headers:e})}async upload(t,e,r){let n=this.buildUrl(t),s=await this.getAuthToken(),i={...r,...s?{token:s}:{}},a=new AbortController,l=setTimeout(()=>a.abort(),6e4),w={method:"POST",headers:i,body:e,signal:a.signal};this.config.debug&&console.error("[API UPLOAD]",n);try{let m=await fetch(n,w);if(!m.ok){if(m.status===401)throw this.authStorage&&(this.cachedToken=null,await this.authStorage.clearCredentials().catch(()=>{})),new S("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");let _=await m.text();throw new A(_||`${m.status} ${m.statusText}`,m.status)}let P=await m.json();if(this.config.debug&&console.error("[API Response]",P),!P.success||P.status!==0)throw new A(P.msg||"\u672A\u77E5\u9519\u8BEF",P.status,P);return P.data}catch(m){throw m instanceof DOMException&&m.name==="AbortError"?new A("\u4E0A\u4F20\u8D85\u65F6 (60000ms)",408):m}finally{clearTimeout(l)}}},gt=new mt,mo=new mt({auth:!1});var go=mo;async function po(){return go.post("app/qrcode/generate")}async function fo(o){let t=new URLSearchParams;t.append("qrToken",o);let e=`app/qrcode/status?${t.toString()}`,r=await go.requestFull(e,{method:"GET"});return r.token&&typeof r.data=="object"&&r.data!==null&&(r.data.token=r.token),r.data}async function xo(o,t,e){let{UserInfoCard:r}=await Promise.resolve().then(()=>(yo(),ho)),{renderComponent:n}=await Promise.resolve().then(()=>(rt(),pt)),s=t!=null?{userInfo:o,lastLogin:t,daysSinceLogin:e??0}:{userInfo:o};n(r,s)}var ft=class{storage;constructor(t){this.storage=t??et()}async generateQR(){let t=await po(),e=`https://m.puresnake.com/r2/auth/login?qrToken=${t.qrContent}&from=wechat`,r=await Rt(e);return{qrData:t,...r}}async waitForLogin(t,e,r,n,s,i){let a=await F(()=>fo(t),{interval:r,timeout:e,condition:l=>{switch(l.status){case"scanned":return i||(console.log(x.cyan(`
11
- \u{1F50D} \u5DF2\u626B\u7801: ${l.userInfo?.nickname||"\u672A\u77E5\u7528\u6237"}`)),console.log(x.yellow("\u8BF7\u5728 APP \u4E0A\u786E\u8BA4\u767B\u5F55"))),s?.("scanning"),!1;case"confirmed":return i||console.log(x.green(`
12
- \u2705 \u7528\u6237\u5DF2\u786E\u8BA4\u767B\u5F55`)),s?.("success"),!0;case"expired":return i||console.log(x.red(`
13
- \u23F0 \u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F`)),s?.("expired"),!0;case"canceled":return i||console.log(x.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 S("\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55"):a.status==="canceled"?new S("\u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55"):new S("\u767B\u5F55\u5931\u8D25: \u672A\u83B7\u53D6\u5230\u51ED\u8BC1")}async login(t){console.log(x.cyan(`
15
- \u{1F510} \u6B63\u5728\u542F\u52A8\u626B\u7801\u767B\u5F55...`));let{qrData:e,qrUrl:r,setStatus:n,closeServer:s}=await this.generateQR();console.log(x.green(`\u2705 \u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
16
- `)),console.log(x.cyan(` \u94FE\u63A5: ${r}
17
- `)),B(r),console.log(x.yellow(`\u23F3 \u7B49\u5F85\u626B\u7801...
18
- `));let i=Number.parseInt(e.expireTime,10),a=Number.parseInt(e.pollInterval,10);try{let l=await this.waitForLogin(e.qrToken,i,a,t,n);return console.log(x.green(`
10
+ `),s.sseClients.push(e),t.on("close",()=>{let i=s.sseClients.indexOf(e);i>=0&&s.sseClients.splice(i,1)});return}if(r===n+"/config"){e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(s.config??{}));return}}e.writeHead(404,{"Content-Type":"text/plain"}),e.end("Not Found")}},z=null,io=!1;function ct(){z&&z.close()}function me(){io||(io=!0,process.on("exit",ct),process.on("SIGINT",ct),process.on("SIGTERM",ct),setInterval(()=>{process.stdin?.destroyed&&ct()},3e3).unref())}function ao(){return z||(z=new kt,me()),z}var ye=co.dirname(pe(import.meta.url)),we="/login",xe="/login-xianyu",vt=null;async function Ie(o){return ge.promises.readFile(co.join(ye,"pages",o),"utf-8")}async function Se(o){return vt||(vt=fe(import.meta.url)),vt("qrcode").toBuffer(o,{width:300,margin:2})}function B(o){let t=process.platform==="win32"?`start "" "${o}"`:process.platform==="darwin"?`open "${o}"`:`xdg-open "${o}"`;he(t)}async function lo(o,t,e,r){let[n,s]=await Promise.all([Ie(t),Se(e)]),i=ao(),a=await i.start();i.registerPage(o,n,s,r);let l=`http://127.0.0.1:${a}${o}/`;return{url:e,qrUrl:l,setStatus:y=>i.setStatus(o,y),closeServer:()=>i.unregisterPage(o)}}function Nt(o){return lo(we,"login.html",o)}function Rt(o,t){return lo(xe,"xianyu-auth.html",o,{authUrl:t})}import{promises as W}from"node:fs";import Lt from"node:path";import Ce from"node:os";var Te=".r2-cli",lt=class{configPath;config;configLoaded=!1;dirEnsured=!1;constructor(){let t=Ce.homedir(),e=Lt.join(t,Te);this.configPath=Lt.join(e,"config.json"),this.config={credentials:null}}getConfigPath(){return this.configPath}async loadConfig(){if(this.configLoaded)return this.config;try{let t=await W.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=Lt.dirname(this.configPath);try{await W.stat(t)}catch(e){if(e.code==="ENOENT")await W.mkdir(t,{recursive:!0});else throw new $("Failed to create directory",t,e.code)}this.dirEnsured=!0}async saveConfig(t){this.config=t,await this.ensureDir();let e=JSON.stringify(t,null,2),r=this.configPath+".tmp";try{await W.writeFile(r,e,"utf-8"),await W.rename(r,this.configPath),this.configLoaded=!0}catch(n){throw await W.unlink(r).catch(s=>{typeof process.env.DEBUG<"u"&&console.error("[config] cleanup tmp failed:",s)}),new $("Failed to save config",this.configPath,n.code)}}},Ot=null;function Dt(){return Ot||(Ot=new lt),Ot}var Et=300*1e3,dt=class{store=Dt();isTokenExpired(t){return t.expire?Date.now()>=t.expire-Et:!1}async saveCredentials(t,e){let r=Date.now(),n=e.expire?Number.parseInt(e.expire,10):0,s={token:t,userInfo:e,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}},Ut=null;function ot(){return Ut||(Ut=new dt),Ut}var be="https://api.puresnake.com",ut=class{config;authStorage=null;cachedToken=null;tokenExpiry=0;constructor(t={}){this.config={baseUrl:t.baseUrl??be,version:t.version??"v3",debug:t.debug??!1},this.authStorage=t.auth===!1?null:ot()}buildUrl(t){let e=t.startsWith("/")?t.slice(1):t;return`${this.config.baseUrl}/${this.config.version}/${e}`}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 I("\u8BF7\u5148\u8FD0\u884C r2-cli auth login \u767B\u5F55");return this.cachedToken=t.token,this.tokenExpiry=t.expire?t.expire-Et:Date.now()+1800*1e3,t.token}async requestFull(t,e){let r=this.buildUrl(t),{method:n,headers:s,body:i,timeout:a=3e4}=e,l=await this.getAuthToken(),y={...s,...l?{token:l}:{}},m=new AbortController,b=setTimeout(()=>m.abort(),a),_={method:n,headers:{"Content-Type":"application/json",...y},signal:m.signal};i!==void 0&&(_.body=JSON.stringify(i)),this.config.debug&&console.error(`[API ${n}]`,r,i);try{let d=await fetch(r,_);if(!d.ok){if(d.status===401)throw this.authStorage&&(this.cachedToken=null,await this.authStorage.clearCredentials().catch(Q=>{console.error("[API] \u6E05\u9664\u51ED\u8BC1\u5931\u8D25:",Q instanceof Error?Q.message:String(Q))})),new I("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");let Pt=await d.text();throw new P(Pt||`${d.status} ${d.statusText}`,d.status)}let k=await d.json();if(this.config.debug&&console.error("[API Response]",k),!k.success||k.status!==0)throw new P(k.msg||"\u672A\u77E5\u9519\u8BEF",k.status,k);return k}catch(d){throw d instanceof DOMException&&d.name==="AbortError"?new P(`\u8BF7\u6C42\u8D85\u65F6 (${a}ms)`,408):d}finally{clearTimeout(b)}}async request(t,e){return(await this.requestFull(t,e)).data}async get(t,e,r){let n=e&&e.size>0?`${t}?${e.toString()}`:t;return this.request(n,{method:"GET",headers:r})}async post(t,e,r){return this.request(t,{method:"POST",body:e,headers:r})}async put(t,e,r){return this.request(t,{method:"PUT",body:e,headers:r})}async delete(t,e){return this.request(t,{method:"DELETE",headers:e})}async upload(t,e,r){let n=this.buildUrl(t),s=await this.getAuthToken(),i={...r,...s?{token:s}:{}},a=new AbortController,l=setTimeout(()=>a.abort(),6e4),y={method:"POST",headers:i,body:e,signal:a.signal};this.config.debug&&console.error("[API UPLOAD]",n);try{let m=await fetch(n,y);if(!m.ok){if(m.status===401)throw this.authStorage&&(this.cachedToken=null,await this.authStorage.clearCredentials().catch(()=>{})),new I("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");let _=await m.text();throw new P(_||`${m.status} ${m.statusText}`,m.status)}let b=await m.json();if(this.config.debug&&console.error("[API Response]",b),!b.success||b.status!==0)throw new P(b.msg||"\u672A\u77E5\u9519\u8BEF",b.status,b);return b.data}catch(m){throw m instanceof DOMException&&m.name==="AbortError"?new P("\u4E0A\u4F20\u8D85\u65F6 (60000ms)",408):m}finally{clearTimeout(l)}}},mt=new ut,uo=new ut({auth:!1});var mo=uo;async function go(){return mo.post("app/qrcode/generate")}async function po(o){let t=new URLSearchParams;t.append("qrToken",o);let e=`app/qrcode/status?${t.toString()}`,r=await mo.requestFull(e,{method:"GET"});return r.token&&typeof r.data=="object"&&r.data!==null&&(r.data.token=r.token),r.data}async function wo(o,t,e){let{UserInfoCard:r}=await Promise.resolve().then(()=>(ho(),fo)),{renderComponent:n}=await Promise.resolve().then(()=>(et(),gt)),s=t!=null?{userInfo:o,lastLogin:t,daysSinceLogin:e??0}:{userInfo:o};n(r,s)}var pt=class{storage;constructor(t){this.storage=t??ot()}async generateQR(){let t=await go(),e=`https://m.puresnake.com/r2/auth/login?qrToken=${t.qrContent}&from=wechat`,r=await Nt(e);return{qrData:t,...r}}async waitForLogin(t,e,r,n,s,i){let a=await F(()=>po(t),{interval:r,timeout:e,condition:l=>{switch(l.status){case"scanned":return i||(console.log(w.cyan(`
11
+ \u{1F50D} \u5DF2\u626B\u7801: ${l.userInfo?.nickname||"\u672A\u77E5\u7528\u6237"}`)),console.log(w.yellow("\u8BF7\u5728 APP \u4E0A\u786E\u8BA4\u767B\u5F55"))),s?.("scanning"),!1;case"confirmed":return i||console.log(w.green(`
12
+ \u2705 \u7528\u6237\u5DF2\u786E\u8BA4\u767B\u5F55`)),s?.("success"),!0;case"expired":return i||console.log(w.red(`
13
+ \u23F0 \u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F`)),s?.("expired"),!0;case"canceled":return i||console.log(w.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 I("\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55"):a.status==="canceled"?new I("\u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55"):new I("\u767B\u5F55\u5931\u8D25: \u672A\u83B7\u53D6\u5230\u51ED\u8BC1")}async login(t){console.log(w.cyan(`
15
+ \u{1F510} \u6B63\u5728\u542F\u52A8\u626B\u7801\u767B\u5F55...`));let{qrData:e,qrUrl:r,setStatus:n,closeServer:s}=await this.generateQR();console.log(w.green(`\u2705 \u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
16
+ `)),console.log(w.cyan(` \u94FE\u63A5: ${r}
17
+ `)),B(r),console.log(w.yellow(`\u23F3 \u7B49\u5F85\u626B\u7801...
18
+ `));let i=Number.parseInt(e.expireTime,10),a=Number.parseInt(e.pollInterval,10);try{let l=await this.waitForLogin(e.qrToken,i,a,t,n);return console.log(w.green(`
19
19
  \u2705 \u767B\u5F55\u6210\u529F\uFF01
20
- `)),xo(l.userInfo),l}catch(l){throw console.log(x.red(`
20
+ `)),wo(l.userInfo),l}catch(l){throw console.log(w.red(`
21
21
  \u274C \u767B\u5F55\u5931\u8D25
22
- `)),l}finally{s()}}async logout(){console.log(x.cyan(`
23
- \u{1F6AA} \u6B63\u5728\u9000\u51FA\u767B\u5F55...`)),await this.storage.clearCredentials(),console.log(x.green(`\u2705 \u5DF2\u9000\u51FA\u767B\u5F55
24
- `))}async status(){if(!await this.storage.isLoggedIn()){console.log(x.yellow(`\u26A0\uFE0F \u5C1A\u672A\u767B\u5F55\u6216\u51ED\u8BC1\u5DF2\u8FC7\u671F
25
- `));return}let e=await this.storage.getCredentials(),r=e.userInfo,n=new Date(e.timestamp),s=Math.floor((Date.now()-e.timestamp)/(1e3*60*60*24));console.log(x.green(`\u2705 \u5DF2\u767B\u5F55
26
- `)),await xo(r,n,s)}},Gt=null;function R(){return Gt||(Gt=new ft),Gt}import q from"chalk";var Io=gt;async function So(){return Io.get("mms/xianyu/auth/url")}async function Co(o){let t=new URLSearchParams({state:o});return Io.get("mms/xianyu/auth/status",t)}async function ht(){let o=await So(),t=await Lt(o.url,o.url);return{authData:o,...t}}async function nt(o,t,e,r,n){return F(()=>Co(o),{interval:e,timeout:t,condition:s=>s.status==="success"?(console.log(q.green(`
27
- \u2705 \u6388\u6743\u6210\u529F\uFF01\u5E97\u94FA: ${s.shopName} (${s.shopId})`)),n?.("success"),!0):s.status==="expired"?(console.log(q.red(`
28
- \u23F0 \u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F`)),n?.("expired"),!0):!1},r)}async function Jt(o){console.log(q.cyan(`
29
- \u{1F517} \u6B63\u5728\u83B7\u53D6\u95F2\u9C7C\u6388\u6743\u5730\u5740...`));let{authData:t,qrUrl:e,setStatus:r,closeServer:n}=await ht();console.log(q.green(`\u2705 \u6388\u6743\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
30
- `)),console.log(q.cyan(` \u94FE\u63A5: ${e}`)),console.log(q.gray(` \u6216\u590D\u5236\u94FE\u63A5\u6253\u5F00: ${t.url}`)),B(e),console.log(q.yellow(`
22
+ `)),l}finally{s()}}async logout(){console.log(w.cyan(`
23
+ \u{1F6AA} \u6B63\u5728\u9000\u51FA\u767B\u5F55...`)),await this.storage.clearCredentials(),console.log(w.green(`\u2705 \u5DF2\u9000\u51FA\u767B\u5F55
24
+ `))}async status(){if(!await this.storage.isLoggedIn()){console.log(w.yellow(`\u26A0\uFE0F \u5C1A\u672A\u767B\u5F55\u6216\u51ED\u8BC1\u5DF2\u8FC7\u671F
25
+ `));return}let e=await this.storage.getCredentials(),r=e.userInfo,n=new Date(e.timestamp),s=Math.floor((Date.now()-e.timestamp)/(1e3*60*60*24));console.log(w.green(`\u2705 \u5DF2\u767B\u5F55
26
+ `)),await wo(r,n,s)}},Bt=null;function R(){return Bt||(Bt=new pt),Bt}import J from"chalk";var xo=mt;async function Io(){return xo.get("mms/xianyu/auth/url")}async function So(o){let t=new URLSearchParams({state:o});return xo.get("mms/xianyu/auth/status",t)}async function ft(){let o=await Io(),t=await Rt(o.url,o.url);return{authData:o,...t}}async function rt(o,t,e,r,n){return F(()=>So(o),{interval:e,timeout:t,condition:s=>s.status==="success"?(console.log(J.green(`
27
+ \u2705 \u6388\u6743\u6210\u529F\uFF01\u5E97\u94FA: ${s.shopName} (${s.shopId})`)),n?.("success"),!0):s.status==="expired"?(console.log(J.red(`
28
+ \u23F0 \u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F`)),n?.("expired"),!0):!1},r)}async function Gt(o){console.log(J.cyan(`
29
+ \u{1F517} \u6B63\u5728\u83B7\u53D6\u95F2\u9C7C\u6388\u6743\u5730\u5740...`));let{authData:t,qrUrl:e,setStatus:r,closeServer:n}=await ft();console.log(J.green(`\u2705 \u6388\u6743\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
30
+ `)),console.log(J.cyan(` \u94FE\u63A5: ${e}`)),console.log(J.gray(` \u6216\u590D\u5236\u94FE\u63A5\u6253\u5F00: ${t.url}`)),B(e),console.log(J.yellow(`
31
31
  \u23F3 \u7B49\u5F85\u6388\u6743...
32
- `));let s=t.expireTime?Number.parseInt(t.expireTime,10):3e5,i=t.pollInterval?Number.parseInt(t.pollInterval,10):1e3;try{let a=await nt(t.state,s,i,o,r);if(a.status==="success")return a;throw new S("\u95F2\u9C7C\u6388\u6743\u5931\u8D25: "+(a.status==="expired"?"\u94FE\u63A5\u5DF2\u8FC7\u671F":"\u672A\u77E5\u72B6\u6001"))}finally{n()}}import j from"chalk";function v(o){if(o instanceof S)console.error(j.red(`
33
- \u25B2 ${o.message}`)),console.error(j.gray(`\u2192 \u8BF7\u5148\u8FD0\u884C: r2-cli auth login
34
- `));else if(o instanceof A)console.error(j.red(`\u25B2 \u64CD\u4F5C\u5931\u8D25: ${o.message}`)),o.status&&console.error(j.gray(` \u72B6\u6001\u7801: ${o.status}`));else if(o instanceof $)console.error(j.red(`\u25B2 \u914D\u7F6E\u6587\u4EF6\u5F02\u5E38: ${o.message}`)),o.path&&console.error(j.gray(` \u8DEF\u5F84: ${o.path}`)),console.error(j.gray(`\u2192 \u8BF7\u5C1D\u8BD5\u91CD\u65B0\u767B\u5F55: r2-cli auth login
35
- `));else{let t=o instanceof Error?o.message:String(o);console.error(j.red(`\u25B2 ${t}`))}process.exit(1)}function qt(o){console.log(JSON.stringify({success:!1,error:o})),process.exit(1)}function g(o){return async t=>{try{await o(t)}catch(e){if(t.json){let r=e instanceof Error?e.message:String(e),n=e instanceof A?e.status:void 0;console.log(JSON.stringify({success:!1,error:r,...n!=null&&{status:n}})),process.exit(1)}v(e)}}}function yt(o){return async(...t)=>{try{await o(...t)}catch(e){let r=e instanceof Error?e.message:String(e);qt(r)}}}var je=new Set(["accessToken","refreshExpireIn"]);function To(o){return o.map(t=>{let e={};for(let[r,n]of Object.entries(t))je.has(r)||(e[r]=n);return e})}async function wt(o){let{qrInfo:t,qrUrl:e,setStatus:r,closeServer:n,waitArgs:s}=await o.generate();console.log(JSON.stringify(t,null,2)),B(e);try{let i=await o.waitResult(s,r);console.log(JSON.stringify(o.formatSuccess(i)))}catch(i){let a=i instanceof Error?i.message:String(i);console.log(JSON.stringify({success:!1,error:a})),process.exit(1)}finally{setTimeout(n,1e3)}}function Xt(){let o=new bo("login");o.description("\u626B\u7801\u767B\u5F55 Round2AI \u8D26\u6237").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new bo("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(yt(async e=>{let n=await R().waitForLogin(e.token,Number.parseInt(e.expire,10),Number.parseInt(e.interval,10));console.log(JSON.stringify({success:!0,...n}))}));return o.addCommand(t),o.action(async e=>{try{e.json?await wt({generate:async()=>{let r=R(),{qrData:n,qrUrl:s,setStatus:i,closeServer:a}=await r.generateQR(),l=Number.parseInt(n.expireTime,10),w=Number.parseInt(n.pollInterval,10);return{qrInfo:{qrToken:n.qrToken,expireTimeMs:l,pollIntervalMs:w,url:`https://m.puresnake.com/r2/auth/login?qrToken=${n.qrContent}&from=wechat`,qrUrl:s},qrUrl:s,setStatus:i,closeServer:a,waitArgs:{qrToken:n.qrToken,expireMs:l,intervalMs:w}}},waitResult:({qrToken:r,expireMs:n,intervalMs:s},i)=>R().waitForLogin(r,n,s,void 0,i,!0),formatSuccess:r=>({success:!0,userInfo:r.userInfo})}):await R().login()}catch(r){if(e.json){let n=r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:n})),process.exit(1)}v(r)}}),o}import{Command as Ee}from"commander";function _t(){let o=new Ee("logout");return o.description("\u9000\u51FA\u767B\u5F55"),o.action(async()=>{try{await R().logout()}catch(t){v(t)}}),o}import{Command as $e}from"commander";function Qt(){let o=new $e("status");return o.description("\u67E5\u770B\u767B\u5F55\u72B6\u6001"),o.action(async()=>{try{await R().status()}catch(t){v(t)}}),o}import{Command as Po}from"commander";function Mt(){let o=new Po("xianyu");o.description("\u95F2\u9C7C\u5E97\u94FA\u6388\u6743").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new Po("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(yt(async e=>{let r=await nt(e.state,Number.parseInt(e.expire,10),Number.parseInt(e.interval,10));r.status==="success"?console.log(JSON.stringify({success:!0,shopId:r.shopId,shopName:r.shopName})):qt(`\u6388\u6743\u72B6\u6001: ${r.status}`)}));return o.addCommand(t),o.action(async e=>{try{e.json?await wt({generate:async()=>{let{authData:r,qrUrl:n,setStatus:s,closeServer:i}=await ht(),a=r.expireTime?Number.parseInt(r.expireTime,10):3e5,l=r.pollInterval?Number.parseInt(r.pollInterval,10):1e3;return{qrInfo:{state:r.state,expireTimeMs:a,pollIntervalMs:l,qrUrl:n},qrUrl:n,setStatus:s,closeServer:i,waitArgs:{state:r.state,expireMs:a,intervalMs:l}}},waitResult:async({state:r,expireMs:n,intervalMs:s},i)=>{let a=await nt(r,n,s,void 0,i);if(a.status!=="success")throw new Error(`\u6388\u6743\u72B6\u6001: ${a.status}`);return a},formatSuccess:r=>({success:!0,shopId:r.shopId,shopName:r.shopName})}):await Jt()}catch(r){if(e.json){let n=r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:n})),process.exit(1)}v(r)}}),o}import{Command as gr}from"commander";import{Command as Je}from"commander";import L from"chalk";import{select as zt,input as qe,confirm as Xe}from"@inquirer/prompts";import{readFileSync as Be}from"node:fs";import{basename as Ge}from"node:path";function X(o){let t=new URLSearchParams;for(let[e,r]of Object.entries(o))r!=null&&r!==""&&t.append(e,String(r));return t}var C=gt;async function Ft(o){return C.post("mms/goods/listing/up/xianyu",o)}async function Ao(o){return C.get("mms/goods/listing/get",X({...o}))}async function ko(o){return C.post("mms/goods/listing/down/xianyu",o)}async function vo(o){return C.post("mms/goods/listing/update/xyPrice",o)}async function No(o){return C.post("mms/goods/listing/update/goodsInfo",o)}async function Ro(o){return C.get("mms/goods/listing/list",o?X({...o}):void 0)}async function xt(){return await C.get("mms/user/shop/list")??[]}async function It(){return await C.get("mms/user/stock/list")??[]}async function St(o){let t=o?X({...o}):void 0;return C.get("mms/seller/goods/select/list",t)}async function Lo(o,t){let e=[];for(let r of t){let n=Be(r),s=Ge(r),i=new FormData;i.append("file",new Blob([n]),s);let a=await C.upload(`platform/xy/media/upload?shopId=${encodeURIComponent(o)}`,i);e.push(a)}return e}async function Oo(o){return C.post("mms/goods/listing/hang/up/xianyu",o)}async function Do(o=16){return await C.get("platform/xy/cat",X({spBizType:o}))??[]}async function Uo(o){return await C.get("platform/xy/props",X({channelCatId:o}))??[]}async function jo(o,t,e){return await C.get("platform/xy/props/value",X({channelCatId:o,propId:t,key:e}))??[]}var _e=2e3,Qe=1e4;function Me(o){let t=o.status?.toLowerCase()??"";return t===""||t==="init"||t==="pending"||t==="processing"}async function Eo(o,t,e,r){r||process.stdout.write(L.cyan("\u23F3 \u6B63\u5728\u67E5\u8BE2\u4E0A\u67B6\u8FDB\u5EA6..."));let n=await F(()=>Ao({stockGoodsId:o,shopId:t,platform:e}),{interval:_e,timeout:Qe,condition:s=>!Me(s)});return r||process.stdout.write("\r"+" ".repeat(30)+"\r"),n}function $o(){let o=new Je("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(g(async t=>{if(t.json&&!(t.stockGoodsId&&t.shopId&&t.price)&&(console.log(JSON.stringify({success:!1,error:"Agent \u6A21\u5F0F\u9700\u8981 --stock-goods-id, --shop-id, --price"})),process.exit(1)),t.stockGoodsId&&t.shopId&&t.price){let d=Number(t.stockGoodsId),k=t.shopId,At=Number(t.price),Q=t.platform,de=await Ft({stockGoodsId:d,shopId:k,price:At,platform:Q}),kt=await Eo(d,k,Q,t.json);if(t.json)console.log(JSON.stringify({success:!0,data:{submit:de,listing:kt}},null,2));else{let ue=kt.status?.toLowerCase()!=="failed";console.log(ue?L.green("\u2713 \u4E0A\u67B6\u6210\u529F"):L.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(kt,null,2))}return}let e=await xt();if(e.length===0){console.log(L.yellow("\u6CA1\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF0C\u8BF7\u5148\u8FD0\u884C r2-cli auth xianyu \u6388\u6743"));return}let r=await zt({message:"\u9009\u62E9\u5E97\u94FA",choices:e.map(d=>({name:`${d.shopName} (${d.platform})`,value:d.shopId}))}),n=await It();if(n.length===0){console.log(L.yellow("\u6CA1\u6709\u53EF\u7528\u7684\u4ED3\u5E93"));return}let s=await zt({message:"\u9009\u62E9\u4ED3\u5E93",choices:n.map(d=>({name:d.stockName,value:d.stockId}))}),i=await St({stockId:s,size:100});if(!i.items?.length){console.log(L.yellow("\u8BE5\u4ED3\u5E93\u6CA1\u6709\u53EF\u9009\u7684\u5546\u54C1"));return}let a=await zt({message:"\u9009\u62E9\u5546\u54C1",choices:i.items.map(d=>({name:`${d.goodsName} ${d.size?`| ${d.size}`:""} | \xA5${d.salePrice}`,value:d.stockGoodsId}))}),l=await qe({message:"\u8F93\u5165\u4E0A\u67B6\u4EF7\u683C",default:i.items.find(d=>d.stockGoodsId===a)?.salePrice?.toString()??"",validate:d=>Number(d)>0?!0:"\u4EF7\u683C\u5FC5\u987B\u4E3A\u6B63\u6570"});if(!await Xe({message:`\u786E\u8BA4\u4E0A\u67B6\uFF1F\u4EF7\u683C \xA5${l}`,default:!0})){console.log(L.gray("\u5DF2\u53D6\u6D88"));return}let m=Number(a);await Ft({stockGoodsId:m,shopId:r,price:Number(l),platform:"xianyu"}),console.log(L.green("\u2713 \u4E0A\u67B6\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u67E5\u8BE2\u8FDB\u5EA6..."));let P=await Eo(m,r,"xianyu"),_=P.status?.toLowerCase()!=="failed";console.log(_?L.green("\u2713 \u4E0A\u67B6\u6210\u529F"):L.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(P,null,2))})),o}import{Command as Ve}from"commander";import qo from"chalk";function Xo(){let o=new Ve("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(g(async t=>{let e=await xt();if(t.json){console.log(JSON.stringify(To(e),null,2));return}if(!e.length){console.log(qo.yellow("\u672A\u627E\u5230\u5DF2\u6388\u6743\u7684\u5E97\u94FA")),console.log(qo.gray(" \u63D0\u793A: \u8BF7\u5148\u5728\u7B2C\u4E8C\u56DE\u5408 APP \u4E2D\u6388\u6743\u5E97\u94FA"));return}let{ShopsTable:r}=await Promise.resolve().then(()=>(Jo(),Go)),{renderComponent:n}=await Promise.resolve().then(()=>(rt(),pt));n(r,{shops:e,platform:"all"})})),o}import{Command as tr}from"commander";import or from"chalk";function Mo(){let o=new tr("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(g(async t=>{let e=await It();if(t.json){console.log(JSON.stringify(e,null,2));return}if(!e.length){console.log(or.yellow("\u672A\u627E\u5230\u4ED3\u5E93\u4FE1\u606F"));return}let{StocksTable:r}=await Promise.resolve().then(()=>(Qo(),_o)),{renderComponent:n}=await Promise.resolve().then(()=>(rt(),pt));n(r,{stocks:e})})),o}import{Command as er}from"commander";import Z from"chalk";function Fo(){let o=new er("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("--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"),o.action(g(async t=>{let r=await St({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(Z.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(Z.cyan(`
32
+ `));let s=t.expireTime?Number.parseInt(t.expireTime,10):3e5,i=t.pollInterval?Number.parseInt(t.pollInterval,10):1e3;try{let a=await rt(t.state,s,i,o,r);if(a.status==="success")return a;throw new I("\u95F2\u9C7C\u6388\u6743\u5931\u8D25: "+(a.status==="expired"?"\u94FE\u63A5\u5DF2\u8FC7\u671F":"\u672A\u77E5\u72B6\u6001"))}finally{n()}}import E from"chalk";function v(o){if(o instanceof I)console.error(E.red(`
33
+ \u25B2 ${o.message}`)),console.error(E.gray(`\u2192 \u8BF7\u5148\u8FD0\u884C: r2-cli auth login
34
+ `));else if(o instanceof P)console.error(E.red(`\u25B2 \u64CD\u4F5C\u5931\u8D25: ${o.message}`)),o.status&&console.error(E.gray(` \u72B6\u6001\u7801: ${o.status}`));else if(o instanceof $)console.error(E.red(`\u25B2 \u914D\u7F6E\u6587\u4EF6\u5F02\u5E38: ${o.message}`)),o.path&&console.error(E.gray(` \u8DEF\u5F84: ${o.path}`)),console.error(E.gray(`\u2192 \u8BF7\u5C1D\u8BD5\u91CD\u65B0\u767B\u5F55: r2-cli auth login
35
+ `));else{let t=o instanceof Error?o.message:String(o);console.error(E.red(`\u25B2 ${t}`))}process.exit(1)}function qt(o){console.log(JSON.stringify({success:!1,error:o})),process.exit(1)}function p(o){return async t=>{try{await o(t)}catch(e){if(t.json){let r=e instanceof Error?e.message:String(e),n=e instanceof P?e.status:void 0;console.log(JSON.stringify({success:!1,error:r,...n!=null&&{status:n}})),process.exit(1)}v(e)}}}function ht(o){return async(...t)=>{try{await o(...t)}catch(e){let r=e instanceof Error?e.message:String(e);qt(r)}}}var Le=new Set(["accessToken","refreshExpireIn"]);function Co(o){return o.map(t=>{let e={};for(let[r,n]of Object.entries(t))Le.has(r)||(e[r]=n);return e})}async function yt(o){let{qrInfo:t,qrUrl:e,setStatus:r,closeServer:n,waitArgs:s}=await o.generate();console.log(JSON.stringify(t,null,2)),B(e);try{let i=await o.waitResult(s,r);console.log(JSON.stringify(o.formatSuccess(i)))}catch(i){let a=i instanceof Error?i.message:String(i);console.log(JSON.stringify({success:!1,error:a})),process.exit(1)}finally{setTimeout(n,1e3)}}function Jt(){let o=new To("login");o.description("\u626B\u7801\u767B\u5F55 Round2AI \u8D26\u6237").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new To("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(ht(async e=>{let n=await R().waitForLogin(e.token,Number.parseInt(e.expire,10),Number.parseInt(e.interval,10));console.log(JSON.stringify({success:!0,...n}))}));return o.addCommand(t),o.action(async e=>{try{e.json?await yt({generate:async()=>{let r=R(),{qrData:n,qrUrl:s,setStatus:i,closeServer:a}=await r.generateQR(),l=Number.parseInt(n.expireTime,10),y=Number.parseInt(n.pollInterval,10);return{qrInfo:{qrToken:n.qrToken,expireTimeMs:l,pollIntervalMs:y,url:`https://m.puresnake.com/r2/auth/login?qrToken=${n.qrContent}&from=wechat`,qrUrl:s},qrUrl:s,setStatus:i,closeServer:a,waitArgs:{qrToken:n.qrToken,expireMs:l,intervalMs:y}}},waitResult:({qrToken:r,expireMs:n,intervalMs:s},i)=>R().waitForLogin(r,n,s,void 0,i,!0),formatSuccess:r=>({success:!0,userInfo:r.userInfo})}):await R().login()}catch(r){if(e.json){let n=r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:n})),process.exit(1)}v(r)}}),o}import{Command as Oe}from"commander";function Xt(){let o=new Oe("logout");return o.description("\u9000\u51FA\u767B\u5F55"),o.action(async()=>{try{await R().logout()}catch(t){v(t)}}),o}import{Command as De}from"commander";function _t(){let o=new De("status");return o.description("\u67E5\u770B\u767B\u5F55\u72B6\u6001"),o.action(async()=>{try{await R().status()}catch(t){v(t)}}),o}import{Command as bo}from"commander";function Qt(){let o=new bo("xianyu");o.description("\u95F2\u9C7C\u5E97\u94FA\u6388\u6743").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new bo("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(ht(async e=>{let r=await rt(e.state,Number.parseInt(e.expire,10),Number.parseInt(e.interval,10));r.status==="success"?console.log(JSON.stringify({success:!0,shopId:r.shopId,shopName:r.shopName})):qt(`\u6388\u6743\u72B6\u6001: ${r.status}`)}));return o.addCommand(t),o.action(async e=>{try{e.json?await yt({generate:async()=>{let{authData:r,qrUrl:n,setStatus:s,closeServer:i}=await ft(),a=r.expireTime?Number.parseInt(r.expireTime,10):3e5,l=r.pollInterval?Number.parseInt(r.pollInterval,10):1e3;return{qrInfo:{state:r.state,expireTimeMs:a,pollIntervalMs:l,qrUrl:n},qrUrl:n,setStatus:s,closeServer:i,waitArgs:{state:r.state,expireMs:a,intervalMs:l}}},waitResult:async({state:r,expireMs:n,intervalMs:s},i)=>{let a=await rt(r,n,s,void 0,i);if(a.status!=="success")throw new Error(`\u6388\u6743\u72B6\u6001: ${a.status}`);return a},formatSuccess:r=>({success:!0,shopId:r.shopId,shopName:r.shopName})}):await Gt()}catch(r){if(e.json){let n=r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:n})),process.exit(1)}v(r)}}),o}import{Command as ir}from"commander";import{Command as Ue}from"commander";import L from"chalk";import{select as Ft,input as Ee,confirm as je}from"@inquirer/prompts";function X(o){let t=new URLSearchParams;for(let[e,r]of Object.entries(o))r!=null&&r!==""&&t.append(e,String(r));return t}var A=mt;async function Mt(o){return A.post("mms/goods/listing/up/xianyu",o)}async function Po(o){return A.get("mms/goods/listing/get",X({...o}))}async function Ao(o){return A.post("mms/goods/listing/down/xianyu",o)}async function ko(o){return A.post("mms/goods/listing/update/xyPrice",o)}async function vo(o){return A.get("mms/goods/listing/list",o?X({...o}):void 0)}async function wt(){return await A.get("mms/user/shop/list")??[]}async function xt(){return await A.get("mms/user/stock/list")??[]}async function It(o){let t=o?X({...o}):void 0;return A.get("mms/seller/goods/select/list",t)}async function No(o){return A.post("mms/goods/listing/hang/up/xianyu",o)}async function Ro(o=16){return await A.get("platform/xy/cat",X({spBizType:o}))??[]}async function Lo(o){return await A.get("platform/xy/props",X({channelCatId:o}))??[]}async function Oo(o,t,e){return await A.get("platform/xy/props/value",X({channelCatId:o,propId:t,key:e}))??[]}var $e=2e3,Be=1e4;function Ge(o){let t=o.status?.toLowerCase()??"";return t===""||t==="init"||t==="pending"||t==="processing"}async function Do(o,t,e,r){r||process.stdout.write(L.cyan("\u23F3 \u6B63\u5728\u67E5\u8BE2\u4E0A\u67B6\u8FDB\u5EA6..."));let n=await F(()=>Po({stockGoodsId:o,shopId:t,platform:e}),{interval:$e,timeout:Be,condition:s=>!Ge(s)});return r||process.stdout.write("\r"+" ".repeat(30)+"\r"),n}function Uo(){let o=new Ue("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(p(async t=>{if(t.json&&!(t.stockGoodsId&&t.shopId&&t.price)&&(console.log(JSON.stringify({success:!1,error:"Agent \u6A21\u5F0F\u9700\u8981 --stock-goods-id, --shop-id, --price"})),process.exit(1)),t.stockGoodsId&&t.shopId&&t.price){let d=Number(t.stockGoodsId),k=t.shopId,Pt=Number(t.price),Q=t.platform,ie=await Mt({stockGoodsId:d,shopId:k,price:Pt,platform:Q}),At=await Do(d,k,Q,t.json);if(t.json)console.log(JSON.stringify({success:!0,data:{submit:ie,listing:At}},null,2));else{let ae=At.status?.toLowerCase()!=="failed";console.log(ae?L.green("\u2713 \u4E0A\u67B6\u6210\u529F"):L.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(At,null,2))}return}let e=await wt();if(e.length===0){console.log(L.yellow("\u6CA1\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF0C\u8BF7\u5148\u8FD0\u884C r2-cli auth xianyu \u6388\u6743"));return}let r=await Ft({message:"\u9009\u62E9\u5E97\u94FA",choices:e.map(d=>({name:`${d.shopName} (${d.platform})`,value:d.shopId}))}),n=await xt();if(n.length===0){console.log(L.yellow("\u6CA1\u6709\u53EF\u7528\u7684\u4ED3\u5E93"));return}let s=await Ft({message:"\u9009\u62E9\u4ED3\u5E93",choices:n.map(d=>({name:d.stockName,value:d.stockId}))}),i=await It({stockId:s,size:100});if(!i.items?.length){console.log(L.yellow("\u8BE5\u4ED3\u5E93\u6CA1\u6709\u53EF\u9009\u7684\u5546\u54C1"));return}let a=await Ft({message:"\u9009\u62E9\u5546\u54C1",choices:i.items.map(d=>({name:`${d.goodsName} ${d.size?`| ${d.size}`:""} | \xA5${d.salePrice}`,value:d.stockGoodsId}))}),l=await Ee({message:"\u8F93\u5165\u4E0A\u67B6\u4EF7\u683C",default:i.items.find(d=>d.stockGoodsId===a)?.salePrice?.toString()??"",validate:d=>Number(d)>0?!0:"\u4EF7\u683C\u5FC5\u987B\u4E3A\u6B63\u6570"});if(!await je({message:`\u786E\u8BA4\u4E0A\u67B6\uFF1F\u4EF7\u683C \xA5${l}`,default:!0})){console.log(L.gray("\u5DF2\u53D6\u6D88"));return}let m=Number(a);await Mt({stockGoodsId:m,shopId:r,price:Number(l),platform:"xianyu"}),console.log(L.green("\u2713 \u4E0A\u67B6\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u67E5\u8BE2\u8FDB\u5EA6..."));let b=await Do(m,r,"xianyu"),_=b.status?.toLowerCase()!=="failed";console.log(_?L.green("\u2713 \u4E0A\u67B6\u6210\u529F"):L.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(b,null,2))})),o}import{Command as Qe}from"commander";import Bo from"chalk";function Go(){let o=new Qe("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(p(async t=>{let e=await wt();if(t.json){console.log(JSON.stringify(Co(e),null,2));return}if(!e.length){console.log(Bo.yellow("\u672A\u627E\u5230\u5DF2\u6388\u6743\u7684\u5E97\u94FA")),console.log(Bo.gray(" \u63D0\u793A: \u8BF7\u5148\u5728\u7B2C\u4E8C\u56DE\u5408 APP \u4E2D\u6388\u6743\u5E97\u94FA"));return}let{ShopsTable:r}=await Promise.resolve().then(()=>($o(),jo)),{renderComponent:n}=await Promise.resolve().then(()=>(et(),gt));n(r,{shops:e,platform:"all"})})),o}import{Command as We}from"commander";import He from"chalk";function Xo(){let o=new We("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(p(async t=>{let e=await xt();if(t.json){console.log(JSON.stringify(e,null,2));return}if(!e.length){console.log(He.yellow("\u672A\u627E\u5230\u4ED3\u5E93\u4FE1\u606F"));return}let{StocksTable:r}=await Promise.resolve().then(()=>(Jo(),qo)),{renderComponent:n}=await Promise.resolve().then(()=>(et(),gt));n(r,{stocks:e})})),o}import{Command as Ve}from"commander";import Z from"chalk";function _o(){let o=new Ve("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("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--page <n>","\u9875\u7801","1").option("--size <n>","\u6BCF\u9875\u6570\u91CF\uFF08\u6700\u5927 50\uFF09","20").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(p(async t=>{let r=await It({stockId:t.stockId||void 0,stockGoodsId:t.stockGoodsId||void 0,page:Number(t.page)||1,size:Math.min(Number(t.size)||20,50)})??{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(Z.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(Z.cyan(`
36
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(` ${Z.bold(n.goodsName)} ${n.size?Z.gray(`| ${n.size}`):""}`),console.log(` \u54C1\u724C: ${n.brand} \u5EFA\u8BAE\u552E\u4EF7: \xA5${n.salePrice} stockGoodsId: ${Z.green(n.stockGoodsId)}`),console.log(Z.gray(` \u5206\u7C7B: ${n.cate1Name} > ${n.cate2Name} > ${n.cate3Name}`)),console.log()})),o}import{Command as ar}from"commander";import cr from"chalk";rt();import{Box as p,Text as h}from"ink";import{jsx as c,jsxs as E}from"react/jsx-runtime";var rr={init:{label:"\u5F85\u4E0A\u67B6",color:"yellow"},up:{label:"\u5DF2\u4E0A\u67B6",color:"green"},down:{label:"\u5DF2\u4E0B\u67B6",color:"gray"},fail:{label:"\u5931\u8D25",color:"red"}},oo=4,eo=8,Ct=12,ro=10,no=6,so=8;function zo(o,t){return o.length>t?o.slice(0,t-1)+"\u2026":o}function Wo(o){if(!o)return"-";let t=new Date(o),e=r=>String(r).padStart(2,"0");return`${e(t.getMonth()+1)}/${e(t.getDate())} ${e(t.getHours())}:${e(t.getMinutes())}`}function nr({fillWidth:o}){return E(p,{flexDirection:"row",children:[c(p,{width:oo,children:c(h,{bold:!0,color:"white",children:"ID"})}),c(p,{width:eo,children:c(h,{bold:!0,color:"white",children:"\u72B6\u6001"})}),c(p,{width:Ct,children:c(h,{bold:!0,color:"white",children:"\u54C1\u724C"})}),c(p,{width:o,children:c(h,{bold:!0,color:"white",children:"\u5546\u54C1\u540D\u79F0"})}),c(p,{width:ro,children:c(h,{bold:!0,color:"white",children:"\u4EF7\u683C"})}),c(p,{width:no,children:c(h,{bold:!0,color:"white",children:"\u89C4\u683C"})}),c(p,{width:so,children:c(h,{bold:!0,color:"white",children:"\u5E93\u5B58ID"})})]})}function sr({item:o}){return c(p,{flexDirection:"column",children:c(h,{color:"gray",children:` shopId: ${o.shopId} thirdItemNo: ${o.thirdItemNo||"-"} outItemNo: ${o.outItemNo||"-"} \u8D27\u53F7: ${o.goodsNo||"-"} ${o.type||"-"} ${o.platform} \u521B\u5EFA: ${Wo(o.gmtCreate)} \u4FEE\u6539: ${Wo(o.gmtModified)}`})})}function ir({item:o,fillWidth:t}){let e=rr[o.status]??{label:o.status,color:"white"};return E(p,{flexDirection:"column",children:[E(p,{flexDirection:"row",children:[c(p,{width:oo,children:c(h,{color:"gray",children:o.id})}),c(p,{width:eo,children:c(h,{color:e.color,children:e.label})}),c(p,{width:Ct,children:c(h,{color:"cyan",children:zo(o.brandName||"-",Ct-1)})}),c(p,{width:t,children:c(h,{children:zo(o.goodsName,t-1)})}),c(p,{width:ro,children:E(h,{color:"yellow",children:["\xA5",o.price]})}),c(p,{width:no,children:c(h,{color:"gray",children:o.spec||"-"})}),c(p,{width:so,children:c(h,{color:"gray",children:o.stockGoodsId})})]}),c(sr,{item:o})]})}function Ho({items:o,total:t}){let e=process.stdout.columns||80,r=4,n=oo+eo+Ct+ro+no+so,s=Math.max(e-r-n,20),i=n+s;return E(p,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[E(p,{flexDirection:"row",children:[c(h,{bold:!0,color:"cyan",children:"\u4E0A\u67B6\u5217\u8868"}),E(h,{color:"gray",children:[" \xB7 \u5171 ",t," \u6761"]})]}),E(p,{flexDirection:"column",marginTop:1,children:[c(nr,{fillWidth:s}),c(h,{color:"gray",children:"\u2500".repeat(i)}),o.map(a=>c(ir,{item:a,fillWidth:s},a.id))]})]})}function Vo(){let o=new ar("listing");return o.description("\u67E5\u8BE2\u4E0A\u67B6\u5546\u54C1\u5217\u8868"),o.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/sold\uFF09").option("-p, --platform <platform>","\u5E73\u53F0","xianyu").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(g(async t=>{let r=await Ro({id:t.id,stockGoodsId:t.stockGoodsId?Number(t.stockGoodsId):void 0,shopId:t.shopId,stockId:t.stockId,status:t.status,platform:t.platform})??{items:[],total:0};if(t.json){r.items?.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.items?.length){console.log(cr.yellow("\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55"));return}Bt(Ho,{items:r.items,total:r.total})})),o}import{Command as lr}from"commander";import io from"chalk";function Ko(){let o=new lr("down");return o.description("\u4E0B\u67B6\u95F2\u9C7C\u5546\u54C1"),o.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"),o.action(g(async t=>{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(io.yellow("\u8BF7\u6307\u5B9A\u4E0B\u67B6\u6761\u4EF6\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let e={};t.id&&(e.id=t.id),t.stockGoodsId&&(e.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(e.shopId=t.shopId),t.json||console.log(io.cyan("\u{1F4E6} \u6B63\u5728\u4E0B\u67B6\u5546\u54C1..."));let r=await ko(e);t.json?console.log(JSON.stringify({success:!0,data:r},null,2)):(console.log(io.green("\u2705 \u4E0B\u67B6\u6210\u529F")),console.log(JSON.stringify(r,null,2)))})),o}import{Command as dr}from"commander";import Tt from"chalk";function Yo(){let o=new dr("price");return o.description("\u4FEE\u6539\u95F2\u9C7C\u4E0A\u67B6\u5546\u54C1\u4EF7\u683C"),o.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"),o.action(g(async t=>{if(!t.price){t.json&&(console.log(JSON.stringify({success:!1,error:"--price <amount> \u4E3A\u5FC5\u586B\u53C2\u6570"})),process.exit(1)),console.log(Tt.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(Tt.yellow("\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let e={price:Number(t.price)};t.id&&(e.id=t.id),t.stockGoodsId&&(e.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(e.shopId=t.shopId),t.json||console.log(Tt.cyan(`\u{1F4B0} \u6B63\u5728\u4FEE\u6539\u4EF7\u683C\u4E3A ${t.price}...`));let r=await vo(e);t.json?console.log(JSON.stringify({success:!0,data:r},null,2)):(console.log(Tt.green("\u2705 \u4EF7\u683C\u4FEE\u6539\u6210\u529F")),console.log(JSON.stringify(r,null,2)))})),o}import{Command as ur}from"commander";import st from"chalk";function Zo(){let o=new ur("edit");return o.description("\u4FEE\u6539\u5DF2\u4E0A\u67B6\u5546\u54C1\u4FE1\u606F\uFF08\u6807\u9898\u3001\u63CF\u8FF0\u3001\u54C1\u724C\u3001\u7C7B\u76EE\u3001\u56FE\u7247\u3001\u5C5E\u6027\u7B49\uFF09"),o.option("--id <id>","\u5546\u54C1\u4E0A\u67B6 ID\uFF08goodsListingId\uFF0C\u63A8\u8350\uFF09").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID\uFF08\u4E0E --account \u914D\u5408\uFF09").option("--account <shopId>","\u95F2\u9C7C\u7528\u6237\u540D/\u5E97\u94FA ID\uFF08\u4E0E --stock-goods-id \u914D\u5408\uFF09").option("--title <title>","\u5546\u54C1\u6807\u9898").option("--desc <desc>","\u5546\u54C1\u63CF\u8FF0").option("--category-id <id>","\u5546\u54C1\u7C7B\u76EE ID\uFF08\u5927\u5206\u7C7B\uFF0C\u540E\u7AEF\u5FC5\u586B\uFF09").option("--channel-cat-id <id>","\u6E20\u9053\u7C7B\u76EE ID\uFF08\u5C0F\u5206\u7C7B\uFF0C\u540E\u7AEF\u5FC5\u586B\uFF09").option("--image-ids <ids>","\u56FE\u7247 ID \u5217\u8868\uFF08\u9017\u53F7\u5206\u9694\uFF09").option("--item-attrs <json>","\u5546\u54C1\u5C5E\u6027\u5217\u8868\uFF08JSON \u5B57\u7B26\u4E32\uFF09").option("--brand-name <name>","\u54C1\u724C\u540D\u79F0").option("--stuff-status <status>","\u6210\u8272\u7B49\u7EA7\uFF1A100=\u5168\u65B0 -1=\u51C6\u65B0 99=99\u65B0 95=95\u65B0 90=9\u65B0").option("--goods-no <no>","\u8D27\u53F7").option("--original-price <price>","\u539F\u4EF7\uFF08\u5355\u4F4D\uFF1A\u5143\uFF09").option("--size <size>","\u5C3A\u7801").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(g(async t=>{if(!t.id&&!(t.stockGoodsId&&t.account)){t.json&&(console.log(JSON.stringify({success:!1,status:400,error:"\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <goodsListingId> \u6216 --stock-goods-id <id> --account <shopId>"})),process.exit(1)),console.log(st.yellow("\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <goodsListingId> \u6216 --stock-goods-id <id> --account <shopId>"));return}let e={};if(t.id&&(e.goodsListingId=Number(t.id)),t.stockGoodsId&&(e.stockGoodsId=Number(t.stockGoodsId)),t.account&&(e.account=t.account),t.title&&(e.title=t.title),t.desc&&(e.desc=t.desc),t.categoryId&&(e.categoryId=Number(t.categoryId)),t.channelCatId&&(e.channelCatId=t.channelCatId),t.imageIds&&(e.imageIdList=t.imageIds.split(",").map(s=>s.trim())),t.brandName&&(e.brandName=t.brandName),t.stuffStatus&&(e.stuffStatus=Number(t.stuffStatus)),t.goodsNo&&(e.goodsNo=t.goodsNo),t.originalPrice&&(e.originalPrice=Number(t.originalPrice)),t.size&&(e.size=t.size),t.itemAttrs)try{e.itemAttrList=JSON.parse(t.itemAttrs)}catch{t.json&&(console.log(JSON.stringify({success:!1,status:400,error:"--item-attrs JSON \u89E3\u6790\u5931\u8D25"})),process.exit(1)),console.log(st.yellow("--item-attrs JSON \u89E3\u6790\u5931\u8D25"));return}if(!Object.keys(e).some(s=>!["goodsListingId","stockGoodsId","account"].includes(s))){t.json&&(console.log(JSON.stringify({success:!1,status:400,error:"\u672A\u6307\u5B9A\u9700\u8981\u4FEE\u6539\u7684\u5B57\u6BB5"})),process.exit(1)),console.log(st.yellow("\u672A\u6307\u5B9A\u9700\u8981\u4FEE\u6539\u7684\u5B57\u6BB5"));return}t.json||console.log(st.cyan("\u6B63\u5728\u4FEE\u6539\u5546\u54C1\u4FE1\u606F..."));let n=await No(e);t.json?console.log(JSON.stringify({success:!0,data:n},null,2)):(console.log(st.green("\u2705 \u5546\u54C1\u4FE1\u606F\u4FEE\u6539\u6210\u529F")),console.log(JSON.stringify(n,null,2)))})),o}import{Command as tt}from"commander";import y from"chalk";var mr={100:"\u5168\u65B0",[-1]:"\u51C6\u65B0",99:"99\u65B0",95:"95\u65B0",90:"9\u65B0"};function te(){let o=new tt("hang-up");return o.description("\u95F2\u9C7C\u6302\u552E\u4E0A\u67B6\uFF08\u5B8C\u6574\u5546\u54C1\u4FE1\u606F\u6A21\u5F0F\uFF09"),o.addCommand(new tt("categories").description("\u83B7\u53D6\u95F2\u9C7C\u7C7B\u76EE\u5217\u8868\uFF08\u5927\u5206\u7C7B \u2192 \u5C0F\u5206\u7C7B\uFF09").option("--sp-biz-type <n>","\u4E1A\u52A1\u5206\u7C7B\uFF0C16=\u5962\u54C1","16").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(g(async t=>{let e=await Do(Number(t.spBizType));if(t.json){console.log(JSON.stringify(e,null,2));return}let r=new Map;for(let n of e){let s=String(n.catId);r.has(s)||r.set(s,{catName:n.catName,children:[]}),r.get(s).children.push({channel:n.channel,channelCatId:n.channelCatId})}for(let[n,s]of r){console.log(y.bold(`${s.catName} (catId: ${y.green(n)})`));for(let i of s.children)console.log(` ${i.channel} (channelCatId: ${y.green(i.channelCatId)})`)}}))),o.addCommand(new tt("props").description("\u83B7\u53D6\u6307\u5B9A\u7C7B\u76EE\u4E0B\u7684\u5C5E\u6027\u5217\u8868\uFF08\u542B\u53EF\u9009\u503C\uFF09").requiredOption("--channel-cat-id <id>","\u5C0F\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(g(async t=>{let e=await Uo(t.channelCatId);if(t.json){console.log(JSON.stringify(e,null,2));return}for(let r of e)if(console.log(y.bold(`
38
- ${r.propName} (propId: ${r.propId})`)),r.propsValues?.length)for(let n of r.propsValues)console.log(` ${n.valueName} (valueId: ${n.valueId})`);else console.log(y.gray(" \uFF08\u4F7F\u7528 brands \u5B50\u547D\u4EE4\u641C\u7D22\uFF09"))}))),o.addCommand(new tt("brands").description("\u641C\u7D22\u95F2\u9C7C\u54C1\u724C\uFF08\u6309\u5173\u952E\u5B57\u8FC7\u6EE4\uFF09").requiredOption("--channel-cat-id <id>","\u5C0F\u5206\u7C7B ID").requiredOption("--prop-id <id>","\u5C5E\u6027 ID\uFF08\u54C1\u724C\u5C5E\u6027\u7684 propId\uFF09").requiredOption("--key <keyword>","\u641C\u7D22\u5173\u952E\u5B57").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(g(async t=>{let e=await jo(t.channelCatId,t.propId,t.key);if(t.json){console.log(JSON.stringify(e,null,2));return}if(!e.length){console.log(y.yellow("\u672A\u627E\u5230\u5339\u914D\u7684\u54C1\u724C"));return}for(let r of e)console.log(` ${r.valueName} (valueId: ${r.valueId})`)}))),o.addCommand(new tt("upload-images").description("\u6279\u91CF\u4E0A\u4F20\u56FE\u7247\u5230\u95F2\u9C7C\uFF08\u6302\u552E\u524D\u5FC5\u987B\u5148\u4E0A\u4F20\u56FE\u7247\uFF09").requiredOption("--shop-id <id>","\u5E97\u94FA ID").requiredOption("--files <paths>","\u56FE\u7247\u6587\u4EF6\u8DEF\u5F84\uFF0C\u9017\u53F7\u5206\u9694").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(g(async t=>{let e=t.files.split(",").map(n=>n.trim()).filter(Boolean);if(e.length===0){t.json&&(console.log(JSON.stringify({success:!1,error:"\u8BF7\u63D0\u4F9B\u81F3\u5C11\u4E00\u5F20\u56FE\u7247"})),process.exit(1)),console.log(y.yellow("\u8BF7\u63D0\u4F9B\u81F3\u5C11\u4E00\u5F20\u56FE\u7247"));return}t.json||console.log(y.cyan(`\u6B63\u5728\u4E0A\u4F20 ${e.length} \u5F20\u56FE\u7247...`));let r=await Lo(t.shopId,e);if(t.json)console.log(JSON.stringify({success:!0,images:r},null,2));else{console.log(y.green(`\u4E0A\u4F20\u6210\u529F\uFF0C\u5171 ${r.length} \u5F20`));for(let n of r)console.log(` \u56FE\u7247ID: ${n.value}`)}}))),o.addCommand(new tt("submit").description("\u63D0\u4EA4\u6302\u552E\u4E0A\u67B6").requiredOption("--shop-id <id>","\u5E97\u94FA ID\uFF08\u5373\u95F2\u9C7C\u7528\u6237\u540D account\uFF09").requiredOption("--title <title>","\u5546\u54C1\u6807\u9898").requiredOption("--price <amount>","\u552E\u4EF7").requiredOption("--category-id <id>","\u5927\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").requiredOption("--channel-cat-id <id>","\u5C0F\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").requiredOption("--image-ids <ids>","\u56FE\u7247 ID \u5217\u8868\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u5148\u901A\u8FC7 upload-images \u83B7\u53D6\uFF09").requiredOption("--stuff-status <n>","\u6210\u8272\uFF1A100 \u5168\u65B0 / -1 \u51C6\u65B0 / 99 99\u65B0 / 95 95\u65B0 / 90 9\u65B0").option("--item-attrs <json>",'\u5546\u54C1\u5C5E\u6027\u5217\u8868 JSON\uFF0C\u683C\u5F0F: [{"propId":"x","valueId":"y","valueName":"z"}]').option("--brand-name <name>","\u54C1\u724C\u540D\u79F0").option("--desc <desc>","\u5546\u54C1\u63CF\u8FF0").option("--size <size>","\u5C3A\u7801").option("--goods-no <no>","\u8D27\u53F7").option("--original-price <amount>","\u539F\u4EF7").option("--trade-type <n>","\u4EA4\u6613\u65B9\u5F0F\uFF1A0 \u4EC5\u5728\u7EBF / 1 \u4EC5\u7EBF\u4E0B / 2 \u7EBF\u4E0A\u6216\u7EBF\u4E0B","0").option("--transport-fee <amount>","\u8FD0\u8D39\uFF08\u9ED8\u8BA4 0 \u5305\u90AE\uFF09","0").option("--yhb","\u662F\u5426\u5F00\u542F\u9A8C\u8D27\u5B9D").requiredOption("--out-item-no <no>","\u5546\u5BB6\u7F16\u7801\uFF08\u540C\u5E97\u94FA\u552F\u4E00\uFF0C\u7528\u6237\u81EA\u5B9A\u4E49\uFF09").option("--division-id <id>","\u884C\u653F\u533A\u5212 ID\uFF08\u5E02\u7EA7 ID\uFF0C\u9ED8\u8BA4\u676D\u5DDE 330100\uFF09","330100").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(g(async t=>{let e=t.imageIds.split(",").map(s=>s.trim()),r={account:t.shopId,title:t.title,reservePrice:Number(t.price),categoryId:Number(t.categoryId),channelCatId:t.channelCatId,imageIdList:e,stuffStatus:Number(t.stuffStatus),itemBizType:2,spBizType:"16",tradeType:Number(t.tradeType)||0,transportFee:Number(t.transportFee)||0,yhb:t.yhb??!1,...t.brandName&&{brandName:t.brandName},...t.desc&&{desc:t.desc},...t.size&&{size:t.size},...t.goodsNo&&{goodsNo:t.goodsNo},...t.originalPrice&&{originalPrice:Number(t.originalPrice)},outItemNo:t.outItemNo,divisionId:Number(t.divisionId)||330100,apiAfterSalesDo:{supportFd10msPolicy:!1,supportFd24hsPolicy:!1,supportNfrPolicy:!1,supportSdrPolicy:!1,supportVnrPolicy:!1,supportGpaPolicy:!1,supportFd48hsPolicy:!1},...t.itemAttrs&&{itemAttrList:JSON.parse(t.itemAttrs)}};t.json||(console.log(y.cyan("\u6B63\u5728\u63D0\u4EA4\u6302\u552E...")),console.log(y.gray(` \u6807\u9898: ${r.title}`)),console.log(y.gray(` \u552E\u4EF7: \xA5${r.reservePrice}`)),console.log(y.gray(` \u6210\u8272: ${mr[r.stuffStatus]??r.stuffStatus}`)),console.log(y.gray(` \u56FE\u7247: ${e.length} \u5F20`)),r.itemAttrList?.length&&console.log(y.gray(` \u5C5E\u6027: ${r.itemAttrList.length} \u9879`)));let n=await Oo(r);t.json?console.log(JSON.stringify({success:!0,data:n},null,2)):(console.log(y.green("\u6302\u552E\u63D0\u4EA4\u6210\u529F")),console.log(JSON.stringify(n,null,2)))}))),o}function oe(){let o=new gr("goods");return o.description("\u5546\u54C1\u7BA1\u7406"),o.addCommand(Xo()),o.addCommand(Mo()),o.addCommand(Fo()),o.addCommand(Vo()),o.addCommand(Ko()),o.addCommand(Yo()),o.addCommand(Zo()),o.addCommand($o()),o.addCommand(te()),o}import{Command as pr}from"commander";import O from"chalk";import{promises as fr}from"node:fs";import hr from"node:path";import yr from"node:os";import{spawn as wr}from"node:child_process";var bt="@round2ai/r2-cli";function ee(){let o=new pr("uninstall");return o.description("\u5378\u8F7D R2-CLI \u5E76\u6E05\u9664\u6240\u6709\u914D\u7F6E"),o.action(async()=>{try{console.log(O.yellow(`
39
- \u26A0\uFE0F \u5373\u5C06\u6267\u884C\u4EE5\u4E0B\u64CD\u4F5C\uFF1A`)),console.log(O.gray(" 1. \u5220\u9664\u914D\u7F6E\u76EE\u5F55 ~/.r2-cli/")),console.log(O.gray(` 2. \u5168\u5C40\u5378\u8F7D ${bt}
40
- `));let{confirm:t}=await import("@inquirer/prompts");if(!await t({message:"\u786E\u8BA4\u5378\u8F7D\uFF1F",default:!1})){console.log(O.gray("\u5DF2\u53D6\u6D88\u5378\u8F7D"));return}let r=hr.join(yr.homedir(),".r2-cli");try{await fr.rm(r,{recursive:!0,force:!0}),console.log(O.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u6E05\u9664"))}catch{console.log(O.yellow("\u26A0\uFE0F \u914D\u7F6E\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u5220\u9664\uFF08\u53EF\u5FFD\u7565\uFF09"))}console.log(O.cyan(`\u6B63\u5728\u5378\u8F7D ${bt}...`)),wr("npm",["uninstall","-g",bt],{stdio:"inherit",shell:!0}).on("exit",s=>{s===0?console.log(O.green(`
41
- \u2705 ${bt} \u5DF2\u5378\u8F7D`)):(console.log(O.yellow(`
42
- \u26A0\uFE0F npm \u5378\u8F7D\u5931\u8D25 (exit code: ${s})`)),console.log(O.gray(" \u5982\u901A\u8FC7 yarn/pnpm \u5B89\u88C5\uFF0C\u8BF7\u624B\u52A8\u5378\u8F7D"))),process.exit(s??1)})}catch(t){v(t)}}),o}import{Command as Sr}from"commander";import it from"chalk";import{spawn as Cr,execSync as Tr}from"node:child_process";import{readFileSync as xr}from"node:fs";import{join as Ir}from"node:path";function Pt(){for(let o of["../package.json","../../package.json"])try{return JSON.parse(xr(Ir(import.meta.dirname,o),"utf-8")).version}catch{}return"0.0.0"}var re="@round2ai/r2-cli";function br(o,t){return new Promise(e=>{let r=Cr(o,t,{stdio:"inherit"});r.on("close",n=>e(n??1)),r.on("error",()=>e(1))})}function ne(){return new Sr("update").description("\u4E00\u952E\u66F4\u65B0 CLI \u548C\u6280\u80FD").action(async()=>{let o=Pt();console.log(it.cyan(`\u5F53\u524D\u7248\u672C: ${o}`)),console.log(it.cyan("\u6B63\u5728\u66F4\u65B0 CLI...")),await br("npm",["install","-g",`${re}@latest`])!==0&&(console.error(it.red(`
43
- \u2717 update failed \xB7 Try: npm install -g ${re}@latest`)),process.exit(1));let e=o;try{e=Tr("r2-cli --version",{encoding:"utf-8"}).trim()||o}catch{}console.log(it.green(`
44
- \u2713 \u66F4\u65B0\u5B8C\u6210: ${o} \u2192 ${e}`)),console.log(it.green("\u2713 \u6280\u80FD\u5DF2\u540C\u6B65\u66F4\u65B0"))})}function se(o){let t=o.command("auth").description("\u6388\u6743\u7BA1\u7406");t.addCommand(Xt()),t.addCommand(_t()),t.addCommand(Qt()),t.addCommand(Mt()),o.addCommand(oe()),o.addCommand(ee()),o.addCommand(ne())}import ie from"chalk";var ae="@round2ai/r2-cli",Pr=[`https://registry.npmmirror.com/${encodeURIComponent(ae)}/latest`,`https://registry.npmjs.org/${encodeURIComponent(ae)}/latest`],Ar=5e3;async function kr(o){let t=new AbortController,e=setTimeout(()=>t.abort(),Ar);try{let r=await fetch(o,{signal:t.signal});return r.ok?(await r.json()).version??null:null}catch{return null}finally{clearTimeout(e)}}async function vr(){let o=await Promise.allSettled(Pr.map(kr));for(let t of o)if(t.status==="fulfilled"&&t.value)return t.value;return null}function Nr(o,t){let e=o.split(".").map(Number),r=t.split(".").map(Number);for(let n=0;n<3;n++)if((e[n]??0)!==(r[n]??0))return(e[n]??0)>(r[n]??0);return!1}async function ce(o){let t=await vr();t&&Nr(t,o)&&Rr(o,t)}function Rr(o,t){console.error(ie.yellow(`
45
- Update available: ${o} \u2192 ${t}`)+ie.gray(`
37
+ `));for(let n of r.items)console.log(` ${Z.bold(n.goodsName)} ${n.size?Z.gray(`| ${n.size}`):""}`),console.log(` \u54C1\u724C: ${n.brand} \u5EFA\u8BAE\u552E\u4EF7: \xA5${n.salePrice} stockGoodsId: ${Z.green(n.stockGoodsId)}`),console.log(Z.gray(` \u5206\u7C7B: ${n.cate1Name} > ${n.cate2Name} > ${n.cate3Name}`)),console.log()})),o}import{Command as or}from"commander";import er from"chalk";et();import{Box as g,Text as h}from"ink";import{jsx as c,jsxs as j}from"react/jsx-runtime";var Ke={init:{label:"\u5F85\u4E0A\u67B6",color:"yellow"},up:{label:"\u5DF2\u4E0A\u67B6",color:"green"},down:{label:"\u5DF2\u4E0B\u67B6",color:"gray"},fail:{label:"\u5931\u8D25",color:"red"},sold:{label:"\u5DF2\u552E\u51FA",color:"blue"}},to=4,oo=8,St=12,eo=10,ro=6,no=8;function Qo(o,t){return o.length>t?o.slice(0,t-1)+"\u2026":o}function Mo(o){if(!o)return"-";let t=new Date(o),e=r=>String(r).padStart(2,"0");return`${e(t.getMonth()+1)}/${e(t.getDate())} ${e(t.getHours())}:${e(t.getMinutes())}`}function Ye({fillWidth:o}){return j(g,{flexDirection:"row",children:[c(g,{width:to,children:c(h,{bold:!0,color:"white",children:"ID"})}),c(g,{width:oo,children:c(h,{bold:!0,color:"white",children:"\u72B6\u6001"})}),c(g,{width:St,children:c(h,{bold:!0,color:"white",children:"\u54C1\u724C"})}),c(g,{width:o,children:c(h,{bold:!0,color:"white",children:"\u5546\u54C1\u540D\u79F0"})}),c(g,{width:eo,children:c(h,{bold:!0,color:"white",children:"\u4EF7\u683C"})}),c(g,{width:ro,children:c(h,{bold:!0,color:"white",children:"\u89C4\u683C"})}),c(g,{width:no,children:c(h,{bold:!0,color:"white",children:"\u5E93\u5B58ID"})})]})}function Ze({item:o}){return c(g,{flexDirection:"column",children:c(h,{color:"gray",children:` shopId: ${o.shopId} thirdItemNo: ${o.thirdItemNo||"-"} outItemNo: ${o.outItemNo||"-"} \u8D27\u53F7: ${o.goodsNo||"-"} ${o.type||"-"} ${o.platform} \u521B\u5EFA: ${Mo(o.gmtCreate)} \u4FEE\u6539: ${Mo(o.gmtModified)}`})})}function tr({item:o,fillWidth:t}){let e=Ke[o.status]??{label:o.status,color:"white"};return j(g,{flexDirection:"column",children:[j(g,{flexDirection:"row",children:[c(g,{width:to,children:c(h,{color:"gray",children:o.id})}),c(g,{width:oo,children:c(h,{color:e.color,children:e.label})}),c(g,{width:St,children:c(h,{color:"cyan",children:Qo(o.brandName||"-",St-1)})}),c(g,{width:t,children:c(h,{children:Qo(o.goodsName,t-1)})}),c(g,{width:eo,children:j(h,{color:"yellow",children:["\xA5",o.price]})}),c(g,{width:ro,children:c(h,{color:"gray",children:o.spec||"-"})}),c(g,{width:no,children:c(h,{color:"gray",children:o.stockGoodsId})})]}),c(Ze,{item:o})]})}function Fo({items:o,total:t}){let e=process.stdout.columns||80,r=4,n=to+oo+St+eo+ro+no,s=Math.max(e-r-n,20),i=n+s;return j(g,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[j(g,{flexDirection:"row",children:[c(h,{bold:!0,color:"cyan",children:"\u4E0A\u67B6\u5217\u8868"}),j(h,{color:"gray",children:[" \xB7 \u5171 ",t," \u6761"]})]}),j(g,{flexDirection:"column",marginTop:1,children:[c(Ye,{fillWidth:s}),c(h,{color:"gray",children:"\u2500".repeat(i)}),o.map(a=>c(tr,{item:a,fillWidth:s},a.id))]})]})}function zo(){let o=new or("listing");return o.description("\u67E5\u8BE2\u4E0A\u67B6\u5546\u54C1\u5217\u8868"),o.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/sold\uFF09").option("-p, --platform <platform>","\u5E73\u53F0","xianyu").option("--page <n>","\u9875\u7801","1").option("--size <n>","\u6BCF\u9875\u6570\u91CF\uFF08\u6700\u5927 50\uFF09","20").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),o.action(p(async t=>{let r=await vo({id:t.id,stockGoodsId:t.stockGoodsId?Number(t.stockGoodsId):void 0,shopId:t.shopId,stockId:t.stockId,status:t.status,platform:t.platform,page:Number(t.page)||1,size:Math.min(Number(t.size)||20,50)})??{items:[],total:0};if(t.json){r.items?.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.items?.length){console.log(er.yellow("\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55"));return}$t(Fo,{items:r.items,total:r.total})})),o}import{Command as rr}from"commander";import so from"chalk";function Wo(){let o=new rr("down");return o.description("\u4E0B\u67B6\u95F2\u9C7C\u5546\u54C1"),o.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"),o.action(p(async t=>{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(so.yellow("\u8BF7\u6307\u5B9A\u4E0B\u67B6\u6761\u4EF6\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let e={};t.id&&(e.id=t.id),t.stockGoodsId&&(e.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(e.shopId=t.shopId),t.json||console.log(so.cyan("\u{1F4E6} \u6B63\u5728\u4E0B\u67B6\u5546\u54C1..."));let r=await Ao(e);t.json?console.log(JSON.stringify({success:!0,data:r},null,2)):(console.log(so.green("\u2705 \u4E0B\u67B6\u6210\u529F")),console.log(JSON.stringify(r,null,2)))})),o}import{Command as nr}from"commander";import Ct from"chalk";function Ho(){let o=new nr("price");return o.description("\u4FEE\u6539\u95F2\u9C7C\u4E0A\u67B6\u5546\u54C1\u4EF7\u683C"),o.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"),o.action(p(async t=>{if(!t.price){t.json&&(console.log(JSON.stringify({success:!1,error:"--price <amount> \u4E3A\u5FC5\u586B\u53C2\u6570"})),process.exit(1)),console.log(Ct.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(Ct.yellow("\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let e={price:Number(t.price)};t.id&&(e.id=t.id),t.stockGoodsId&&(e.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(e.shopId=t.shopId),t.json||console.log(Ct.cyan(`\u{1F4B0} \u6B63\u5728\u4FEE\u6539\u4EF7\u683C\u4E3A ${t.price}...`));let r=await ko(e);t.json?console.log(JSON.stringify({success:!0,data:r},null,2)):(console.log(Ct.green("\u2705 \u4EF7\u683C\u4FEE\u6539\u6210\u529F")),console.log(JSON.stringify(r,null,2)))})),o}import{Command as Fs}from"commander";import Ws from"chalk";import{Command as nt}from"commander";import T from"chalk";var sr={100:"\u5168\u65B0",[-1]:"\u51C6\u65B0",99:"99\u65B0",95:"95\u65B0",90:"9\u65B0"};function Vo(){let o=new nt("hang-up");return o.description("\u95F2\u9C7C\u6302\u552E\u4E0A\u67B6\uFF08\u5B8C\u6574\u5546\u54C1\u4FE1\u606F\u6A21\u5F0F\uFF09"),o.addCommand(new nt("categories").description("\u83B7\u53D6\u95F2\u9C7C\u7C7B\u76EE\u5217\u8868\uFF08\u5927\u5206\u7C7B \u2192 \u5C0F\u5206\u7C7B\uFF09").option("--sp-biz-type <n>","\u4E1A\u52A1\u5206\u7C7B\uFF0C16=\u5962\u54C1","16").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(p(async t=>{let e=await Ro(Number(t.spBizType));if(t.json){console.log(JSON.stringify(e,null,2));return}let r=new Map;for(let n of e){let s=String(n.catId);r.has(s)||r.set(s,{catName:n.catName,children:[]}),r.get(s).children.push({channel:n.channel,channelCatId:n.channelCatId})}for(let[n,s]of r){console.log(T.bold(`${s.catName} (catId: ${T.green(n)})`));for(let i of s.children)console.log(` ${i.channel} (channelCatId: ${T.green(i.channelCatId)})`)}}))),o.addCommand(new nt("props").description("\u83B7\u53D6\u6307\u5B9A\u7C7B\u76EE\u4E0B\u7684\u5C5E\u6027\u5217\u8868\uFF08\u542B\u53EF\u9009\u503C\uFF09").requiredOption("--channel-cat-id <id>","\u5C0F\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(p(async t=>{let e=await Lo(t.channelCatId);if(t.json){console.log(JSON.stringify(e,null,2));return}for(let r of e)if(console.log(T.bold(`
38
+ ${r.propName} (propId: ${r.propId})`)),r.propsValues?.length)for(let n of r.propsValues)console.log(` ${n.valueName} (valueId: ${n.valueId})`);else console.log(T.gray(" \uFF08\u4F7F\u7528 brands \u5B50\u547D\u4EE4\u641C\u7D22\uFF09"))}))),o.addCommand(new nt("brands").description("\u641C\u7D22\u95F2\u9C7C\u54C1\u724C\uFF08\u6309\u5173\u952E\u5B57\u8FC7\u6EE4\uFF09").requiredOption("--channel-cat-id <id>","\u5C0F\u5206\u7C7B ID").requiredOption("--prop-id <id>","\u5C5E\u6027 ID\uFF08\u54C1\u724C\u5C5E\u6027\u7684 propId\uFF09").requiredOption("--key <keyword>","\u641C\u7D22\u5173\u952E\u5B57").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(p(async t=>{let e=await Oo(t.channelCatId,t.propId,t.key);if(t.json){console.log(JSON.stringify(e,null,2));return}if(!e.length){console.log(T.yellow("\u672A\u627E\u5230\u5339\u914D\u7684\u54C1\u724C"));return}for(let r of e)console.log(` ${r.valueName} (valueId: ${r.valueId})`)}))),o.addCommand(new nt("submit").description("\u63D0\u4EA4\u6302\u552E\u4E0A\u67B6").requiredOption("--shop-id <id>","\u5E97\u94FA ID\uFF08\u5373\u95F2\u9C7C\u7528\u6237\u540D account\uFF09").requiredOption("--title <title>","\u5546\u54C1\u6807\u9898").requiredOption("--price <amount>","\u552E\u4EF7").requiredOption("--category-id <id>","\u5927\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").requiredOption("--channel-cat-id <id>","\u5C0F\u5206\u7C7B ID\uFF08\u4ECE categories \u83B7\u53D6\uFF09").requiredOption("--image-ids <ids>","\u56FE\u7247 ID \u5217\u8868\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u5148\u901A\u8FC7 upload-images \u83B7\u53D6\uFF09").requiredOption("--stuff-status <n>","\u6210\u8272\uFF1A100 \u5168\u65B0 / -1 \u51C6\u65B0 / 99 99\u65B0 / 95 95\u65B0 / 90 9\u65B0").option("--item-attrs <json>",'\u5546\u54C1\u5C5E\u6027\u5217\u8868 JSON\uFF0C\u683C\u5F0F: [{"propId":"x","valueId":"y","valueName":"z"}]').option("--brand-name <name>","\u54C1\u724C\u540D\u79F0").option("--desc <desc>","\u5546\u54C1\u63CF\u8FF0").option("--size <size>","\u5C3A\u7801").option("--goods-no <no>","\u8D27\u53F7").option("--original-price <amount>","\u539F\u4EF7").option("--trade-type <n>","\u4EA4\u6613\u65B9\u5F0F\uFF1A0 \u4EC5\u5728\u7EBF / 1 \u4EC5\u7EBF\u4E0B / 2 \u7EBF\u4E0A\u6216\u7EBF\u4E0B","0").option("--transport-fee <amount>","\u8FD0\u8D39\uFF08\u9ED8\u8BA4 0 \u5305\u90AE\uFF09","0").option("--yhb","\u662F\u5426\u5F00\u542F\u9A8C\u8D27\u5B9D").requiredOption("--out-item-no <no>","\u5546\u5BB6\u7F16\u7801\uFF08\u540C\u5E97\u94FA\u552F\u4E00\uFF0C\u7528\u6237\u81EA\u5B9A\u4E49\uFF09").option("--division-id <id>","\u884C\u653F\u533A\u5212 ID\uFF08\u5E02\u7EA7 ID\uFF0C\u9ED8\u8BA4\u676D\u5DDE 330100\uFF09","330100").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").action(p(async t=>{let e=t.imageIds.split(",").map(s=>s.trim()),r={account:t.shopId,title:t.title,reservePrice:Number(t.price),categoryId:Number(t.categoryId),channelCatId:t.channelCatId,imageIdList:e,stuffStatus:Number(t.stuffStatus),itemBizType:2,spBizType:"16",tradeType:Number(t.tradeType)||0,transportFee:Number(t.transportFee)||0,yhb:t.yhb??!1,...t.brandName&&{brandName:t.brandName},...t.desc&&{desc:t.desc},...t.size&&{size:t.size},...t.goodsNo&&{goodsNo:t.goodsNo},...t.originalPrice&&{originalPrice:Number(t.originalPrice)},outItemNo:t.outItemNo,divisionId:Number(t.divisionId)||330100,apiAfterSalesDo:{supportFd10msPolicy:!1,supportFd24hsPolicy:!1,supportNfrPolicy:!1,supportSdrPolicy:!1,supportVnrPolicy:!1,supportGpaPolicy:!1,supportFd48hsPolicy:!1},...t.itemAttrs&&{itemAttrList:JSON.parse(t.itemAttrs)}};t.json||(console.log(T.cyan("\u6B63\u5728\u63D0\u4EA4\u6302\u552E...")),console.log(T.gray(` \u6807\u9898: ${r.title}`)),console.log(T.gray(` \u552E\u4EF7: \xA5${r.reservePrice}`)),console.log(T.gray(` \u6210\u8272: ${sr[r.stuffStatus]??r.stuffStatus}`)),console.log(T.gray(` \u56FE\u7247: ${e.length} \u5F20`)),r.itemAttrList?.length&&console.log(T.gray(` \u5C5E\u6027: ${r.itemAttrList.length} \u9879`)));let n=await No(r);t.json?console.log(JSON.stringify({success:!0,data:n},null,2)):(console.log(T.green("\u6302\u552E\u63D0\u4EA4\u6210\u529F")),console.log(JSON.stringify(n,null,2)))}))),o}function Ko(){let o=new ir("goods");return o.description("\u5546\u54C1\u7BA1\u7406"),o.addCommand(Go()),o.addCommand(Xo()),o.addCommand(_o()),o.addCommand(zo()),o.addCommand(Wo()),o.addCommand(Ho()),o.addCommand(Uo()),o.addCommand(Vo()),o}import{Command as ar}from"commander";import O from"chalk";import{promises as cr}from"node:fs";import lr from"node:path";import dr from"node:os";import{spawn as ur}from"node:child_process";var Tt="@round2ai/r2-cli";function Yo(){let o=new ar("uninstall");return o.description("\u5378\u8F7D R2-CLI \u5E76\u6E05\u9664\u6240\u6709\u914D\u7F6E"),o.action(async()=>{try{console.log(O.yellow(`
39
+ \u26A0\uFE0F \u5373\u5C06\u6267\u884C\u4EE5\u4E0B\u64CD\u4F5C\uFF1A`)),console.log(O.gray(" 1. \u5220\u9664\u914D\u7F6E\u76EE\u5F55 ~/.r2-cli/")),console.log(O.gray(` 2. \u5168\u5C40\u5378\u8F7D ${Tt}
40
+ `));let{confirm:t}=await import("@inquirer/prompts");if(!await t({message:"\u786E\u8BA4\u5378\u8F7D\uFF1F",default:!1})){console.log(O.gray("\u5DF2\u53D6\u6D88\u5378\u8F7D"));return}let r=lr.join(dr.homedir(),".r2-cli");try{await cr.rm(r,{recursive:!0,force:!0}),console.log(O.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u6E05\u9664"))}catch{console.log(O.yellow("\u26A0\uFE0F \u914D\u7F6E\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u5220\u9664\uFF08\u53EF\u5FFD\u7565\uFF09"))}console.log(O.cyan(`\u6B63\u5728\u5378\u8F7D ${Tt}...`)),ur("npm",["uninstall","-g",Tt],{stdio:"inherit",shell:!0}).on("exit",s=>{s===0?console.log(O.green(`
41
+ \u2705 ${Tt} \u5DF2\u5378\u8F7D`)):(console.log(O.yellow(`
42
+ \u26A0\uFE0F npm \u5378\u8F7D\u5931\u8D25 (exit code: ${s})`)),console.log(O.gray(" \u5982\u901A\u8FC7 yarn/pnpm \u5B89\u88C5\uFF0C\u8BF7\u624B\u52A8\u5378\u8F7D"))),process.exit(s??1)})}catch(t){v(t)}}),o}import{Command as pr}from"commander";import st from"chalk";import{spawn as fr,execSync as hr}from"node:child_process";import{readFileSync as mr}from"node:fs";import{join as gr}from"node:path";function bt(){for(let o of["../package.json","../../package.json"])try{return JSON.parse(mr(gr(import.meta.dirname,o),"utf-8")).version}catch{}return"0.0.0"}var Zo="@round2ai/r2-cli";function yr(o,t){return new Promise(e=>{let r=fr(o,t,{stdio:"inherit"});r.on("close",n=>e(n??1)),r.on("error",()=>e(1))})}function te(){return new pr("update").description("\u4E00\u952E\u66F4\u65B0 CLI \u548C\u6280\u80FD").action(async()=>{let o=bt();console.log(st.cyan(`\u5F53\u524D\u7248\u672C: ${o}`)),console.log(st.cyan("\u6B63\u5728\u66F4\u65B0 CLI...")),await yr("npm",["install","-g",`${Zo}@latest`])!==0&&(console.error(st.red(`
43
+ \u2717 update failed \xB7 Try: npm install -g ${Zo}@latest`)),process.exit(1));let e=o;try{e=hr("r2-cli --version",{encoding:"utf-8"}).trim()||o}catch{}console.log(st.green(`
44
+ \u2713 \u66F4\u65B0\u5B8C\u6210: ${o} \u2192 ${e}`)),console.log(st.green("\u2713 \u6280\u80FD\u5DF2\u540C\u6B65\u66F4\u65B0"))})}function oe(o){let t=o.command("auth").description("\u6388\u6743\u7BA1\u7406");t.addCommand(Jt()),t.addCommand(Xt()),t.addCommand(_t()),t.addCommand(Qt()),o.addCommand(Ko()),o.addCommand(Yo()),o.addCommand(te())}import ee from"chalk";var re="@round2ai/r2-cli",wr=[`https://registry.npmmirror.com/${encodeURIComponent(re)}/latest`,`https://registry.npmjs.org/${encodeURIComponent(re)}/latest`],xr=5e3;async function Ir(o){let t=new AbortController,e=setTimeout(()=>t.abort(),xr);try{let r=await fetch(o,{signal:t.signal});return r.ok?(await r.json()).version??null:null}catch{return null}finally{clearTimeout(e)}}async function Sr(){let o=await Promise.allSettled(wr.map(Ir));for(let t of o)if(t.status==="fulfilled"&&t.value)return t.value;return null}function Cr(o,t){let e=o.split(".").map(Number),r=t.split(".").map(Number);for(let n=0;n<3;n++)if((e[n]??0)!==(r[n]??0))return(e[n]??0)>(r[n]??0);return!1}async function ne(o){let t=await Sr();t&&Cr(t,o)&&Tr(o,t)}function Tr(o,t){console.error(ee.yellow(`
45
+ Update available: ${o} \u2192 ${t}`)+ee.gray(`
46
46
  Run: r2-cli update
47
- `))}async function Or(){let{default:o}=await import("figlet");console.log(ot.cyan.bold(o.textSync("R2-CLI",{font:"Standard",horizontalLayout:"full"}))),console.log(ot.gray(` \u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B
48
- `))}function Dr(){let o=new Lr;o.name("r2-cli").description("R2-CLI\uFF0C\u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B");let t=Pt();t==="0.0.0"&&console.error(ot.yellow("Warning: unable to read version from package.json")),o.version(t,"-v, --version");let e=ce(t);return o.configureOutput({writeErr:r=>{console.error(ot.red(r.replace("error:","").trim()))}}),o.action(async()=>{await Or(),o.help()}),se(o),{program:o,updateCheckPromise:e}}function le(){console.log(ot.gray(`
49
- \u64CD\u4F5C\u5DF2\u53D6\u6D88`)),process.exit(130)}process.on("SIGINT",le);process.on("SIGTERM",le);var{program:Ur,updateCheckPromise:jr}=Dr();Ur.parse(process.argv);jr.catch(o=>{console.error(ot.gray(`[update-check] ${o instanceof Error?o.message:String(o)}`))});
47
+ `))}async function Pr(){let{default:o}=await import("figlet");console.log(tt.cyan.bold(o.textSync("R2-CLI",{font:"Standard",horizontalLayout:"full"}))),console.log(tt.gray(` \u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B
48
+ `))}function Ar(){let o=new br;o.name("r2-cli").description("R2-CLI\uFF0C\u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B");let t=bt();t==="0.0.0"&&console.error(tt.yellow("Warning: unable to read version from package.json")),o.version(t,"-v, --version");let e=ne(t);return o.configureOutput({writeErr:r=>{console.error(tt.red(r.replace("error:","").trim()))}}),o.action(async()=>{await Pr(),o.help()}),oe(o),{program:o,updateCheckPromise:e}}function se(){console.log(tt.gray(`
49
+ \u64CD\u4F5C\u5DF2\u53D6\u6D88`)),process.exit(130)}process.on("SIGINT",se);process.on("SIGTERM",se);var{program:kr,updateCheckPromise:vr}=Ar();kr.parse(process.argv);vr.catch(o=>{console.error(tt.gray(`[update-check] ${o instanceof Error?o.message:String(o)}`))});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@round2ai/r2-cli",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "R2-CLI,向 AI 开放二手潮奢交易全链路能力",
5
5
  "main": "dist/r2-cli.js",
6
6
  "type": "module",
@@ -60,6 +60,8 @@ r2-cli auth login --json
60
60
 
61
61
  ### Agent 操作步骤
62
62
 
63
+ > **注意**:不要在命令末尾加 `&`。`run_in_background: true` 已处理后台运行,加 `&` 会导致 shell 立即返回,无法捕获后续输出。
64
+
63
65
  1. 用 Bash 工具 `run_in_background: true` 启动命令
64
66
  2. 用 `TaskOutput(block=true, timeout=5000)` 获取第 1 段 JSON
65
67
  3. **必须先**将 `qrUrl` 以醒目格式单独一行展示给用户:
@@ -46,16 +46,17 @@ metadata:
46
46
  | `r2-cli goods shops [--json]` | 查看已授权店铺 | [r2-goods-query](references/r2-goods-query.md) |
47
47
  | `r2-cli goods stocks [--json]` | 查看仓库 | [r2-goods-query](references/r2-goods-query.md) |
48
48
  | `r2-cli goods list [--stock-id <id>] [--json]` | 查看选品商品 | [r2-goods-query](references/r2-goods-query.md) |
49
- | `r2-cli goods listing [--json]` | 查询上架列表 | [r2-goods-query](references/r2-goods-query.md) |
49
+ | `r2-cli goods listing [--status <up/down/sold>] [--json]` | 查询上架列表 | [r2-goods-query](references/r2-goods-query.md) |
50
50
 
51
- ### 上架/下架/改价/修改
51
+ ### 上架/下架/改价
52
52
 
53
53
  | 命令 | 说明 | 详细文档 |
54
54
  |------|------|----------|
55
55
  | `r2-cli goods up --stock-goods-id <> --shop-id <> --price <> --json` | 普通上架(选品商品) | [r2-goods-listing](references/r2-goods-listing.md) |
56
56
  | `r2-cli goods down --id <id> [--json]` | 下架商品 | [r2-goods-listing](references/r2-goods-listing.md) |
57
57
  | `r2-cli goods price --id <id> --price <amount> [--json]` | 修改价格 | [r2-goods-listing](references/r2-goods-listing.md) |
58
- | `r2-cli goods edit --id <id> [--title ...] --json` | 修改商品信息 | [r2-goods-listing](references/r2-goods-listing.md) |
58
+
59
+ > **暂未开放**:`goods edit`(修改商品信息)接口尚未发布正式版,暂时不可用。
59
60
 
60
61
  ### 选品上架 4 步流程
61
62
 
@@ -66,39 +67,6 @@ metadata:
66
67
 
67
68
  必填参数:`--stock-goods-id`、`--shop-id`(取 `shopId` 不是 `id`)、`--price`
68
69
 
69
- ### 修改商品信息(edit)
70
-
71
- 修改已上架商品的标题、描述、品牌、类目、图片、属性等。
72
-
73
- **路由决策**:
74
-
75
- | 用户意图 | 流程 |
76
- |----------|------|
77
- | 提供了图片文件 | 全自动:读图识别 → 上传图片 → 匹配类目/属性/品牌 → 展示变更 → 用户确认 → 提交 |
78
- | 指定了具体字段(如"改标题为X") | 直接修改指定字段,不动图片 |
79
- | 说"修改/更新商品信息"但没给细节 | 提示:可以提供图片自动识别商品信息,也可以指定要修改的具体字段 |
80
-
81
- **定位商品**:优先使用 `--id <goodsListingId>`(从上架列表获取 `id` 字段),也可用 `--stock-goods-id <id> --account <shopId>`。
82
-
83
- **关键约束**:
84
- - `--category-id` 和 `--channel-cat-id` 是**必填的**(后端复用挂售 DTO),即使不改类目也要传当前类目
85
- - Agent 应自动查询类目并匹配,不需要用户手动提供
86
- - AI 读图识别后填充的字段需展示给用户确认,不能静默覆盖已有信息
87
- - `--image-ids` 接受已上传的图片 ID,用户给图片文件时需先调 `hang-up upload-images` 上传
88
-
89
- **带图片的全自动流程**(Agent 自动完成,用户只需提供图片并确认):
90
-
91
- 1. **展示列表**:`goods listing --json` → 用户选择要修改的商品
92
- 2. **上传图片**:`hang-up upload-images --shop-id <shopId> --files <paths> --json`
93
- 3. **AI 读图识别**:Agent 用 Read 工具查看图片,识别品牌/类目/成色/描述等
94
- 4. **自动匹配类目**:`hang-up categories --json` → 根据识别结果匹配 catId + channelCatId
95
- 5. **自动查询属性**:`hang-up props --channel-cat-id <id> --json` → 根据识别结果匹配成色/尺码/季节等
96
- 6. **自动搜索品牌**:`hang-up brands --channel-cat-id <> --prop-id <> --key <品牌名> --json` → 获取品牌 valueId
97
- 7. **汇总展示**:当前值 vs 变更值,让用户确认
98
- 8. **提交**:`goods edit --id <goodsListingId> --category-id <> --channel-cat-id <> --image-ids <> --item-attrs <> --brand-name <> --json`
99
-
100
- **核心原则**:用户只需提供图片 + 确认。类目匹配、属性填充、品牌搜索全部由 Agent 自动完成。
101
-
102
70
  ### 挂售(hang-up)
103
71
 
104
72
  | 命令 | 说明 | 详细文档 |
@@ -106,17 +74,17 @@ metadata:
106
74
  | `r2-cli goods hang-up categories [--json]` | 获取闲鱼类目 | [r2-goods-hangup](references/r2-goods-hangup.md) |
107
75
  | `r2-cli goods hang-up props --channel-cat-id <id> [--json]` | 获取属性列表 | [r2-goods-hangup](references/r2-goods-hangup.md) |
108
76
  | `r2-cli goods hang-up brands --channel-cat-id <> --prop-id <> --key <> [--json]` | 品牌搜索 | [r2-goods-hangup](references/r2-goods-hangup.md) |
109
- | `r2-cli goods hang-up upload-images --shop-id <> --files <> --json` | 上传图片 | [r2-goods-hangup](references/r2-goods-hangup.md) |
110
77
  | `r2-cli goods hang-up submit --shop-id <> --title <> ... --json` | 提交挂售上架 | [r2-goods-hangup](references/r2-goods-hangup.md) |
111
78
 
79
+ > **暂未开放**:`hang-up upload-images`(上传图片)接口尚未发布正式版,暂时不可用。
80
+
112
81
  ### 挂售上架流程
113
82
 
114
- 1. **上传图片**:`hang-up upload-images --shop-id <> --files <paths> --json`
115
- 2. **识别商品**:Agent Read 工具查看图片,自动识别品牌/成色/类目/描述。不支持读图的 Agent 走询问路径
116
- 3. **匹配类目**:`hang-up categories --json` → 自动匹配
117
- 4. **匹配属性**:`hang-up props --channel-cat-id <id> --json` → 自动填充。品牌需调 `hang-up brands` 搜索
118
- 5. **汇总展示**:自动填充的字段标 ✅,缺失字段标 让用户补充
119
- 6. **提交**:`hang-up submit` — 必填:`shop-id`、`title`、`price`、`category-id`、`channel-cat-id`、`image-ids`、`stuff-status`、`desc`、`out-item-no`
83
+ 1. **识别商品**:Agent Read 工具查看图片,自动识别品牌/成色/类目/描述。不支持读图的 Agent 走询问路径
84
+ 2. **匹配类目**:`hang-up categories --json` 自动匹配
85
+ 3. **匹配属性**:`hang-up props --channel-cat-id <id> --json` → 自动填充。品牌需调 `hang-up brands` 搜索
86
+ 4. **汇总展示**:自动填充的字段标 ✅,缺失字段标 让用户补充
87
+ 5. **提交**:`hang-up submit` 必填:`shop-id`、`title`、`price`、`category-id`、`channel-cat-id`、`image-ids`、`stuff-status`、`desc`、`out-item-no`
120
88
 
121
89
  **核心原则**:**图片里能看到的,就别问用户**。只问价格和商家编码(优先用户自定义,不填则推荐自动生成),其他全部从图片自动提取。
122
90
 
@@ -156,7 +156,7 @@ Agent 将所有自动填充和识别结果汇总展示给用户,**一次确认
156
156
  ✅ 鞋码:42(图片识别)
157
157
  ❓ 季节:?(无法识别,请选择:春季/夏季/秋季/冬季/四季)
158
158
  💰 价格:?(必填)
159
- 📋 商家编码:?(必填)
159
+ 📋 商家编码:?(优先自定义,不填自动生成)
160
160
  ```
161
161
 
162
162
  **处理顺序**:
@@ -164,7 +164,7 @@ Agent 将所有自动填充和识别结果汇总展示给用户,**一次确认
164
164
  2. 让用户补充缺失字段(价格、商家编码、无法识别的属性)
165
165
  3. 用户确认后直接提交
166
166
 
167
- **所有参数就绪后直接提交,不需要用户确认**:
167
+ **所有参数就绪后提交**:
168
168
 
169
169
  ```bash
170
170
  r2-cli goods hang-up submit \
@@ -215,6 +215,14 @@ r2-cli goods hang-up submit \
215
215
  | `--title`(标题) | 图片识别无法生成时 | "商品标题用什么?" |
216
216
  | `--desc`(描述) | 图片识别无法生成时 | "商品描述?" |
217
217
 
218
+ ## Agent 常见错误预防
219
+
220
+ - **不要在命令末尾加 `&`**:如果用 `run_in_background: true` 启动命令,不要额外加 `&`,否则 shell 立即返回,无法捕获后续输出
221
+ - **`--image-ids` 保持字符串**:图片 ID 是 19 位数字(如 `"1086608743767730915"`),JavaScript `Number()` 会精度丢失。拼接时用字符串拼接,不要 `parseInt`/`Number`
222
+ - **`--stuff-status` 准新是数字 `-1`**:不是字符串 `"-1"`,直接传 `--stuff-status -1`
223
+ - **`--item-attrs` 传 JSON 字符串**:值必须是 `JSON.stringify()` 后的字符串,不能直接传对象。命令行示例:`--item-attrs '[{"propId":"x","valueId":"y"}]'`
224
+ - **`--files` 和 `--image-ids` 都是逗号分隔**:不要多次传 `--files`,用逗号拼成单个值:`--files a.jpg,b.jpg`
225
+
218
226
  ## 必填参数
219
227
 
220
228
  | 参数 | 说明 |
@@ -23,7 +23,24 @@
23
23
  }
24
24
  ```
25
25
 
26
- 状态值:`init`(处理中)、`up`(已上架)、`down`(已下架)、`fail`(失败,查看 `errorMsg`)
26
+ 状态值:`init`(处理中)、`up`(已上架)、`down`(已下架)、`fail`(失败,查看 `errorMsg`)、`sold`(已售出)
27
+
28
+ ## 上架列表返回字段
29
+
30
+ | 字段 | 说明 |
31
+ |------|------|
32
+ | `id` | 上架记录 ID(edit/down/price 的 `--id` 取这个值) |
33
+ | `stockGoodsId` | 库存商品 ID(挂售商品可能为 0) |
34
+ | `shopId` | 店铺 ID |
35
+ | `goodsName` | 商品名称 |
36
+ | `brandName` | 品牌 |
37
+ | `price` | 上架价格 |
38
+ | `status` | 状态:`init`/`up`/`down`/`fail`/`sold` |
39
+ | `thirdItemNo` | 平台商品 ID |
40
+ | `outItemNo` | 商家编码 |
41
+ | `spec` | 规格(尺码) |
42
+ | `platform` | 平台(xianyu) |
43
+ | `gmtCreate` / `gmtModified` | 创建/修改时间戳 |
27
44
 
28
45
  ## 上架参数
29
46
 
@@ -71,6 +88,12 @@ r2-cli goods price --stock-goods-id <id> --shop-id <id> --price <新价格> --js
71
88
  | 上架记录 ID | `--id <goodsListingId>` | 推荐,从 listing 的 id 字段取 |
72
89
  | 库存商品 + 店铺 | `--stock-goods-id <id> --account <shopId>` | 备选,挂售商品 stockGoodsId 可能为 0 |
73
90
 
91
+ ### Agent 注意事项
92
+
93
+ - **`--image-ids` 保持字符串**:图片 ID 是 19 位数字,`Number()` 会精度丢失
94
+ - **`--item-attrs` 传 JSON 字符串**:必须是 `JSON.stringify()` 后的结果,不能直接传对象
95
+ - **即使不改类目也要传 `--category-id` 和 `--channel-cat-id`**:后端必填,缺少会报 `getCategoryId() is null`
96
+
74
97
  ### 必填参数
75
98
 
76
99
  | 参数 | 说明 |
@@ -126,7 +149,7 @@ r2-cli goods edit \
126
149
 
127
150
  ```bash
128
151
  # 改标题
129
- r2-cli goods goods edit --id 5 \
152
+ r2-cli goods edit --id 5 \
130
153
  --category-id 50106003 --channel-cat-id "f4718bbb04d7ed1facde29f76907b07f" \
131
154
  --title "新标题" --json
132
155
 
@@ -36,7 +36,7 @@ r2-cli goods list --stock-id <stockId> --json
36
36
  r2-cli goods list --stock-goods-id <id> --json
37
37
 
38
38
  # 翻页
39
- r2-cli goods list --stock-id <stockId> --page 2 --size 20 --json
39
+ r2-cli goods list --stock-id <stockId> --page 2 --size 50 --json
40
40
  ```
41
41
 
42
42
  返回字段:
@@ -59,6 +59,7 @@ r2-cli goods listing --status sold --json # 只看已售出
59
59
  r2-cli goods listing --shop-id <id> --json # 按店铺过滤
60
60
  r2-cli goods listing --stock-goods-id <id> --json # 按商品过滤
61
61
  r2-cli goods listing --id <id> --json # 精确查询
62
+ r2-cli goods listing --page 2 --size 50 --json # 翻页
62
63
  ```
63
64
 
64
- 过滤参数:`--id`、`--stock-goods-id`、`--shop-id`、`--stock-id`、`--status`(init/up/down/fail/sold)、`--platform`
65
+ 过滤参数:`--id`、`--stock-goods-id`、`--shop-id`、`--stock-id`、`--status`(init/up/down/fail/sold)、`--platform`、`--page`(默认 1)、`--size`(默认 20,最大 50)
@@ -28,6 +28,7 @@ metadata:
28
28
  - 所有命令**必须**通过已安装的 `r2-cli` 二进制执行(`r2-cli goods ...`、`r2-cli auth ...`)
29
29
  - **禁止**读取项目源码或用 `tsx`/`node` 直接运行源文件
30
30
  - 如果 `r2-cli` 命令不可用,提示用户先安装:`npm install -g @round2ai/r2-cli@latest`
31
+ - **不要在命令末尾加 `&`**:如果用 Bash 工具的 `run_in_background: true`,不要额外加 `&`,否则 shell 立即返回导致输出丢失
31
32
 
32
33
  **版本检查**:
33
34
  - 首次使用时,Agent 应运行 `r2-cli --version` 检查当前版本
@@ -66,15 +67,13 @@ npm install -g @round2ai/r2-cli@latest
66
67
  | 查询 | `r2-cli goods shops [--json]` | 查看已授权店铺 |
67
68
  | | `r2-cli goods stocks [--json]` | 查看仓库 |
68
69
  | | `r2-cli goods list [--stock-id <id>] [--json]` | 查看选品商品 |
69
- | | `r2-cli goods listing [--json]` | 查询上架列表 |
70
+ | | `r2-cli goods listing [--status <up/down/sold>] [--json]` | 查询上架列表 |
70
71
  | 上架 | `r2-cli goods up --stock-goods-id <> --shop-id <> --price <> --json` | 普通上架(选品商品) |
71
72
  | | `r2-cli goods down --id <id> [--json]` | 下架商品 |
72
73
  | | `r2-cli goods price --id <id> --price <amount> [--json]` | 修改价格 |
73
- | 修改 | `r2-cli goods edit --id <> --category-id <> --channel-cat-id <> ... --json` | 修改商品信息(定位推荐 `--id`) |
74
74
  | 挂售 | `r2-cli goods hang-up categories [--json]` | 获取闲鱼类目 |
75
75
  | | `r2-cli goods hang-up props --channel-cat-id <id> [--json]` | 获取属性列表 |
76
76
  | | `r2-cli goods hang-up brands --channel-cat-id <> --prop-id <> --key <> [--json]` | 品牌搜索 |
77
- | | `r2-cli goods hang-up upload-images --shop-id <> --files <> --json` | 上传图片 |
78
77
  | | `r2-cli goods hang-up submit --shop-id <> --title <> ... --json` | 提交挂售上架 |
79
78
 
80
79
  ## 其他命令