@round2ai/r2-cli 1.0.11 → 1.0.12-beta.0

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
@@ -5,7 +5,7 @@
5
5
 
6
6
  R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com/Round2AI) 团队维护 — 让人类和 AI Agent 都能在终端中完成商品上架等交易操作。
7
7
 
8
- 覆盖商品上架、认证登录等核心业务域,提供 7 个商品命令及 3 个 AI Agent [Skills](./skills/)。
8
+ 覆盖商品上架、挂售、认证登录等核心业务域,提供 12 个命令及 3 个 AI Agent [Skills](./skills/)。
9
9
 
10
10
  [安装](#安装与快速开始) · [AI Agent 快速开始](#快速开始ai-agent) · [Agent Skills](#agent-skills) · [认证](#认证) · [命令](#命令参考) · [安全](#安全与风险提示)
11
11
 
@@ -22,6 +22,7 @@ R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com
22
22
  |------|------|
23
23
  | 认证登录 | 扫码登录(第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出(Agent 一步式流程) |
24
24
  | 商品管理 | 商品上架(4 步流程:获取店铺 → 获取仓库 → 获取选品商品 → 提交上架 + 自动轮询上架结果)、店铺查看、仓库查看、选品商品查看、上架列表查询、下架、改价 |
25
+ | 闲鱼挂售 | 完整商品信息模式:类目查询 → 属性/品牌选择 → 图片上传 → 提交挂售 |
25
26
 
26
27
  ---
27
28
 
@@ -114,9 +115,9 @@ npx skills add Round2AI/r2-cli --all -y
114
115
 
115
116
  | Skill | 说明 |
116
117
  |-------|------|
118
+ | `r2-shared` | 共享基础:安装、统一错误格式、命令概览 |
117
119
  | `r2-auth` | 认证登录:一步式扫码登录(生成二维码 + 自动轮询,支持第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出 |
118
- | `r2-cli` | 命令概览:安装检测、认证命令、商品管理命令、命令前缀自动识别 |
119
- | `r2-goods` | 商品管理:4 步上架流程(获取数据 → 展示给用户 → 用户选择 → 提交上架 + 自动轮询结果)、下架、改价、店铺/仓库/商品/上架列表查看 |
120
+ | `r2-goods` | 商品管理:4 步上架流程、挂售流程(类目→属性→图片→提交)、下架、改价、店铺/仓库/商品/上架列表查看 |
120
121
 
121
122
  ---
122
123
 
@@ -139,7 +140,7 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
139
140
 
140
141
  ## 命令参考
141
142
 
142
- ### 商品管理
143
+ ### 商品查询
143
144
 
144
145
  | 命令 | 说明 |
145
146
  |------|------|
@@ -147,20 +148,31 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
147
148
  | `r2-cli goods stocks [--json]` | 查看所有仓库 |
148
149
  | `r2-cli goods list [--stock-id <id>] [--stock-goods-id <id>] [--json]` | 查看选品商品(可按仓库或商品 ID 过滤,支持 `--page` 和 `--size`) |
149
150
  | `r2-cli goods listing [--json]` | 查询上架列表(支持 `--id` / `--shop-id` / `--stock-goods-id` / `--stock-id` / `--status` / `--platform` 过滤) |
151
+
152
+ ### 商品上架/下架
153
+
154
+ | 命令 | 说明 |
155
+ |------|------|
150
156
  | `r2-cli goods up` | 交互式上架(自动轮询上架结果) |
151
157
  | `r2-cli goods up --stock-goods-id <id> --shop-id <id> --price <amount> --json` | Agent 直接上架(自动轮询上架结果) |
152
158
  | `r2-cli goods down --id <id> [--json]` | 下架商品(也可用 `--stock-goods-id <id> --shop-id <id>`) |
153
159
  | `r2-cli goods price --id <id> --price <amount> [--json]` | 修改上架价格(也可用 `--stock-goods-id <id> --shop-id <id>`) |
154
160
 
155
- ### 上架参数
161
+ ### 闲鱼挂售(完整商品信息模式)
162
+
163
+ 挂售模式支持完整的商品信息:图片、类目、属性、品牌等。流程:查询类目/属性 → 上传图片 → 提交挂售。
164
+
165
+ | 命令 | 说明 |
166
+ |------|------|
167
+ | `r2-cli goods hang-up categories [--json]` | 获取闲鱼类目列表(大分类 → 小分类) |
168
+ | `r2-cli goods hang-up props --channel-cat-id <id> [--json]` | 获取指定类目下的属性列表(含可选值) |
169
+ | `r2-cli goods hang-up brands --channel-cat-id <id> --prop-id <id> --key <keyword> [--json]` | 品牌搜索 |
170
+ | `r2-cli goods hang-up upload-images --shop-id <id> --files <paths> --json` | 批量上传图片到闲鱼(挂售前必须先上传) |
171
+ | `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` | 提交挂售上架 |
172
+
173
+ **挂售必填参数**:`--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`(商家编码,同店铺唯一)
156
174
 
157
- | 参数 | 必填 | 说明 |
158
- |------|------|------|
159
- | `--stock-goods-id <id>` | 是 | 库存商品 ID(来自选品商品列表的 `stockGoodsId` 字段) |
160
- | `--shop-id <id>` | 是 | 第三方店铺 ID(来自店铺列表的 `shopId` 字段,不是 `id`) |
161
- | `--price <amount>` | 是 | 上架价格(正数) |
162
- | `-p, --platform <platform>` | 否 | 平台,默认 xianyu |
163
- | `--json` | 否 | JSON 输出(Agent 推荐) |
175
+ **挂售可选参数**:`--brand-name`、`--size`、`--goods-no`、`--original-price`、`--item-attrs`(属性列表 JSON)、`--trade-type`(默认 0 仅在线)、`--transport-fee`(默认 0 包邮)、`--yhb`(验货宝)、`--division-id`(默认 330100 杭州)
164
176
 
165
177
  ### 其他命令
166
178
 
package/dist/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com/Round2AI) 团队维护 — 让人类和 AI Agent 都能在终端中完成商品上架等交易操作。
7
7
 
8
- 覆盖商品上架、认证登录等核心业务域,提供 7 个商品命令及 3 个 AI Agent [Skills](./skills/)。
8
+ 覆盖商品上架、挂售、认证登录等核心业务域,提供 12 个命令及 3 个 AI Agent [Skills](./skills/)。
9
9
 
10
10
  [安装](#安装与快速开始) · [AI Agent 快速开始](#快速开始ai-agent) · [Agent Skills](#agent-skills) · [认证](#认证) · [命令](#命令参考) · [安全](#安全与风险提示)
11
11
 
@@ -22,6 +22,7 @@ R2-CLI — 二手潮奢交易命令行工具,由 [Round2AI](https://github.com
22
22
  |------|------|
23
23
  | 认证登录 | 扫码登录(第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出(Agent 一步式流程) |
24
24
  | 商品管理 | 商品上架(4 步流程:获取店铺 → 获取仓库 → 获取选品商品 → 提交上架 + 自动轮询上架结果)、店铺查看、仓库查看、选品商品查看、上架列表查询、下架、改价 |
25
+ | 闲鱼挂售 | 完整商品信息模式:类目查询 → 属性/品牌选择 → 图片上传 → 提交挂售 |
25
26
 
26
27
  ---
27
28
 
@@ -114,9 +115,9 @@ npx skills add Round2AI/r2-cli --all -y
114
115
 
115
116
  | Skill | 说明 |
116
117
  |-------|------|
118
+ | `r2-shared` | 共享基础:安装、统一错误格式、命令概览 |
117
119
  | `r2-auth` | 认证登录:一步式扫码登录(生成二维码 + 自动轮询,支持第二回合 APP / 微信 / 支付宝)、闲鱼店铺授权、状态查询、登出 |
118
- | `r2-cli` | 命令概览:安装检测、认证命令、商品管理命令、命令前缀自动识别 |
119
- | `r2-goods` | 商品管理:4 步上架流程(获取数据 → 展示给用户 → 用户选择 → 提交上架 + 自动轮询结果)、下架、改价、店铺/仓库/商品/上架列表查看 |
120
+ | `r2-goods` | 商品管理:4 步上架流程、挂售流程(类目→属性→图片→提交)、下架、改价、店铺/仓库/商品/上架列表查看 |
120
121
 
121
122
  ---
122
123
 
@@ -139,7 +140,7 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
139
140
 
140
141
  ## 命令参考
141
142
 
142
- ### 商品管理
143
+ ### 商品查询
143
144
 
144
145
  | 命令 | 说明 |
145
146
  |------|------|
@@ -147,20 +148,31 @@ Token 存储在 `~/.r2-cli/config.json`(原子写入防丢失),过期后
147
148
  | `r2-cli goods stocks [--json]` | 查看所有仓库 |
148
149
  | `r2-cli goods list [--stock-id <id>] [--stock-goods-id <id>] [--json]` | 查看选品商品(可按仓库或商品 ID 过滤,支持 `--page` 和 `--size`) |
149
150
  | `r2-cli goods listing [--json]` | 查询上架列表(支持 `--id` / `--shop-id` / `--stock-goods-id` / `--stock-id` / `--status` / `--platform` 过滤) |
151
+
152
+ ### 商品上架/下架
153
+
154
+ | 命令 | 说明 |
155
+ |------|------|
150
156
  | `r2-cli goods up` | 交互式上架(自动轮询上架结果) |
151
157
  | `r2-cli goods up --stock-goods-id <id> --shop-id <id> --price <amount> --json` | Agent 直接上架(自动轮询上架结果) |
152
158
  | `r2-cli goods down --id <id> [--json]` | 下架商品(也可用 `--stock-goods-id <id> --shop-id <id>`) |
153
159
  | `r2-cli goods price --id <id> --price <amount> [--json]` | 修改上架价格(也可用 `--stock-goods-id <id> --shop-id <id>`) |
154
160
 
155
- ### 上架参数
161
+ ### 闲鱼挂售(完整商品信息模式)
162
+
163
+ 挂售模式支持完整的商品信息:图片、类目、属性、品牌等。流程:查询类目/属性 → 上传图片 → 提交挂售。
164
+
165
+ | 命令 | 说明 |
166
+ |------|------|
167
+ | `r2-cli goods hang-up categories [--json]` | 获取闲鱼类目列表(大分类 → 小分类) |
168
+ | `r2-cli goods hang-up props --channel-cat-id <id> [--json]` | 获取指定类目下的属性列表(含可选值) |
169
+ | `r2-cli goods hang-up brands --channel-cat-id <id> --prop-id <id> --key <keyword> [--json]` | 品牌搜索 |
170
+ | `r2-cli goods hang-up upload-images --shop-id <id> --files <paths> --json` | 批量上传图片到闲鱼(挂售前必须先上传) |
171
+ | `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` | 提交挂售上架 |
172
+
173
+ **挂售必填参数**:`--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`(商家编码,同店铺唯一)
156
174
 
157
- | 参数 | 必填 | 说明 |
158
- |------|------|------|
159
- | `--stock-goods-id <id>` | 是 | 库存商品 ID(来自选品商品列表的 `stockGoodsId` 字段) |
160
- | `--shop-id <id>` | 是 | 第三方店铺 ID(来自店铺列表的 `shopId` 字段,不是 `id`) |
161
- | `--price <amount>` | 是 | 上架价格(正数) |
162
- | `-p, --platform <platform>` | 否 | 平台,默认 xianyu |
163
- | `--json` | 否 | JSON 输出(Agent 推荐) |
175
+ **挂售可选参数**:`--brand-name`、`--size`、`--goods-no`、`--original-price`、`--item-attrs`(属性列表 JSON)、`--trade-type`(默认 0 仅在线)、`--transport-fee`(默认 0 包邮)、`--yhb`(验货宝)、`--division-id`(默认 330100 杭州)
164
176
 
165
177
  ### 其他命令
166
178
 
package/dist/r2-cli.js CHANGED
@@ -1,47 +1,48 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- var Ue=Object.defineProperty;var Y=(e,t)=>()=>(e&&(t=e(e=0)),t);var V=(e,t)=>{for(var o in t)Ue(e,o,{get:t[o],enumerable:!0})};var Kt={};V(Kt,{UserInfoCard:()=>Ve});import{Box as Q,Text as E}from"ink";import{jsx as O,jsxs as _}from"react/jsx-runtime";function Ve({userInfo:e,lastLogin:t,daysSinceLogin:o}){let r=e.mobile?e.mobile.replace(/(\d{3})\d{4}(\d{4})/,"$1****$2"):"-";return _(Q,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[O(E,{bold:!0,color:"cyan",children:"\u7528\u6237\u4FE1\u606F"}),_(Q,{flexDirection:"row",marginTop:1,children:[O(Q,{width:10,children:O(E,{color:"gray",children:"\u6635\u79F0"})}),O(E,{color:"yellow",children:e.nickname})]}),_(Q,{flexDirection:"row",children:[O(Q,{width:10,children:O(E,{color:"gray",children:"\u624B\u673A\u53F7"})}),O(E,{color:"yellow",children:r})]}),t&&_(Q,{flexDirection:"column",marginTop:1,children:[_(E,{color:"gray",children:["\u6700\u540E\u767B\u5F55: ",t.toLocaleString()]}),o!==void 0&&_(E,{color:"gray",children:[" \u8DDD\u4ECA: ",o," \u5929"]})]})]})}var Yt=Y(()=>{"use strict"});var ot={};V(ot,{renderComponent:()=>oo,renderOnce:()=>Vt});import Ze from"react";import Tt from"chalk";import{render as to}from"ink";import{Writable as eo}from"node:stream";function Vt(e){let t=Tt.level;process.env.NO_COLOR||(Tt.level=3);try{let o=[],r=new eo({write(l,d,g){o.push(Buffer.from(l)),g()}});r.isTTY=!0,r.columns=process.stdout.columns||80,r.rows=process.stdout.rows||24,to(e,{stdout:r,patchConsole:!1}).unmount();let s=Buffer.concat(o).toString("utf8"),a=(s.split(/\x1B\[2J\x1B\[3J\x1B\[H/).at(-1)||s).replace(/\x1B\[\?[\d;]+[hl]/g,"").trimEnd()+`
4
- `;process.stdout.write(a)}finally{Tt.level=t}}function oo(e,t){Vt(Ze.createElement(e,t))}var rt=Y(()=>{"use strict"});var pe={};V(pe,{ShopsTable:()=>yo});import{Box as w,Text as C}from"ink";import{jsx as p,jsxs as M}from"react/jsx-runtime";function go(e){return e.map(t=>"shopName"in t?{id:t.shopId,name:t.shopName,platform:t.platform,expiresIn:t.expiresIn}:{id:t.id,name:t.name,platform:t.thirdUserId,expiresIn:t.expiresIn})}function fo({hasPlatform:e,fillWidth:t}){return M(w,{flexDirection:"row",paddingBottom:0,children:[e&&p(w,{width:Ut,children:p(C,{bold:!0,color:"white",children:"\u5E73\u53F0"})}),p(w,{width:t,children:p(C,{bold:!0,color:"white",children:"\u5E97\u94FA\u540D"})}),p(w,{width:Dt,children:p(C,{bold:!0,color:"white",children:"ID"})}),p(w,{width:$t,children:p(C,{bold:!0,color:"white",children:"\u72B6\u6001"})})]})}function ho({shop:e,hasPlatform:t,fillWidth:o}){let r=de[e.platform]??e.platform;return M(w,{flexDirection:"row",children:[t&&p(w,{width:Ut,children:p(C,{color:"cyan",children:r})}),p(w,{width:o,children:p(C,{bold:!0,children:e.name})}),p(w,{width:Dt,children:p(C,{color:"gray",children:e.id})}),p(w,{width:$t,children:p(C,{color:"green",children:"\u25CF \u6388\u6743\u4E2D"})})]})}function yo({shops:e,platform:t}){let o=go(e),r=t==="all",n=t==="all"?"\u6240\u6709\u6388\u6743\u5E97\u94FA":`${de[t]??t}\u6388\u6743\u5E97\u94FA`,s=process.stdout.columns||80,i=4,a=Dt+$t+(r?Ut:0),l=Math.max(s-i-a,20),d=a+l;return M(w,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[M(w,{flexDirection:"row",children:[p(C,{bold:!0,color:"cyan",children:n}),M(C,{color:"gray",children:[" \xB7 ",o.length," \u5BB6"]})]}),M(w,{flexDirection:"column",marginTop:1,children:[p(fo,{hasPlatform:r,fillWidth:l}),p(C,{color:"gray",children:"\u2500".repeat(d)}),o.map(g=>p(ho,{shop:g,hasPlatform:r,fillWidth:l},g.id))]})]})}var de,Ut,Dt,$t,ge=Y(()=>{"use strict";de={xianyu:"\u95F2\u9C7C",douyin:"\u6296\u97F3"},Ut=8,Dt=16,$t=10});var ye={};V(ye,{StocksTable:()=>Co});import{Box as h,Text as x}from"ink";import{jsx as u,jsxs as X}from"react/jsx-runtime";function xo({fillWidth:e}){return X(h,{flexDirection:"row",paddingBottom:0,children:[u(h,{width:jt,children:u(x,{bold:!0,color:"white",children:"ID"})}),u(h,{width:Gt,children:u(x,{bold:!0,color:"white",children:"\u7528\u6237ID"})}),u(h,{width:Bt,children:u(x,{bold:!0,color:"white",children:"\u4ED3\u5E93ID"})}),u(h,{width:e,children:u(x,{bold:!0,color:"white",children:"\u4ED3\u5E93\u540D\u79F0"})}),u(h,{width:Jt,children:u(x,{bold:!0,color:"white",children:"\u521B\u5EFA\u65F6\u95F4"})})]})}function So({stock:e,fillWidth:t}){let o=new Date(e.gmtCreate).toLocaleString("zh-CN");return X(h,{flexDirection:"row",children:[u(h,{width:jt,children:u(x,{color:"gray",children:e.id})}),u(h,{width:Gt,children:u(x,{color:"gray",children:e.userId})}),u(h,{width:Bt,children:u(x,{color:"gray",children:e.stockId})}),u(h,{width:t,children:u(x,{bold:!0,children:e.stockName})}),u(h,{width:Jt,children:u(x,{color:"gray",children:o})})]})}function Co({stocks:e}){let t=process.stdout.columns||80,o=4,r=jt+Gt+Bt+Jt,n=Math.max(t-o-r,20),s=r+n;return X(h,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[X(h,{flexDirection:"row",children:[u(x,{bold:!0,color:"cyan",children:"\u4ED3\u5E93\u5217\u8868"}),X(x,{color:"gray",children:[" \xB7 ",e.length," \u4E2A"]})]}),X(h,{flexDirection:"column",marginTop:1,children:[u(xo,{fillWidth:n}),u(x,{color:"gray",children:"\u2500".repeat(s)}),e.map(i=>u(So,{stock:i,fillWidth:n},i.id))]})]})}var jt,Gt,Bt,Jt,we=Y(()=>{"use strict";jt=6,Gt=10,Bt=10,Jt=22});import{Command as qo}from"commander";import{readFileSync as Qo}from"node:fs";import Re from"node:path";import z from"chalk";import"commander";import{Command as ne}from"commander";import f from"chalk";var G=class e extends Error{constructor(o,r,n){super(o);this.code=r;this.details=n;this.name="R2Error",Error.captureStackTrace&&Error.captureStackTrace(this,e)}code;details},v=class extends G{constructor(o,r,n){super(o,"API_ERROR",n);this.status=r;this.response=n;this.name="ApiError"}status;response},N=class extends G{constructor(o,r,n){super(o,"STORAGE_ERROR",{path:r,code:n});this.path=r;this.code=n;this.name="StorageError"}path;code},y=class extends G{constructor(t){super(t,"AUTH_ERROR"),this.name="AuthError"}},b=class extends G{constructor(o,r,n){super(o,"POLLING_ERROR",{attempts:r,timeout:n});this.attempts=r;this.timeout=n;this.name="PollingError"}attempts;timeout};async function De(e,t,o){let r=new AbortController,n=()=>r.abort();o?.addEventListener("abort",n,{once:!0});let s=setTimeout(()=>r.abort(),t);try{return await e()}catch(i){throw r.signal.aborted&&!o?.aborted?new b("\u5355\u6B21\u8F6E\u8BE2\u8BF7\u6C42\u8D85\u65F6"):i}finally{clearTimeout(s),o?.removeEventListener("abort",n)}}async function B(e,t,o){let{interval:r,timeout:n,condition:s}=t,i=Date.now(),a=0;for(;Date.now()-i<n;){if(o?.aborted)throw new b("\u8F6E\u8BE2\u88AB\u4E2D\u6B62");a++;let l=n-(Date.now()-i),d=await De(e,l,o);if(s(d,a))return d;await $e(r,o)}throw new b(`\u8F6E\u8BE2\u8D85\u65F6 (\u5DF2\u7B49\u5F85 ${Date.now()-i}ms, \u5171 ${a} \u6B21)`)}function $e(e,t){return new Promise((o,r)=>{if(t?.aborted){r(new b("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"));return}let n=()=>{clearTimeout(s),r(new b("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"))},s=setTimeout(()=>{t?.removeEventListener("abort",n),o()},e);t?.addEventListener("abort",n,{once:!0})})}import Be from"node:fs";import{fileURLToPath as Je}from"node:url";import{createRequire as qe}from"node:module";import Xt from"node:path";import{exec as Qe}from"node:child_process";import je from"node:http";var gt=class e{server=null;pages=new Map;port=0;idleTimer=null;static IDLE_TIMEOUT_MS=1e4;async start(){return this.server?this.port:new Promise((t,o)=>{this.server=je.createServer((r,n)=>this.handleRequest(r,n)),this.server.listen(0,"127.0.0.1",()=>{let r=this.server.address();typeof r=="object"&&r?(this.port=r.port,t(this.port)):o(new Error("Failed to get server address"))}),this.server.on("error",o)})}registerPage(t,o,r,n){let s=this.pages.get(t);if(s){s.qrBuffer=r,s.status="waiting",s.config=n;let i=`data: ${JSON.stringify({status:"waiting"})}
3
+ var _e=Object.defineProperty;var tt=(e,t)=>()=>(e&&(t=e(e=0)),t);var et=(e,t)=>{for(var n in t)_e(e,n,{get:t[n],enumerable:!0})};var ee={};et(ee,{UserInfoCard:()=>co});import{Box as _,Text as E}from"ink";import{jsx as j,jsxs as M}from"react/jsx-runtime";function co({userInfo:e,lastLogin:t,daysSinceLogin:n}){let o=e.mobile?e.mobile.replace(/(\d{3})\d{4}(\d{4})/,"$1****$2"):"-";return M(_,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[j(E,{bold:!0,color:"cyan",children:"\u7528\u6237\u4FE1\u606F"}),M(_,{flexDirection:"row",marginTop:1,children:[j(_,{width:10,children:j(E,{color:"gray",children:"\u6635\u79F0"})}),j(E,{color:"yellow",children:e.nickname})]}),M(_,{flexDirection:"row",children:[j(_,{width:10,children:j(E,{color:"gray",children:"\u624B\u673A\u53F7"})}),j(E,{color:"yellow",children:o})]}),t&&M(_,{flexDirection:"column",marginTop:1,children:[M(E,{color:"gray",children:["\u6700\u540E\u767B\u5F55: ",t.toLocaleString()]}),n!==void 0&&M(E,{color:"gray",children:[" \u8DDD\u4ECA: ",n," \u5929"]})]})]})}var oe=tt(()=>{"use strict"});var at={};et(at,{renderComponent:()=>po,renderOnce:()=>ne});import lo from"react";import kt from"chalk";import{render as uo}from"ink";import{Writable as mo}from"node:stream";function ne(e){let t=kt.level;process.env.NO_COLOR||(kt.level=3);try{let n=[],o=new mo({write(c,u,d){n.push(Buffer.from(c)),d()}});o.isTTY=!0,o.columns=process.stdout.columns||80,o.rows=process.stdout.rows||24,uo(e,{stdout:o,patchConsole:!1}).unmount();let s=Buffer.concat(n).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{kt.level=t}}function po(e,t){ne(lo.createElement(e,t))}var ct=tt(()=>{"use strict"});var Pe={};et(Pe,{ShopsTable:()=>Ro});import{Box as S,Text as A}from"ink";import{jsx as g,jsxs as z}from"react/jsx-runtime";function Ao(e){return e.map(t=>"shopName"in t?{id:t.shopId,name:t.shopName,platform:t.platform,expiresIn:t.expiresIn}:{id:t.id,name:t.name,platform:t.thirdUserId,expiresIn:t.expiresIn})}function vo({hasPlatform:e,fillWidth:t}){return z(S,{flexDirection:"row",paddingBottom:0,children:[e&&g(S,{width:qt,children:g(A,{bold:!0,color:"white",children:"\u5E73\u53F0"})}),g(S,{width:t,children:g(A,{bold:!0,color:"white",children:"\u5E97\u94FA\u540D"})}),g(S,{width:Bt,children:g(A,{bold:!0,color:"white",children:"ID"})}),g(S,{width:Gt,children:g(A,{bold:!0,color:"white",children:"\u72B6\u6001"})})]})}function ko({shop:e,hasPlatform:t,fillWidth:n}){let o=Ce[e.platform]??e.platform;return z(S,{flexDirection:"row",children:[t&&g(S,{width:qt,children:g(A,{color:"cyan",children:o})}),g(S,{width:n,children:g(A,{bold:!0,children:e.name})}),g(S,{width:Bt,children:g(A,{color:"gray",children:e.id})}),g(S,{width:Gt,children:g(A,{color:"green",children:"\u25CF \u6388\u6743\u4E2D"})})]})}function Ro({shops:e,platform:t}){let n=Ao(e),o=t==="all",r=t==="all"?"\u6240\u6709\u6388\u6743\u5E97\u94FA":`${Ce[t]??t}\u6388\u6743\u5E97\u94FA`,s=process.stdout.columns||80,i=4,a=Bt+Gt+(o?qt:0),c=Math.max(s-i-a,20),u=a+c;return z(S,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[z(S,{flexDirection:"row",children:[g(A,{bold:!0,color:"cyan",children:r}),z(A,{color:"gray",children:[" \xB7 ",n.length," \u5BB6"]})]}),z(S,{flexDirection:"column",marginTop:1,children:[g(vo,{hasPlatform:o,fillWidth:c}),g(A,{color:"gray",children:"\u2500".repeat(u)}),n.map(d=>g(ko,{shop:d,hasPlatform:o,fillWidth:c},d.id))]})]})}var Ce,qt,Bt,Gt,Te=tt(()=>{"use strict";Ce={xianyu:"\u95F2\u9C7C",douyin:"\u6296\u97F3"},qt=8,Bt=16,Gt=10});var ve={};et(ve,{StocksTable:()=>Uo});import{Box as h,Text as C}from"ink";import{jsx as m,jsxs as H}from"react/jsx-runtime";function Lo({fillWidth:e}){return H(h,{flexDirection:"row",paddingBottom:0,children:[m(h,{width:Jt,children:m(C,{bold:!0,color:"white",children:"ID"})}),m(h,{width:Xt,children:m(C,{bold:!0,color:"white",children:"\u7528\u6237ID"})}),m(h,{width:Qt,children:m(C,{bold:!0,color:"white",children:"\u4ED3\u5E93ID"})}),m(h,{width:e,children:m(C,{bold:!0,color:"white",children:"\u4ED3\u5E93\u540D\u79F0"})}),m(h,{width:_t,children:m(C,{bold:!0,color:"white",children:"\u521B\u5EFA\u65F6\u95F4"})})]})}function Oo({stock:e,fillWidth:t}){let n=new Date(e.gmtCreate).toLocaleString("zh-CN");return H(h,{flexDirection:"row",children:[m(h,{width:Jt,children:m(C,{color:"gray",children:e.id})}),m(h,{width:Xt,children:m(C,{color:"gray",children:e.userId})}),m(h,{width:Qt,children:m(C,{color:"gray",children:e.stockId})}),m(h,{width:t,children:m(C,{bold:!0,children:e.stockName})}),m(h,{width:_t,children:m(C,{color:"gray",children:n})})]})}function Uo({stocks:e}){let t=process.stdout.columns||80,n=4,o=Jt+Xt+Qt+_t,r=Math.max(t-n-o,20),s=o+r;return H(h,{flexDirection:"column",marginTop:1,borderStyle:"round",borderColor:"gray",paddingX:1,children:[H(h,{flexDirection:"row",children:[m(C,{bold:!0,color:"cyan",children:"\u4ED3\u5E93\u5217\u8868"}),H(C,{color:"gray",children:[" \xB7 ",e.length," \u4E2A"]})]}),H(h,{flexDirection:"column",marginTop:1,children:[m(Lo,{fillWidth:r}),m(C,{color:"gray",children:"\u2500".repeat(s)}),e.map(i=>m(Oo,{stock:i,fillWidth:r},i.id))]})]})}var Jt,Xt,Qt,_t,ke=tt(()=>{"use strict";Jt=6,Xt=10,Qt=10,_t=22});import{Command as tn}from"commander";import{readFileSync as en}from"node:fs";import on from"node:path";import K from"chalk";import"commander";import{Command as le}from"commander";import f from"chalk";var G=class e extends Error{constructor(n,o,r){super(n);this.code=o;this.details=r;this.name="R2Error",Error.captureStackTrace&&Error.captureStackTrace(this,e)}code;details},T=class extends G{constructor(n,o,r){super(n,"API_ERROR",r);this.status=o;this.response=r;this.name="ApiError"}status;response},D=class extends G{constructor(n,o,r){super(n,"STORAGE_ERROR",{path:o,code:r});this.path=o;this.code=r;this.name="StorageError"}path;code},x=class extends G{constructor(t){super(t,"AUTH_ERROR"),this.name="AuthError"}},L=class extends G{constructor(n,o,r){super(n,"POLLING_ERROR",{attempts:o,timeout:r});this.attempts=o;this.timeout=r;this.name="PollingError"}attempts;timeout};async function Me(e,t,n){let o=new AbortController,r=()=>o.abort();n?.addEventListener("abort",r,{once:!0});let s=setTimeout(()=>o.abort(),t);try{return await e()}catch(i){throw o.signal.aborted&&!n?.aborted?new L("\u5355\u6B21\u8F6E\u8BE2\u8BF7\u6C42\u8D85\u65F6"):i}finally{clearTimeout(s),n?.removeEventListener("abort",r)}}async function J(e,t,n){let{interval:o,timeout:r,condition:s}=t,i=Date.now(),a=0;for(;Date.now()-i<r;){if(n?.aborted)throw new L("\u8F6E\u8BE2\u88AB\u4E2D\u6B62");a++;let c=r-(Date.now()-i),u=await Me(e,c,n);if(s(u,a))return u;await Fe(o,n)}throw new L(`\u8F6E\u8BE2\u8D85\u65F6 (\u5DF2\u7B49\u5F85 ${Date.now()-i}ms, \u5171 ${a} \u6B21)`)}function Fe(e,t){return new Promise((n,o)=>{if(t?.aborted){o(new L("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"));return}let r=()=>{clearTimeout(s),o(new L("\u8F6E\u8BE2\u88AB\u4E2D\u6B62"))},s=setTimeout(()=>{t?.removeEventListener("abort",r),n()},e);t?.addEventListener("abort",r,{once:!0})})}import We from"node:fs";import{fileURLToPath as Ve}from"node:url";import{createRequire as Ke}from"node:module";import Wt from"node:path";import{exec as Ye}from"node:child_process";import ze from"node:http";var xt=class e{server=null;pages=new Map;port=0;idleTimer=null;static IDLE_TIMEOUT_MS=1e4;async start(){return this.server?this.port:new Promise((t,n)=>{this.server=ze.createServer((o,r)=>this.handleRequest(o,r)),this.server.listen(0,"127.0.0.1",()=>{let o=this.server.address();typeof o=="object"&&o?(this.port=o.port,t(this.port)):n(new Error("Failed to get server address"))}),this.server.on("error",n)})}registerPage(t,n,o,r){let s=this.pages.get(t);if(s){s.qrBuffer=o,s.status="waiting",s.config=r;let i=`data: ${JSON.stringify({status:"waiting"})}
5
5
 
6
- `;for(let a of s.sseClients)a.write(i)}else this.pages.set(t,{html:o,qrBuffer:r,status:"waiting",sseClients:[],config:n});this.resetIdleTimer()}unregisterPage(t){let o=this.pages.get(t);if(o){for(let r of o.sseClients)r.end();o.sseClients.length=0,this.pages.delete(t),this.pages.size===0&&this.close()}}setStatus(t,o){let r=this.pages.get(t);if(!r)return;r.status=o;let n=`data: ${JSON.stringify({status:o})}
6
+ `;for(let a of s.sseClients)a.write(i)}else this.pages.set(t,{html:n,qrBuffer:o,status:"waiting",sseClients:[],config:r});this.resetIdleTimer()}unregisterPage(t){let n=this.pages.get(t);if(n){for(let o of n.sseClients)o.end();n.sseClients.length=0,this.pages.delete(t),this.pages.size===0&&this.close()}}setStatus(t,n){let o=this.pages.get(t);if(!o)return;o.status=n;let r=`data: ${JSON.stringify({status:n})}
7
7
 
8
- `;for(let s of r.sseClients)s.write(n)}close(){if(this.server){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null);for(let t of this.pages.values()){for(let o of t.sseClients)o.end();t.sseClients.length=0}this.pages.clear(),this.server.close(),this.server=null,this.port=0,J=null}}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>{[...this.pages.values()].some(o=>o.sseClients.length>0)||this.close()},e.IDLE_TIMEOUT_MS)}handleRequest(t,o){let r=t.url??"/";for(let[n,s]of this.pages){if(r===n){o.writeHead(302,{Location:n+"/"}),o.end();return}if(r===n+"/"){o.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),o.end(s.html);return}if(r===n+"/qr.png"){o.writeHead(200,{"Content-Type":"image/png","Content-Length":s.qrBuffer.length}),o.end(s.qrBuffer);return}if(r===n+"/events"){o.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),o.write(`data: ${JSON.stringify({status:s.status})}
8
+ `;for(let s of o.sseClients)s.write(r)}close(){if(this.server){this.idleTimer&&(clearTimeout(this.idleTimer),this.idleTimer=null);for(let t of this.pages.values()){for(let n of t.sseClients)n.end();t.sseClients.length=0}this.pages.clear(),this.server.close(),this.server=null,this.port=0,X=null}}resetIdleTimer(){this.idleTimer&&clearTimeout(this.idleTimer),this.idleTimer=setTimeout(()=>{[...this.pages.values()].some(n=>n.sseClients.length>0)||this.close()},e.IDLE_TIMEOUT_MS)}handleRequest(t,n){let o=t.url??"/";for(let[r,s]of this.pages){if(o===r){n.writeHead(302,{Location:r+"/"}),n.end();return}if(o===r+"/"){n.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),n.end(s.html);return}if(o===r+"/qr.png"){n.writeHead(200,{"Content-Type":"image/png","Content-Length":s.qrBuffer.length}),n.end(s.qrBuffer);return}if(o===r+"/events"){n.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"}),n.write(`data: ${JSON.stringify({status:s.status})}
9
9
 
10
- `),s.sseClients.push(o),t.on("close",()=>{let i=s.sseClients.indexOf(o);i>=0&&s.sseClients.splice(i,1)});return}if(r===n+"/config"){o.writeHead(200,{"Content-Type":"application/json"}),o.end(JSON.stringify(s.config??{}));return}}o.writeHead(404,{"Content-Type":"text/plain"}),o.end("Not Found")}},J=null,_t=!1;function Z(){J&&J.close()}function Ge(){_t||(_t=!0,process.on("exit",Z),process.on("SIGINT",Z),process.on("SIGTERM",Z),setInterval(()=>{process.stdin?.destroyed&&Z()},3e3).unref())}function Mt(){return J||(J=new gt,Ge()),J}var _e=Xt.dirname(Je(import.meta.url)),Me="/login",Xe="/login-xianyu",ft=null;async function Fe(e){return Be.promises.readFile(Xt.join(_e,"pages",e),"utf-8")}async function ze(e){return ft||(ft=qe(import.meta.url)),ft("qrcode").toBuffer(e,{width:300,margin:2})}function P(e){let t=process.platform==="win32"?`start "" "${e}"`:process.platform==="darwin"?`open "${e}"`:`xdg-open "${e}"`;Qe(t)}async function Ft(e,t,o,r){let[n,s]=await Promise.all([Fe(t),ze(o)]),i=Mt(),a=await i.start();i.registerPage(e,n,s,r);let l=`http://127.0.0.1:${a}${e}/`;return{url:o,qrUrl:l,setStatus:d=>i.setStatus(e,d),closeServer:()=>i.unregisterPage(e)}}function ht(e){return Ft(Me,"login.html",e)}function yt(e,t){return Ft(Xe,"xianyu-auth.html",e,{authUrl:t})}import{promises as q}from"node:fs";import wt from"node:path";import We from"node:os";var He=".r2-cli",tt=class{configPath;config;configLoaded=!1;dirEnsured=!1;constructor(){let t=We.homedir(),o=wt.join(t,He);this.configPath=wt.join(o,"config.json"),this.config={credentials:null}}getConfigPath(){return this.configPath}async loadConfig(){if(this.configLoaded)return this.config;try{let t=await q.readFile(this.configPath,"utf-8");return this.config=JSON.parse(t),this.configLoaded=!0,this.config}catch{return this.config={credentials:null},this.configLoaded=!0,this.config}}async ensureDir(){if(this.dirEnsured)return;let t=wt.dirname(this.configPath);try{await q.stat(t)}catch(o){if(o.code==="ENOENT")await q.mkdir(t,{recursive:!0});else throw new N("Failed to create directory",t,o.code)}this.dirEnsured=!0}async saveConfig(t){this.config=t,await this.ensureDir();let o=JSON.stringify(t,null,2),r=this.configPath+".tmp";try{await q.writeFile(r,o,"utf-8"),await q.rename(r,this.configPath),this.configLoaded=!0}catch(n){throw await q.unlink(r).catch(s=>{typeof process.env.DEBUG<"u"&&console.error("[config] cleanup tmp failed:",s)}),new N("Failed to save config",this.configPath,n.code)}}},xt=null;function St(){return xt||(xt=new tt),xt}var It=300*1e3,et=class{store=St();isTokenExpired(t){return t.expire?Date.now()>=t.expire-It:!1}async saveCredentials(t,o){let r=Date.now(),n=o.expire?Number.parseInt(o.expire,10):0,s={token:t,userInfo:o,timestamp:r,...n>0&&{expire:r+n}},i=await this.store.loadConfig();i.credentials=s,await this.store.saveConfig(i)}async getCredentials(){let t=await this.store.loadConfig();return!t.credentials||this.isTokenExpired(t.credentials)?null:t.credentials}async clearCredentials(){let t=await this.store.loadConfig();t.credentials=null,await this.store.saveConfig(t)}async getToken(){return(await this.getCredentials())?.token??null}async getUserInfo(){return(await this.getCredentials())?.userInfo??null}async isLoggedIn(){return await this.getCredentials()!==null}},Ct=null;function W(){return Ct||(Ct=new et),Ct}var Ke="https://api.puresnake.com",A=class{config;authStorage=null;cachedToken=null;tokenExpiry=0;constructor(t={}){this.config={baseUrl:t.baseUrl??Ke,version:t.version??"v3",debug:t.debug??!1},this.authStorage=t.auth===!1?null:W()}buildUrl(t){let o=t.startsWith("/")?t.slice(1):t;return`${this.config.baseUrl}/${this.config.version}/${o}`}async getAuthToken(){if(!this.authStorage)return;if(this.cachedToken&&Date.now()<this.tokenExpiry)return this.cachedToken;let t=await this.authStorage.getCredentials();if(!t)throw new y("\u8BF7\u5148\u8FD0\u884C r2-cli auth login \u767B\u5F55");return this.cachedToken=t.token,this.tokenExpiry=t.expire?t.expire-It:Date.now()+1800*1e3,t.token}async requestFull(t,o){let r=this.buildUrl(t),{method:n,headers:s,body:i,timeout:a=3e4}=o,l=await this.getAuthToken(),d={...s,...l?{token:l}:{}},g=new AbortController,$=setTimeout(()=>g.abort(),a),K={method:n,headers:{"Content-Type":"application/json",...d},signal:g.signal};i!==void 0&&(K.body=JSON.stringify(i)),this.config.debug&&console.error(`[API ${n}]`,r,i);try{let c=await fetch(r,K);if(!c.ok){if(c.status===401)throw this.authStorage&&(this.cachedToken=null,await this.authStorage.clearCredentials().catch(j=>{console.error("[API] \u6E05\u9664\u51ED\u8BC1\u5931\u8D25:",j instanceof Error?j.message:String(j))})),new y("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");let dt=await c.text();throw new v(dt||`${c.status} ${c.statusText}`,c.status)}let S=await c.json();if(this.config.debug&&console.error("[API Response]",S),!S.success||S.status!==0)throw new v(S.msg||"\u672A\u77E5\u9519\u8BEF",S.status,S);return S}catch(c){throw c instanceof DOMException&&c.name==="AbortError"?new v(`\u8BF7\u6C42\u8D85\u65F6 (${a}ms)`,408):c}finally{clearTimeout($)}}async request(t,o){return(await this.requestFull(t,o)).data}async get(t,o,r){let n=o&&o.size>0?`${t}?${o.toString()}`:t;return this.request(n,{method:"GET",headers:r})}async post(t,o,r){return this.request(t,{method:"POST",body:o,headers:r})}async put(t,o,r){return this.request(t,{method:"PUT",body:o,headers:r})}async delete(t,o){return this.request(t,{method:"DELETE",headers:o})}};var zt=new A({auth:!1});async function Wt(){return zt.post("app/qrcode/generate")}async function Ht(e){let t=new URLSearchParams;t.append("qrToken",e);let o=`app/qrcode/status?${t.toString()}`,r=await zt.requestFull(o,{method:"GET"});return r.token&&typeof r.data=="object"&&r.data!==null&&(r.data.token=r.token),r.data}async function Zt(e,t,o){let{UserInfoCard:r}=await Promise.resolve().then(()=>(Yt(),Kt)),{renderComponent:n}=await Promise.resolve().then(()=>(rt(),ot)),s=t!=null?{userInfo:e,lastLogin:t,daysSinceLogin:o??0}:{userInfo:e};n(r,s)}var nt=class{storage;constructor(t){this.storage=t??W()}async generateQR(){let t=await Wt(),o=`https://m.puresnake.com/r2/auth/login?qrToken=${t.qrContent}&from=wechat`,r=await ht(o);return{qrData:t,...r}}async waitForLogin(t,o,r,n,s,i){let a=await B(()=>Ht(t),{interval:r,timeout:o,condition:l=>{switch(l.status){case"scanned":return i||(console.log(f.cyan(`
11
- \u{1F50D} \u5DF2\u626B\u7801: ${l.userInfo?.nickname||"\u672A\u77E5\u7528\u6237"}`)),console.log(f.yellow("\u8BF7\u5728 APP \u4E0A\u786E\u8BA4\u767B\u5F55"))),s?.("scanning"),!1;case"confirmed":return i||console.log(f.green(`
10
+ `),s.sseClients.push(n),t.on("close",()=>{let i=s.sseClients.indexOf(n);i>=0&&s.sseClients.splice(i,1)});return}if(o===r+"/config"){n.writeHead(200,{"Content-Type":"application/json"}),n.end(JSON.stringify(s.config??{}));return}}n.writeHead(404,{"Content-Type":"text/plain"}),n.end("Not Found")}},X=null,zt=!1;function ot(){X&&X.close()}function He(){zt||(zt=!0,process.on("exit",ot),process.on("SIGINT",ot),process.on("SIGTERM",ot),setInterval(()=>{process.stdin?.destroyed&&ot()},3e3).unref())}function Ht(){return X||(X=new xt,He()),X}var Ze=Wt.dirname(Ve(import.meta.url)),to="/login",eo="/login-xianyu",It=null;async function oo(e){return We.promises.readFile(Wt.join(Ze,"pages",e),"utf-8")}async function no(e){return It||(It=Ke(import.meta.url)),It("qrcode").toBuffer(e,{width:300,margin:2})}function R(e){let t=process.platform==="win32"?`start "" "${e}"`:process.platform==="darwin"?`open "${e}"`:`xdg-open "${e}"`;Ye(t)}async function Vt(e,t,n,o){let[r,s]=await Promise.all([oo(t),no(n)]),i=Ht(),a=await i.start();i.registerPage(e,r,s,o);let c=`http://127.0.0.1:${a}${e}/`;return{url:n,qrUrl:c,setStatus:u=>i.setStatus(e,u),closeServer:()=>i.unregisterPage(e)}}function St(e){return Vt(to,"login.html",e)}function Ct(e,t){return Vt(eo,"xianyu-auth.html",e,{authUrl:t})}import{promises as Q}from"node:fs";import Pt from"node:path";import ro from"node:os";var so=".r2-cli",nt=class{configPath;config;configLoaded=!1;dirEnsured=!1;constructor(){let t=ro.homedir(),n=Pt.join(t,so);this.configPath=Pt.join(n,"config.json"),this.config={credentials:null}}getConfigPath(){return this.configPath}async loadConfig(){if(this.configLoaded)return this.config;try{let t=await Q.readFile(this.configPath,"utf-8");return this.config=JSON.parse(t),this.configLoaded=!0,this.config}catch{return this.config={credentials:null},this.configLoaded=!0,this.config}}async ensureDir(){if(this.dirEnsured)return;let t=Pt.dirname(this.configPath);try{await Q.stat(t)}catch(n){if(n.code==="ENOENT")await Q.mkdir(t,{recursive:!0});else throw new D("Failed to create directory",t,n.code)}this.dirEnsured=!0}async saveConfig(t){this.config=t,await this.ensureDir();let n=JSON.stringify(t,null,2),o=this.configPath+".tmp";try{await Q.writeFile(o,n,"utf-8"),await Q.rename(o,this.configPath),this.configLoaded=!0}catch(r){throw await Q.unlink(o).catch(s=>{typeof process.env.DEBUG<"u"&&console.error("[config] cleanup tmp failed:",s)}),new D("Failed to save config",this.configPath,r.code)}}},Tt=null;function bt(){return Tt||(Tt=new nt),Tt}var vt=300*1e3,rt=class{store=bt();isTokenExpired(t){return t.expire?Date.now()>=t.expire-vt:!1}async saveCredentials(t,n){let o=Date.now(),r=n.expire?Number.parseInt(n.expire,10):0,s={token:t,userInfo:n,timestamp:o,...r>0&&{expire:o+r}},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}},At=null;function Y(){return At||(At=new rt),At}var io="https://api.puresnake.com",st=class{config;authStorage=null;cachedToken=null;tokenExpiry=0;constructor(t={}){this.config={baseUrl:t.baseUrl??io,version:t.version??"v3",debug:t.debug??!1},this.authStorage=t.auth===!1?null:Y()}buildUrl(t){let n=t.startsWith("/")?t.slice(1):t;return`${this.config.baseUrl}/${this.config.version}/${n}`}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 x("\u8BF7\u5148\u8FD0\u884C r2-cli auth login \u767B\u5F55");return this.cachedToken=t.token,this.tokenExpiry=t.expire?t.expire-vt:Date.now()+1800*1e3,t.token}async requestFull(t,n){let o=this.buildUrl(t),{method:r,headers:s,body:i,timeout:a=3e4}=n,c=await this.getAuthToken(),u={...s,...c?{token:c}:{}},d=new AbortController,w=setTimeout(()=>d.abort(),a),q={method:r,headers:{"Content-Type":"application/json",...u},signal:d.signal};i!==void 0&&(q.body=JSON.stringify(i)),this.config.debug&&console.error(`[API ${r}]`,o,i);try{let l=await fetch(o,q);if(!l.ok){if(l.status===401)throw this.authStorage&&(this.cachedToken=null,await this.authStorage.clearCredentials().catch(B=>{console.error("[API] \u6E05\u9664\u51ED\u8BC1\u5931\u8D25:",B instanceof Error?B.message:String(B))})),new x("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");let yt=await l.text();throw new T(yt||`${l.status} ${l.statusText}`,l.status)}let P=await l.json();if(this.config.debug&&console.error("[API Response]",P),!P.success||P.status!==0)throw new T(P.msg||"\u672A\u77E5\u9519\u8BEF",P.status,P);return P}catch(l){throw l instanceof DOMException&&l.name==="AbortError"?new T(`\u8BF7\u6C42\u8D85\u65F6 (${a}ms)`,408):l}finally{clearTimeout(w)}}async request(t,n){return(await this.requestFull(t,n)).data}async get(t,n,o){let r=n&&n.size>0?`${t}?${n.toString()}`:t;return this.request(r,{method:"GET",headers:o})}async post(t,n,o){return this.request(t,{method:"POST",body:n,headers:o})}async put(t,n,o){return this.request(t,{method:"PUT",body:n,headers:o})}async delete(t,n){return this.request(t,{method:"DELETE",headers:n})}async upload(t,n,o){let r=this.buildUrl(t),s=await this.getAuthToken(),i={...o,...s?{token:s}:{}},a=new AbortController,c=setTimeout(()=>a.abort(),6e4),u={method:"POST",headers:i,body:n,signal:a.signal};this.config.debug&&console.error("[API UPLOAD]",r);try{let d=await fetch(r,u);if(!d.ok){if(d.status===401)throw this.authStorage&&(this.cachedToken=null,await this.authStorage.clearCredentials().catch(()=>{})),new x("\u767B\u5F55\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u8FD0\u884C r2-cli auth login \u91CD\u65B0\u767B\u5F55");let q=await d.text();throw new T(q||`${d.status} ${d.statusText}`,d.status)}let w=await d.json();if(this.config.debug&&console.error("[API Response]",w),!w.success||w.status!==0)throw new T(w.msg||"\u672A\u77E5\u9519\u8BEF",w.status,w);return w.data}catch(d){throw d instanceof DOMException&&d.name==="AbortError"?new T("\u4E0A\u4F20\u8D85\u65F6 (60000ms)",408):d}finally{clearTimeout(c)}}},it=new st,Kt=new st({auth:!1});var Yt=Kt;async function Zt(){return Yt.post("app/qrcode/generate")}async function te(e){let t=new URLSearchParams;t.append("qrToken",e);let n=`app/qrcode/status?${t.toString()}`,o=await Yt.requestFull(n,{method:"GET"});return o.token&&typeof o.data=="object"&&o.data!==null&&(o.data.token=o.token),o.data}async function re(e,t,n){let{UserInfoCard:o}=await Promise.resolve().then(()=>(oe(),ee)),{renderComponent:r}=await Promise.resolve().then(()=>(ct(),at)),s=t!=null?{userInfo:e,lastLogin:t,daysSinceLogin:n??0}:{userInfo:e};r(o,s)}var lt=class{storage;constructor(t){this.storage=t??Y()}async generateQR(){let t=await Zt(),n=`https://m.puresnake.com/r2/auth/login?qrToken=${t.qrContent}&from=wechat`,o=await St(n);return{qrData:t,...o}}async waitForLogin(t,n,o,r,s,i){let a=await J(()=>te(t),{interval:o,timeout:n,condition:c=>{switch(c.status){case"scanned":return i||(console.log(f.cyan(`
11
+ \u{1F50D} \u5DF2\u626B\u7801: ${c.userInfo?.nickname||"\u672A\u77E5\u7528\u6237"}`)),console.log(f.yellow("\u8BF7\u5728 APP \u4E0A\u786E\u8BA4\u767B\u5F55"))),s?.("scanning"),!1;case"confirmed":return i||console.log(f.green(`
12
12
  \u2705 \u7528\u6237\u5DF2\u786E\u8BA4\u767B\u5F55`)),s?.("success"),!0;case"expired":return i||console.log(f.red(`
13
13
  \u23F0 \u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F`)),s?.("expired"),!0;case"canceled":return i||console.log(f.red(`
14
- \u{1F6AB} \u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55`)),s?.("expired"),!0;default:return!1}}},n??void 0);if(a.status==="confirmed"&&a.token&&a.userInfo)return await this.storage.saveCredentials(a.token,a.userInfo),{userInfo:a.userInfo,token:a.token};throw a.status==="expired"?new y("\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55"):a.status==="canceled"?new y("\u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55"):new y("\u767B\u5F55\u5931\u8D25: \u672A\u83B7\u53D6\u5230\u51ED\u8BC1")}async login(t){console.log(f.cyan(`
15
- \u{1F510} \u6B63\u5728\u542F\u52A8\u626B\u7801\u767B\u5F55...`));let{qrData:o,qrUrl:r,setStatus:n,closeServer:s}=await this.generateQR();console.log(f.green(`\u2705 \u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
16
- `)),console.log(f.cyan(` \u94FE\u63A5: ${r}
17
- `)),P(r),console.log(f.yellow(`\u23F3 \u7B49\u5F85\u626B\u7801...
18
- `));let i=Number.parseInt(o.expireTime,10),a=Number.parseInt(o.pollInterval,10);try{let l=await this.waitForLogin(o.qrToken,i,a,t,n);return console.log(f.green(`
14
+ \u{1F6AB} \u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55`)),s?.("expired"),!0;default:return!1}}},r??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 x("\u4E8C\u7EF4\u7801\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55"):a.status==="canceled"?new x("\u7528\u6237\u5DF2\u53D6\u6D88\u767B\u5F55"):new x("\u767B\u5F55\u5931\u8D25: \u672A\u83B7\u53D6\u5230\u51ED\u8BC1")}async login(t){console.log(f.cyan(`
15
+ \u{1F510} \u6B63\u5728\u542F\u52A8\u626B\u7801\u767B\u5F55...`));let{qrData:n,qrUrl:o,setStatus:r,closeServer:s}=await this.generateQR();console.log(f.green(`\u2705 \u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
16
+ `)),console.log(f.cyan(` \u94FE\u63A5: ${o}
17
+ `)),R(o),console.log(f.yellow(`\u23F3 \u7B49\u5F85\u626B\u7801...
18
+ `));let i=Number.parseInt(n.expireTime,10),a=Number.parseInt(n.pollInterval,10);try{let c=await this.waitForLogin(n.qrToken,i,a,t,r);return console.log(f.green(`
19
19
  \u2705 \u767B\u5F55\u6210\u529F\uFF01
20
- `)),Zt(l.userInfo),l}catch(l){throw console.log(f.red(`
20
+ `)),re(c.userInfo),c}catch(c){throw console.log(f.red(`
21
21
  \u274C \u767B\u5F55\u5931\u8D25
22
- `)),l}finally{s()}}async logout(){console.log(f.cyan(`
22
+ `)),c}finally{s()}}async logout(){console.log(f.cyan(`
23
23
  \u{1F6AA} \u6B63\u5728\u9000\u51FA\u767B\u5F55...`)),await this.storage.clearCredentials(),console.log(f.green(`\u2705 \u5DF2\u9000\u51FA\u767B\u5F55
24
24
  `))}async status(){if(!await this.storage.isLoggedIn()){console.log(f.yellow(`\u26A0\uFE0F \u5C1A\u672A\u767B\u5F55\u6216\u51ED\u8BC1\u5DF2\u8FC7\u671F
25
- `));return}let o=await this.storage.getCredentials(),r=o.userInfo,n=new Date(o.timestamp),s=Math.floor((Date.now()-o.timestamp)/(1e3*60*60*24));console.log(f.green(`\u2705 \u5DF2\u767B\u5F55
26
- `)),await Zt(r,n,s)}},Pt=null;function k(){return Pt||(Pt=new nt),Pt}import U from"chalk";var te=new A;async function ee(){return te.get("mms/xianyu/auth/url")}async function oe(e){let t=new URLSearchParams({state:e});return te.get("mms/xianyu/auth/status",t)}async function st(){let e=await ee(),t=await yt(e.url,e.url);return{authData:e,...t}}async function H(e,t,o,r,n){return B(()=>oe(e),{interval:o,timeout:t,condition:s=>s.status==="success"?(console.log(U.green(`
27
- \u2705 \u6388\u6743\u6210\u529F\uFF01\u5E97\u94FA: ${s.shopName} (${s.shopId})`)),n?.("success"),!0):s.status==="expired"?(console.log(U.red(`
28
- \u23F0 \u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F`)),n?.("expired"),!0):!1},r)}async function kt(e){console.log(U.cyan(`
29
- \u{1F517} \u6B63\u5728\u83B7\u53D6\u95F2\u9C7C\u6388\u6743\u5730\u5740...`));let{authData:t,qrUrl:o,setStatus:r,closeServer:n}=await st();console.log(U.green(`\u2705 \u6388\u6743\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
30
- `)),console.log(U.cyan(` \u94FE\u63A5: ${o}`)),console.log(U.gray(` \u6216\u590D\u5236\u94FE\u63A5\u6253\u5F00: ${t.url}`)),P(o),console.log(U.yellow(`
25
+ `));return}let n=await this.storage.getCredentials(),o=n.userInfo,r=new Date(n.timestamp),s=Math.floor((Date.now()-n.timestamp)/(1e3*60*60*24));console.log(f.green(`\u2705 \u5DF2\u767B\u5F55
26
+ `)),await re(o,r,s)}},Rt=null;function N(){return Rt||(Rt=new lt),Rt}import $ from"chalk";var se=it;async function ie(){return se.get("mms/xianyu/auth/url")}async function ae(e){let t=new URLSearchParams({state:e});return se.get("mms/xianyu/auth/status",t)}async function dt(){let e=await ie(),t=await Ct(e.url,e.url);return{authData:e,...t}}async function Z(e,t,n,o,r){return J(()=>ae(e),{interval:n,timeout:t,condition:s=>s.status==="success"?(console.log($.green(`
27
+ \u2705 \u6388\u6743\u6210\u529F\uFF01\u5E97\u94FA: ${s.shopName} (${s.shopId})`)),r?.("success"),!0):s.status==="expired"?(console.log($.red(`
28
+ \u23F0 \u6388\u6743\u94FE\u63A5\u5DF2\u8FC7\u671F`)),r?.("expired"),!0):!1},o)}async function Nt(e){console.log($.cyan(`
29
+ \u{1F517} \u6B63\u5728\u83B7\u53D6\u95F2\u9C7C\u6388\u6743\u5730\u5740...`));let{authData:t,qrUrl:n,setStatus:o,closeServer:r}=await dt();console.log($.green(`\u2705 \u6388\u6743\u4E8C\u7EF4\u7801\u5DF2\u751F\u6210
30
+ `)),console.log($.cyan(` \u94FE\u63A5: ${n}`)),console.log($.gray(` \u6216\u590D\u5236\u94FE\u63A5\u6253\u5F00: ${t.url}`)),R(n),console.log($.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 H(t.state,s,i,e,r);if(a.status==="success")return a;throw new y("\u95F2\u9C7C\u6388\u6743\u5931\u8D25: "+(a.status==="expired"?"\u94FE\u63A5\u5DF2\u8FC7\u671F":"\u672A\u77E5\u72B6\u6001"))}finally{n()}}import L from"chalk";function m(e){if(e instanceof y)console.error(L.red(`
33
- \u25B2 ${e.message}`)),console.error(L.gray(`\u2192 \u8BF7\u5148\u8FD0\u884C: r2-cli auth login
34
- `));else if(e instanceof v)console.error(L.red(`\u25B2 \u64CD\u4F5C\u5931\u8D25: ${e.message}`)),e.status&&console.error(L.gray(` \u72B6\u6001\u7801: ${e.status}`));else if(e instanceof N)console.error(L.red(`\u25B2 \u914D\u7F6E\u6587\u4EF6\u5F02\u5E38: ${e.message}`)),e.path&&console.error(L.gray(` \u8DEF\u5F84: ${e.path}`)),console.error(L.gray(`\u2192 \u8BF7\u5C1D\u8BD5\u91CD\u65B0\u767B\u5F55: r2-cli auth login
35
- `));else{let t=e instanceof Error?e.message:String(e);console.error(L.red(`\u25B2 ${t}`))}process.exit(1)}function vt(e){console.log(JSON.stringify({success:!1,error:e})),process.exit(1)}function it(e){return async(...t)=>{try{await e(...t)}catch(o){let r=o instanceof Error?o.message:String(o);vt(r)}}}var no=new Set(["accessToken","refreshExpireIn"]);function re(e){return e.map(t=>{let o={};for(let[r,n]of Object.entries(t))no.has(r)||(o[r]=n);return o})}function bt(){let e=new ne("login");e.description("\u626B\u7801\u767B\u5F55 Round2AI \u8D26\u6237").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new ne("poll").description("\u8F6E\u8BE2\u767B\u5F55\u72B6\u6001\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").requiredOption("--token <qrToken>","\u4E8C\u7EF4\u7801 token").option("--expire <ms>","\u8FC7\u671F\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09","300000").option("--interval <ms>","\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09","1000").action(it(async o=>{let n=await k().waitForLogin(o.token,Number.parseInt(o.expire,10),Number.parseInt(o.interval,10));console.log(JSON.stringify({success:!0,...n}))}));return e.addCommand(t),e.action(async o=>{try{if(o.json){let r=k(),{qrData:n,qrUrl:s,setStatus:i,closeServer:a}=await r.generateQR(),l=Number.parseInt(n.expireTime,10),d=Number.parseInt(n.pollInterval,10);console.log(JSON.stringify({qrToken:n.qrToken,expireTimeMs:l,pollIntervalMs:d,url:`https://m.puresnake.com/r2/auth/login?qrToken=${n.qrContent}&from=wechat`,qrUrl:s},null,2)),P(s);try{let g=await r.waitForLogin(n.qrToken,l,d,void 0,i,!0);console.log(JSON.stringify({success:!0,userInfo:g.userInfo}))}catch(g){let $=g instanceof Error?g.message:String(g);console.log(JSON.stringify({success:!1,error:$}))}finally{setTimeout(a,1e3)}}else await k().login()}catch(r){if(o.json){let n=r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:n})),process.exit(1)}m(r)}}),e}import{Command as so}from"commander";function At(){let e=new so("logout");return e.description("\u9000\u51FA\u767B\u5F55"),e.action(async()=>{try{await k().logout()}catch(t){m(t)}}),e}import{Command as io}from"commander";function Lt(){let e=new io("status");return e.description("\u67E5\u770B\u767B\u5F55\u72B6\u6001"),e.action(async()=>{try{await k().status()}catch(t){m(t)}}),e}import{Command as se}from"commander";function Rt(){let e=new se("xianyu");e.description("\u95F2\u9C7C\u5E97\u94FA\u6388\u6743").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new se("poll").description("\u8F6E\u8BE2\u95F2\u9C7C\u6388\u6743\u72B6\u6001\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09").requiredOption("--state <state>","\u6388\u6743\u8F6E\u8BE2 token").option("--expire <ms>","\u8FC7\u671F\u65F6\u95F4\uFF08\u6BEB\u79D2\uFF09","300000").option("--interval <ms>","\u8F6E\u8BE2\u95F4\u9694\uFF08\u6BEB\u79D2\uFF09","1000").action(it(async o=>{let r=await H(o.state,Number.parseInt(o.expire,10),Number.parseInt(o.interval,10));r.status==="success"?console.log(JSON.stringify({success:!0,shopId:r.shopId,shopName:r.shopName})):vt(`\u6388\u6743\u72B6\u6001: ${r.status}`)}));return e.addCommand(t),e.action(async o=>{try{if(o.json){let{authData:r,qrUrl:n,setStatus:s,closeServer:i}=await st(),a=r.expireTime?Number.parseInt(r.expireTime,10):3e5,l=r.pollInterval?Number.parseInt(r.pollInterval,10):1e3;console.log(JSON.stringify({state:r.state,expireTimeMs:a,pollIntervalMs:l,qrUrl:n},null,2)),P(n);try{let d=await H(r.state,a,l,void 0,s);d.status==="success"?console.log(JSON.stringify({success:!0,shopId:d.shopId,shopName:d.shopName})):(console.log(JSON.stringify({success:!1,error:`\u6388\u6743\u72B6\u6001: ${d.status}`})),process.exit(1))}catch(d){let g=d instanceof Error?d.message:String(d);console.log(JSON.stringify({success:!1,error:g})),process.exit(1)}finally{setTimeout(i,1e3)}}else await kt()}catch(r){if(o.json){let n=r instanceof Error?r.message:String(r);console.log(JSON.stringify({success:!1,error:n})),process.exit(1)}m(r)}}),e}import{Command as Lo}from"commander";import{Command as ao}from"commander";import I from"chalk";import{select as Ot,input as co,confirm as lo}from"@inquirer/prompts";var R=new A;function Nt(e){let t=new URLSearchParams;for(let[o,r]of Object.entries(e))r!=null&&r!==""&&t.append(o,String(r));return t}async function Et(e){return R.post("mms/goods/listing/up/xianyu",e)}async function ie(e){return R.get("mms/goods/listing/get",Nt({...e}))}async function ae(e){return R.post("mms/goods/listing/down/xianyu",e)}async function ce(e){return R.post("mms/goods/listing/update/xyPrice",e)}async function le(e){return R.get("mms/goods/listing/list",e?Nt({...e}):void 0)}async function at(){return await R.get("mms/user/shop/list")??[]}async function ct(){return await R.get("mms/user/stock/list")??[]}async function lt(e){let t=e?Nt({...e}):void 0;return R.get("mms/seller/goods/select/list",t)}var mo=2e3,uo=1e4;function po(e){let t=e.status?.toLowerCase()??"";return t===""||t==="init"||t==="pending"||t==="processing"}async function me(e,t,o,r){r||process.stdout.write(I.cyan("\u23F3 \u6B63\u5728\u67E5\u8BE2\u4E0A\u67B6\u8FDB\u5EA6..."));let n=await B(()=>ie({stockGoodsId:e,shopId:t,platform:o}),{interval:mo,timeout:uo,condition:s=>!po(s)});return r||process.stdout.write("\r"+" ".repeat(30)+"\r"),n}function ue(){let e=new ao("up");return e.description("\u4E0A\u67B6\u5546\u54C1\u5230\u95F2\u9C7C"),e.option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1ID\uFF08\u4ECE goods list \u83B7\u53D6\uFF09").option("--shop-id <id>","\u5E97\u94FAID\uFF08\u4ECE goods shops \u83B7\u53D6\uFF09").option("--price <amount>","\u4E0A\u67B6\u4EF7\u683C").option("-p, --platform <platform>","\u5E73\u53F0","xianyu").option("--json","\u8F93\u51FA JSON\uFF08Agent \u7528\uFF09").action(async t=>{try{if(t.stockGoodsId&&t.shopId&&t.price){let c=Number(t.stockGoodsId),S=t.shopId,dt=Number(t.price),j=t.platform,Ee=await Et({stockGoodsId:c,shopId:S,price:dt,platform:j}),pt=await me(c,S,j,t.json);if(t.json)console.log(JSON.stringify({success:!0,data:{submit:Ee,listing:pt}},null,2));else{let Oe=pt.status?.toLowerCase()!=="failed";console.log(Oe?I.green("\u2713 \u4E0A\u67B6\u6210\u529F"):I.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(pt,null,2))}return}let o=await at();if(o.length===0){console.log(I.yellow("\u6CA1\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF0C\u8BF7\u5148\u8FD0\u884C r2-cli auth xianyu \u6388\u6743"));return}let r=await Ot({message:"\u9009\u62E9\u5E97\u94FA",choices:o.map(c=>({name:`${c.shopName} (${c.platform})`,value:c.shopId}))}),n=await ct();if(n.length===0){console.log(I.yellow("\u6CA1\u6709\u53EF\u7528\u7684\u4ED3\u5E93"));return}let s=await Ot({message:"\u9009\u62E9\u4ED3\u5E93",choices:n.map(c=>({name:c.stockName,value:c.stockId}))}),i=await lt({stockId:s,size:100});if(!i.items?.length){console.log(I.yellow("\u8BE5\u4ED3\u5E93\u6CA1\u6709\u53EF\u9009\u7684\u5546\u54C1"));return}let a=await Ot({message:"\u9009\u62E9\u5546\u54C1",choices:i.items.map(c=>({name:`${c.goodsName} ${c.size?`| ${c.size}`:""} | \xA5${c.salePrice}`,value:c.stockGoodsId}))}),l=await co({message:"\u8F93\u5165\u4E0A\u67B6\u4EF7\u683C",default:i.items.find(c=>c.stockGoodsId===a)?.salePrice?.toString()??"",validate:c=>Number(c)>0?!0:"\u4EF7\u683C\u5FC5\u987B\u4E3A\u6B63\u6570"});if(!await lo({message:`\u786E\u8BA4\u4E0A\u67B6\uFF1F\u4EF7\u683C \xA5${l}`,default:!0})){console.log(I.gray("\u5DF2\u53D6\u6D88"));return}let g=Number(a);await Et({stockGoodsId:g,shopId:r,price:Number(l),platform:"xianyu"}),console.log(I.green("\u2713 \u4E0A\u67B6\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u67E5\u8BE2\u8FDB\u5EA6..."));let $=await me(g,r,"xianyu"),K=$.status?.toLowerCase()!=="failed";console.log(K?I.green("\u2713 \u4E0A\u67B6\u6210\u529F"):I.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify($,null,2))}catch(o){m(o)}}),e}import{Command as wo}from"commander";import fe from"chalk";function he(){let e=new wo("shops");return e.description("\u67E5\u770B\u6240\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF08\u8DE8\u5E73\u53F0\uFF09"),e.option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{let o=await at();if(t.json){console.log(JSON.stringify(re(o),null,2));return}if(!o.length){console.log(fe.yellow("\u672A\u627E\u5230\u5DF2\u6388\u6743\u7684\u5E97\u94FA")),console.log(fe.gray(" \u63D0\u793A: \u8BF7\u5148\u5728\u7B2C\u4E8C\u56DE\u5408 APP \u4E2D\u6388\u6743\u5E97\u94FA"));return}let{ShopsTable:r}=await Promise.resolve().then(()=>(ge(),pe)),{renderComponent:n}=await Promise.resolve().then(()=>(rt(),ot));n(r,{shops:o,platform:"all"})}catch(o){m(o)}}),e}import{Command as Io}from"commander";import To from"chalk";function xe(){let e=new Io("stocks");return e.description("\u67E5\u770B\u6240\u6709\u4ED3\u5E93"),e.option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{let o=await ct();if(t.json){console.log(JSON.stringify(o,null,2));return}if(!o.length){console.log(To.yellow("\u672A\u627E\u5230\u4ED3\u5E93\u4FE1\u606F"));return}let{StocksTable:r}=await Promise.resolve().then(()=>(we(),ye)),{renderComponent:n}=await Promise.resolve().then(()=>(rt(),ot));n(r,{stocks:o})}catch(o){m(o)}}),e}import{Command as Po}from"commander";import F from"chalk";function Se(){let e=new Po("list");return e.description("\u67E5\u770B\u4ED3\u5E93\u4E2D\u7684\u9009\u54C1\u5546\u54C1"),e.option("--stock-id <id>","\u4ED3\u5E93 ID\uFF08\u4ECE goods stocks \u83B7\u53D6\uFF09").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--page <n>","\u9875\u7801","1").option("--size <n>","\u6BCF\u9875\u6570\u91CF","20").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{let r=await lt({stockId:t.stockId||void 0,stockGoodsId:t.stockGoodsId||void 0,page:Number(t.page)||1,size:Number(t.size)||20})??{items:[],total:0};if(t.json){r.items?.length?console.log(JSON.stringify(r,null,2)):console.log(JSON.stringify({...r,hint:"\u9009\u54C1\u5546\u54C1\u4E3A\u7A7A\uFF0C\u8BF7\u5148\u5728\u540E\u53F0\u751F\u6210\u9009\u54C1\u8868\u6570\u636E\u540E\u518D\u8BD5"},null,2));return}if(!r.items?.length){console.log(F.yellow("\u6682\u65E0\u9009\u54C1\u5546\u54C1\uFF0C\u8BF7\u5148\u7ED1\u5B9A\u4ED3\u5E93\u6216\u5728\u540E\u53F0\u751F\u6210\u9009\u54C1\u8868\u6570\u636E"));return}console.log(F.cyan(`
36
- \u9009\u54C1\u5546\u54C1\uFF08\u5171 ${r.total} \u4EF6\uFF0C\u7B2C ${r.page} \u9875\uFF09
37
- `));for(let n of r.items)console.log(` ${F.bold(n.goodsName)} ${n.size?F.gray(`| ${n.size}`):""}`),console.log(` \u54C1\u724C: ${n.brand} \u5EFA\u8BAE\u552E\u4EF7: \xA5${n.salePrice} stockGoodsId: ${F.green(n.stockGoodsId)}`),console.log(F.gray(` \u5206\u7C7B: ${n.cate1Name} > ${n.cate2Name} > ${n.cate3Name}`)),console.log()}catch(o){if(t.json){let r=o instanceof Error?o.message:String(o);console.log(JSON.stringify({success:!1,error:r})),process.exit(1)}m(o)}}),e}import{Command as ko}from"commander";import Ce from"chalk";var vo={init:"\u5F85\u4E0A\u67B6",up:"\u5DF2\u4E0A\u67B6",down:"\u5DF2\u4E0B\u67B6",fail:"\u5931\u8D25"};function Ie(){let e=new ko("listing");return e.description("\u67E5\u8BE2\u4E0A\u67B6\u5546\u54C1\u5217\u8868"),e.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--stock-id <id>","\u4ED3\u5E93 ID").option("-s, --status <status>","\u72B6\u6001\u8FC7\u6EE4\uFF08init/up/down/fail\uFF09").option("-p, --platform <platform>","\u5E73\u53F0","xianyu").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{let r=await le({id:t.id,stockGoodsId:t.stockGoodsId?Number(t.stockGoodsId):void 0,shopId:t.shopId,stockId:t.stockId,status:t.status,platform:t.platform})??{list:[],total:0};if(t.json){r.list?.length?console.log(JSON.stringify(r,null,2)):console.log(JSON.stringify({...r,hint:"\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55"},null,2));return}if(!r.list?.length){console.log(Ce.yellow("\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55"));return}console.log(Ce.green(`\u2705 \u5171 ${r.total} \u6761\u8BB0\u5F55
38
- `));for(let n of r.list){let s=vo[n.status]??n.status;console.log(` ID: ${n.id} | \u72B6\u6001: ${s} | \u4EF7\u683C: ${n.price} | stockGoodsId: ${n.stockGoodsId}`)}}catch(o){if(t.json){let r=o instanceof Error?o.message:String(o);console.log(JSON.stringify({success:!1,error:r})),process.exit(1)}m(o)}}),e}import{Command as bo}from"commander";import qt from"chalk";function Te(){let e=new bo("down");return e.description("\u4E0B\u67B6\u95F2\u9C7C\u5546\u54C1"),e.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{if(!t.id&&!(t.stockGoodsId&&t.shopId)){t.json&&(console.log(JSON.stringify({success:!1,error:"\u8BF7\u6307\u5B9A\u4E0B\u67B6\u6761\u4EF6\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"})),process.exit(1)),console.log(qt.yellow("\u8BF7\u6307\u5B9A\u4E0B\u67B6\u6761\u4EF6\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let o={};t.id&&(o.id=t.id),t.stockGoodsId&&(o.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(o.shopId=t.shopId),t.json||console.log(qt.cyan("\u{1F4E6} \u6B63\u5728\u4E0B\u67B6\u5546\u54C1..."));let r=await ae(o);t.json?console.log(JSON.stringify({success:!0,data:r},null,2)):(console.log(qt.green("\u2705 \u4E0B\u67B6\u6210\u529F")),console.log(JSON.stringify(r,null,2)))}catch(o){if(t.json){let r=o instanceof Error?o.message:String(o);console.log(JSON.stringify({success:!1,error:r})),process.exit(1)}m(o)}}),e}import{Command as Ao}from"commander";import mt from"chalk";function Pe(){let e=new Ao("price");return e.description("\u4FEE\u6539\u95F2\u9C7C\u4E0A\u67B6\u5546\u54C1\u4EF7\u683C"),e.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--price <amount>","\u65B0\u4EF7\u683C\uFF08\u5FC5\u586B\uFF09").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(async t=>{try{if(!t.price){t.json&&(console.log(JSON.stringify({success:!1,error:"--price <amount> \u4E3A\u5FC5\u586B\u53C2\u6570"})),process.exit(1)),console.log(mt.yellow("--price <amount> \u4E3A\u5FC5\u586B\u53C2\u6570"));return}if(!t.id&&!(t.stockGoodsId&&t.shopId)){t.json&&(console.log(JSON.stringify({success:!1,error:"\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"})),process.exit(1)),console.log(mt.yellow("\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let o={price:Number(t.price)};t.id&&(o.id=t.id),t.stockGoodsId&&(o.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(o.shopId=t.shopId),t.json||console.log(mt.cyan(`\u{1F4B0} \u6B63\u5728\u4FEE\u6539\u4EF7\u683C\u4E3A ${t.price}...`));let r=await ce(o);t.json?console.log(JSON.stringify({success:!0,data:r},null,2)):(console.log(mt.green("\u2705 \u4EF7\u683C\u4FEE\u6539\u6210\u529F")),console.log(JSON.stringify(r,null,2)))}catch(o){if(t.json){let r=o instanceof Error?o.message:String(o);console.log(JSON.stringify({success:!1,error:r})),process.exit(1)}m(o)}}),e}function ke(){let e=new Lo("goods");return e.description("\u5546\u54C1\u7BA1\u7406"),e.addCommand(he()),e.addCommand(xe()),e.addCommand(Se()),e.addCommand(Ie()),e.addCommand(Te()),e.addCommand(Pe()),e.addCommand(ue()),e}import{Command as Ro}from"commander";import T from"chalk";import{promises as No}from"node:fs";import Eo from"node:path";import Oo from"node:os";import{spawn as Uo}from"node:child_process";var ut="@round2ai/r2-cli";function ve(){let e=new Ro("uninstall");return e.description("\u5378\u8F7D R2-CLI \u5E76\u6E05\u9664\u6240\u6709\u914D\u7F6E"),e.action(async()=>{try{console.log(T.yellow(`
39
- \u26A0\uFE0F \u5373\u5C06\u6267\u884C\u4EE5\u4E0B\u64CD\u4F5C\uFF1A`)),console.log(T.gray(" 1. \u5220\u9664\u914D\u7F6E\u76EE\u5F55 ~/.r2-cli/")),console.log(T.gray(` 2. \u5168\u5C40\u5378\u8F7D ${ut}
40
- `));let{confirm:t}=await import("@inquirer/prompts");if(!await t({message:"\u786E\u8BA4\u5378\u8F7D\uFF1F",default:!1})){console.log(T.gray("\u5DF2\u53D6\u6D88\u5378\u8F7D"));return}let r=Eo.join(Oo.homedir(),".r2-cli");try{await No.rm(r,{recursive:!0,force:!0}),console.log(T.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u6E05\u9664"))}catch{console.log(T.yellow("\u26A0\uFE0F \u914D\u7F6E\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u5220\u9664\uFF08\u53EF\u5FFD\u7565\uFF09"))}console.log(T.cyan(`\u6B63\u5728\u5378\u8F7D ${ut}...`)),Uo("npm",["uninstall","-g",ut],{stdio:"inherit",shell:!0}).on("exit",s=>{s===0?console.log(T.green(`
41
- \u2705 ${ut} \u5DF2\u5378\u8F7D`)):(console.log(T.yellow(`
42
- \u26A0\uFE0F npm \u5378\u8F7D\u5931\u8D25 (exit code: ${s})`)),console.log(T.gray(" \u5982\u901A\u8FC7 yarn/pnpm \u5B89\u88C5\uFF0C\u8BF7\u624B\u52A8\u5378\u8F7D"))),process.exit(s??1)})}catch(t){m(t)}}),e}function be(e){let t=e.command("auth").description("\u6388\u6743\u7BA1\u7406");t.addCommand(bt()),t.addCommand(At()),t.addCommand(Lt()),t.addCommand(Rt()),e.addCommand(ke()),e.addCommand(ve())}import Ae from"chalk";var Qt="@round2ai/r2-cli",Do=[`https://registry.npmmirror.com/${encodeURIComponent(Qt)}/latest`,`https://registry.npmjs.org/${encodeURIComponent(Qt)}/latest`],$o=5e3;async function jo(e){let t=new AbortController,o=setTimeout(()=>t.abort(),$o);try{let r=await fetch(e,{signal:t.signal});return r.ok?(await r.json()).version??null:null}catch{return null}finally{clearTimeout(o)}}async function Go(){let e=await Promise.allSettled(Do.map(jo));for(let t of e)if(t.status==="fulfilled"&&t.value)return t.value;return null}function Bo(e,t){let o=e.split(".").map(Number),r=t.split(".").map(Number);for(let n=0;n<3;n++)if((o[n]??0)!==(r[n]??0))return(o[n]??0)>(r[n]??0);return!1}async function Le(e){let t=await Go();t&&Bo(t,e)&&Jo(e,t)}function Jo(e,t){console.error(Ae.yellow(`
43
- Update available: ${e} \u2192 ${t}`)+Ae.gray(`
44
- Run: npm update -g ${Qt}
45
- `))}async function _o(){let{default:e}=await import("figlet");console.log(z.cyan.bold(e.textSync("R2-CLI",{font:"Standard",horizontalLayout:"full"}))),console.log(z.gray(` \u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B
46
- `))}function Mo(){let e=new qo;e.name("r2-cli").description("R2-CLI\uFF0C\u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B");let t=[Re.join(import.meta.dirname,"../../package.json"),Re.join(import.meta.dirname,"package.json")],o="0.0.0";for(let n of t)try{o=JSON.parse(Qo(n,"utf-8")).version;break}catch{}o==="0.0.0"&&console.error(z.yellow("Warning: unable to read version from package.json")),e.version(o,"-v, --version");let r=Le(o);return e.configureOutput({writeErr:n=>{console.error(z.red(n.replace("error:","").trim()))}}),e.action(async()=>{await _o(),e.help()}),be(e),{program:e,updateCheckPromise:r}}function Ne(){console.log(z.gray(`
47
- \u64CD\u4F5C\u5DF2\u53D6\u6D88`)),process.exit(130)}process.on("SIGINT",Ne);process.on("SIGTERM",Ne);var{program:Xo,updateCheckPromise:Fo}=Mo();Xo.parse(process.argv);Fo.catch(e=>{console.error(z.gray(`[update-check] ${e instanceof Error?e.message:String(e)}`))});
32
+ `));let s=t.expireTime?Number.parseInt(t.expireTime,10):3e5,i=t.pollInterval?Number.parseInt(t.pollInterval,10):1e3;try{let a=await Z(t.state,s,i,e,o);if(a.status==="success")return a;throw new x("\u95F2\u9C7C\u6388\u6743\u5931\u8D25: "+(a.status==="expired"?"\u94FE\u63A5\u5DF2\u8FC7\u671F":"\u672A\u77E5\u72B6\u6001"))}finally{r()}}import O from"chalk";function b(e){if(e instanceof x)console.error(O.red(`
33
+ \u25B2 ${e.message}`)),console.error(O.gray(`\u2192 \u8BF7\u5148\u8FD0\u884C: r2-cli auth login
34
+ `));else if(e instanceof T)console.error(O.red(`\u25B2 \u64CD\u4F5C\u5931\u8D25: ${e.message}`)),e.status&&console.error(O.gray(` \u72B6\u6001\u7801: ${e.status}`));else if(e instanceof D)console.error(O.red(`\u25B2 \u914D\u7F6E\u6587\u4EF6\u5F02\u5E38: ${e.message}`)),e.path&&console.error(O.gray(` \u8DEF\u5F84: ${e.path}`)),console.error(O.gray(`\u2192 \u8BF7\u5C1D\u8BD5\u91CD\u65B0\u767B\u5F55: r2-cli auth login
35
+ `));else{let t=e instanceof Error?e.message:String(e);console.error(O.red(`\u25B2 ${t}`))}process.exit(1)}function Lt(e){console.log(JSON.stringify({success:!1,error:e})),process.exit(1)}function p(e){return async t=>{try{await e(t)}catch(n){if(t.json){let o=n instanceof Error?n.message:String(n);console.log(JSON.stringify({success:!1,error:o})),process.exit(1)}b(n)}}}function ut(e){return async(...t)=>{try{await e(...t)}catch(n){let o=n instanceof Error?n.message:String(n);Lt(o)}}}var fo=new Set(["accessToken","refreshExpireIn"]);function ce(e){return e.map(t=>{let n={};for(let[o,r]of Object.entries(t))fo.has(o)||(n[o]=r);return n})}function Ot(){let e=new le("login");e.description("\u626B\u7801\u767B\u5F55 Round2AI \u8D26\u6237").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new le("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(ut(async n=>{let r=await N().waitForLogin(n.token,Number.parseInt(n.expire,10),Number.parseInt(n.interval,10));console.log(JSON.stringify({success:!0,...r}))}));return e.addCommand(t),e.action(async n=>{try{if(n.json){let o=N(),{qrData:r,qrUrl:s,setStatus:i,closeServer:a}=await o.generateQR(),c=Number.parseInt(r.expireTime,10),u=Number.parseInt(r.pollInterval,10);console.log(JSON.stringify({qrToken:r.qrToken,expireTimeMs:c,pollIntervalMs:u,url:`https://m.puresnake.com/r2/auth/login?qrToken=${r.qrContent}&from=wechat`,qrUrl:s},null,2)),R(s);try{let d=await o.waitForLogin(r.qrToken,c,u,void 0,i,!0);console.log(JSON.stringify({success:!0,userInfo:d.userInfo}))}catch(d){let w=d instanceof Error?d.message:String(d);console.log(JSON.stringify({success:!1,error:w}))}finally{setTimeout(a,1e3)}}else await N().login()}catch(o){if(n.json){let r=o instanceof Error?o.message:String(o);console.log(JSON.stringify({success:!1,error:r})),process.exit(1)}b(o)}}),e}import{Command as ho}from"commander";function Ut(){let e=new ho("logout");return e.description("\u9000\u51FA\u767B\u5F55"),e.action(async()=>{try{await N().logout()}catch(t){b(t)}}),e}import{Command as yo}from"commander";function Dt(){let e=new yo("status");return e.description("\u67E5\u770B\u767B\u5F55\u72B6\u6001"),e.action(async()=>{try{await N().status()}catch(t){b(t)}}),e}import{Command as de}from"commander";function Et(){let e=new de("xianyu");e.description("\u95F2\u9C7C\u5E97\u94FA\u6388\u6743").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09");let t=new de("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(ut(async n=>{let o=await Z(n.state,Number.parseInt(n.expire,10),Number.parseInt(n.interval,10));o.status==="success"?console.log(JSON.stringify({success:!0,shopId:o.shopId,shopName:o.shopName})):Lt(`\u6388\u6743\u72B6\u6001: ${o.status}`)}));return e.addCommand(t),e.action(async n=>{try{if(n.json){let{authData:o,qrUrl:r,setStatus:s,closeServer:i}=await dt(),a=o.expireTime?Number.parseInt(o.expireTime,10):3e5,c=o.pollInterval?Number.parseInt(o.pollInterval,10):1e3;console.log(JSON.stringify({state:o.state,expireTimeMs:a,pollIntervalMs:c,qrUrl:r},null,2)),R(r);try{let u=await Z(o.state,a,c,void 0,s);u.status==="success"?console.log(JSON.stringify({success:!0,shopId:u.shopId,shopName:u.shopName})):(console.log(JSON.stringify({success:!1,error:`\u6388\u6743\u72B6\u6001: ${u.status}`})),process.exit(1))}catch(u){let d=u instanceof Error?u.message:String(u);console.log(JSON.stringify({success:!1,error:d})),process.exit(1)}finally{setTimeout(i,1e3)}}else await Nt()}catch(o){if(n.json){let r=o instanceof Error?o.message:String(o);console.log(JSON.stringify({success:!1,error:r})),process.exit(1)}b(o)}}),e}import{Command as Xo}from"commander";import{Command as Io}from"commander";import v from"chalk";import{select as $t,input as So,confirm as Co}from"@inquirer/prompts";import{readFileSync as wo}from"node:fs";import{basename as xo}from"node:path";var I=it;function F(e){let t=new URLSearchParams;for(let[n,o]of Object.entries(e))o!=null&&o!==""&&t.append(n,String(o));return t}async function jt(e){return I.post("mms/goods/listing/up/xianyu",e)}async function ue(e){return I.get("mms/goods/listing/get",F({...e}))}async function me(e){return I.post("mms/goods/listing/down/xianyu",e)}async function pe(e){return I.post("mms/goods/listing/update/xyPrice",e)}async function ge(e){return I.get("mms/goods/listing/list",e?F({...e}):void 0)}async function mt(){return await I.get("mms/user/shop/list")??[]}async function pt(){return await I.get("mms/user/stock/list")??[]}async function gt(e){let t=e?F({...e}):void 0;return I.get("mms/seller/goods/select/list",t)}async function fe(e,t){let n=[];for(let o of t){let r=wo(o),s=xo(o),i=new FormData;i.append("file",new Blob([r]),s);let a=await I.upload(`platform/xy/media/upload?shopId=${encodeURIComponent(e)}`,i);n.push(a)}return n}async function he(e){return I.post("mms/goods/listing/hang/up/xianyu",e)}async function ye(e=16){return await I.get("platform/xy/cat",F({spBizType:e}))??[]}async function we(e){return await I.get("platform/xy/props",F({channelCatId:e}))??[]}async function xe(e,t,n){return await I.get("platform/xy/props/value",F({channelCatId:e,propId:t,key:n}))??[]}var Po=2e3,To=1e4;function bo(e){let t=e.status?.toLowerCase()??"";return t===""||t==="init"||t==="pending"||t==="processing"}async function Ie(e,t,n,o){o||process.stdout.write(v.cyan("\u23F3 \u6B63\u5728\u67E5\u8BE2\u4E0A\u67B6\u8FDB\u5EA6..."));let r=await J(()=>ue({stockGoodsId:e,shopId:t,platform:n}),{interval:Po,timeout:To,condition:s=>!bo(s)});return o||process.stdout.write("\r"+" ".repeat(30)+"\r"),r}function Se(){let e=new Io("up");return e.description("\u4E0A\u67B6\u5546\u54C1\u5230\u95F2\u9C7C"),e.option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1ID\uFF08\u4ECE goods list \u83B7\u53D6\uFF09").option("--shop-id <id>","\u5E97\u94FAID\uFF08\u4ECE goods shops \u83B7\u53D6\uFF09").option("--price <amount>","\u4E0A\u67B6\u4EF7\u683C").option("-p, --platform <platform>","\u5E73\u53F0","xianyu").option("--json","\u8F93\u51FA JSON\uFF08Agent \u7528\uFF09").action(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 l=Number(t.stockGoodsId),P=t.shopId,yt=Number(t.price),B=t.platform,Xe=await jt({stockGoodsId:l,shopId:P,price:yt,platform:B}),wt=await Ie(l,P,B,t.json);if(t.json)console.log(JSON.stringify({success:!0,data:{submit:Xe,listing:wt}},null,2));else{let Qe=wt.status?.toLowerCase()!=="failed";console.log(Qe?v.green("\u2713 \u4E0A\u67B6\u6210\u529F"):v.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(wt,null,2))}return}let n=await mt();if(n.length===0){console.log(v.yellow("\u6CA1\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF0C\u8BF7\u5148\u8FD0\u884C r2-cli auth xianyu \u6388\u6743"));return}let o=await $t({message:"\u9009\u62E9\u5E97\u94FA",choices:n.map(l=>({name:`${l.shopName} (${l.platform})`,value:l.shopId}))}),r=await pt();if(r.length===0){console.log(v.yellow("\u6CA1\u6709\u53EF\u7528\u7684\u4ED3\u5E93"));return}let s=await $t({message:"\u9009\u62E9\u4ED3\u5E93",choices:r.map(l=>({name:l.stockName,value:l.stockId}))}),i=await gt({stockId:s,size:100});if(!i.items?.length){console.log(v.yellow("\u8BE5\u4ED3\u5E93\u6CA1\u6709\u53EF\u9009\u7684\u5546\u54C1"));return}let a=await $t({message:"\u9009\u62E9\u5546\u54C1",choices:i.items.map(l=>({name:`${l.goodsName} ${l.size?`| ${l.size}`:""} | \xA5${l.salePrice}`,value:l.stockGoodsId}))}),c=await So({message:"\u8F93\u5165\u4E0A\u67B6\u4EF7\u683C",default:i.items.find(l=>l.stockGoodsId===a)?.salePrice?.toString()??"",validate:l=>Number(l)>0?!0:"\u4EF7\u683C\u5FC5\u987B\u4E3A\u6B63\u6570"});if(!await Co({message:`\u786E\u8BA4\u4E0A\u67B6\uFF1F\u4EF7\u683C \xA5${c}`,default:!0})){console.log(v.gray("\u5DF2\u53D6\u6D88"));return}let d=Number(a);await jt({stockGoodsId:d,shopId:o,price:Number(c),platform:"xianyu"}),console.log(v.green("\u2713 \u4E0A\u67B6\u5DF2\u63D0\u4EA4\uFF0C\u6B63\u5728\u67E5\u8BE2\u8FDB\u5EA6..."));let w=await Ie(d,o,"xianyu"),q=w.status?.toLowerCase()!=="failed";console.log(q?v.green("\u2713 \u4E0A\u67B6\u6210\u529F"):v.red("\u2717 \u4E0A\u67B6\u5931\u8D25")),console.log(JSON.stringify(w,null,2))})),e}import{Command as No}from"commander";import be from"chalk";function Ae(){let e=new No("shops");return e.description("\u67E5\u770B\u6240\u6709\u5DF2\u6388\u6743\u5E97\u94FA\uFF08\u8DE8\u5E73\u53F0\uFF09"),e.option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(p(async t=>{let n=await mt();if(t.json){console.log(JSON.stringify(ce(n),null,2));return}if(!n.length){console.log(be.yellow("\u672A\u627E\u5230\u5DF2\u6388\u6743\u7684\u5E97\u94FA")),console.log(be.gray(" \u63D0\u793A: \u8BF7\u5148\u5728\u7B2C\u4E8C\u56DE\u5408 APP \u4E2D\u6388\u6743\u5E97\u94FA"));return}let{ShopsTable:o}=await Promise.resolve().then(()=>(Te(),Pe)),{renderComponent:r}=await Promise.resolve().then(()=>(ct(),at));r(o,{shops:n,platform:"all"})})),e}import{Command as Do}from"commander";import Eo from"chalk";function Re(){let e=new Do("stocks");return e.description("\u67E5\u770B\u6240\u6709\u4ED3\u5E93"),e.option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(p(async t=>{let n=await pt();if(t.json){console.log(JSON.stringify(n,null,2));return}if(!n.length){console.log(Eo.yellow("\u672A\u627E\u5230\u4ED3\u5E93\u4FE1\u606F"));return}let{StocksTable:o}=await Promise.resolve().then(()=>(ke(),ve)),{renderComponent:r}=await Promise.resolve().then(()=>(ct(),at));r(o,{stocks:n})})),e}import{Command as jo}from"commander";import W from"chalk";function Ne(){let e=new jo("list");return e.description("\u67E5\u770B\u4ED3\u5E93\u4E2D\u7684\u9009\u54C1\u5546\u54C1"),e.option("--stock-id <id>","\u4ED3\u5E93 ID\uFF08\u4ECE goods stocks \u83B7\u53D6\uFF09").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--page <n>","\u9875\u7801","1").option("--size <n>","\u6BCF\u9875\u6570\u91CF","20").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(p(async t=>{let o=await gt({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){o.items?.length?console.log(JSON.stringify(o,null,2)):console.log(JSON.stringify({...o,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(!o.items?.length){console.log(W.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(W.cyan(`
36
+ \u9009\u54C1\u5546\u54C1\uFF08\u5171 ${o.total} \u4EF6\uFF0C\u7B2C ${o.page} \u9875\uFF09
37
+ `));for(let r of o.items)console.log(` ${W.bold(r.goodsName)} ${r.size?W.gray(`| ${r.size}`):""}`),console.log(` \u54C1\u724C: ${r.brand} \u5EFA\u8BAE\u552E\u4EF7: \xA5${r.salePrice} stockGoodsId: ${W.green(r.stockGoodsId)}`),console.log(W.gray(` \u5206\u7C7B: ${r.cate1Name} > ${r.cate2Name} > ${r.cate3Name}`)),console.log()})),e}import{Command as $o}from"commander";import Le from"chalk";var qo={init:"\u5F85\u4E0A\u67B6",up:"\u5DF2\u4E0A\u67B6",down:"\u5DF2\u4E0B\u67B6",fail:"\u5931\u8D25"};function Oe(){let e=new $o("listing");return e.description("\u67E5\u8BE2\u4E0A\u67B6\u5546\u54C1\u5217\u8868"),e.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--stock-id <id>","\u4ED3\u5E93 ID").option("-s, --status <status>","\u72B6\u6001\u8FC7\u6EE4\uFF08init/up/down/fail\uFF09").option("-p, --platform <platform>","\u5E73\u53F0","xianyu").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(p(async t=>{let o=await ge({id:t.id,stockGoodsId:t.stockGoodsId?Number(t.stockGoodsId):void 0,shopId:t.shopId,stockId:t.stockId,status:t.status,platform:t.platform})??{list:[],total:0};if(t.json){o.list?.length?console.log(JSON.stringify(o,null,2)):console.log(JSON.stringify({...o,hint:"\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55"},null,2));return}if(!o.list?.length){console.log(Le.yellow("\u6682\u65E0\u4E0A\u67B6\u8BB0\u5F55"));return}console.log(Le.green(`\u2705 \u5171 ${o.total} \u6761\u8BB0\u5F55
38
+ `));for(let r of o.list){let s=qo[r.status]??r.status;console.log(` ID: ${r.id} | \u72B6\u6001: ${s} | \u4EF7\u683C: ${r.price} | stockGoodsId: ${r.stockGoodsId}`)}})),e}import{Command as Bo}from"commander";import Mt from"chalk";function Ue(){let e=new Bo("down");return e.description("\u4E0B\u67B6\u95F2\u9C7C\u5546\u54C1"),e.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(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(Mt.yellow("\u8BF7\u6307\u5B9A\u4E0B\u67B6\u6761\u4EF6\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let n={};t.id&&(n.id=t.id),t.stockGoodsId&&(n.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(n.shopId=t.shopId),t.json||console.log(Mt.cyan("\u{1F4E6} \u6B63\u5728\u4E0B\u67B6\u5546\u54C1..."));let o=await me(n);t.json?console.log(JSON.stringify({success:!0,data:o},null,2)):(console.log(Mt.green("\u2705 \u4E0B\u67B6\u6210\u529F")),console.log(JSON.stringify(o,null,2)))})),e}import{Command as Go}from"commander";import ft from"chalk";function De(){let e=new Go("price");return e.description("\u4FEE\u6539\u95F2\u9C7C\u4E0A\u67B6\u5546\u54C1\u4EF7\u683C"),e.option("--id <id>","\u4E0A\u67B6\u8BB0\u5F55 ID").option("--stock-goods-id <id>","\u5E93\u5B58\u5546\u54C1 ID").option("--shop-id <id>","\u5E97\u94FA ID").option("--price <amount>","\u65B0\u4EF7\u683C\uFF08\u5FC5\u586B\uFF09").option("--json","\u8F93\u51FA JSON\uFF08\u4F9B AI Agent \u4F7F\u7528\uFF09"),e.action(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(ft.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(ft.yellow("\u8BF7\u6307\u5B9A\u5546\u54C1\uFF1A--id <id> \u6216 --stock-goods-id <id> --shop-id <id>"));return}let n={price:Number(t.price)};t.id&&(n.id=t.id),t.stockGoodsId&&(n.stockGoodsId=Number(t.stockGoodsId)),t.shopId&&(n.shopId=t.shopId),t.json||console.log(ft.cyan(`\u{1F4B0} \u6B63\u5728\u4FEE\u6539\u4EF7\u683C\u4E3A ${t.price}...`));let o=await pe(n);t.json?console.log(JSON.stringify({success:!0,data:o},null,2)):(console.log(ft.green("\u2705 \u4EF7\u683C\u4FEE\u6539\u6210\u529F")),console.log(JSON.stringify(o,null,2)))})),e}import{Command as V}from"commander";import y from"chalk";var Jo={100:"\u5168\u65B0",[-1]:"\u51C6\u65B0",99:"99\u65B0",95:"95\u65B0",90:"9\u65B0"};function Ee(){let e=new V("hang-up");return e.description("\u95F2\u9C7C\u6302\u552E\u4E0A\u67B6\uFF08\u5B8C\u6574\u5546\u54C1\u4FE1\u606F\u6A21\u5F0F\uFF09"),e.addCommand(new V("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 n=await ye(Number(t.spBizType));if(t.json){console.log(JSON.stringify(n,null,2));return}let o=new Map;for(let r of n){let s=String(r.catId);o.has(s)||o.set(s,{catName:r.catName,children:[]}),o.get(s).children.push({channel:r.channel,channelCatId:r.channelCatId})}for(let[,r]of o){console.log(y.bold(r.catName));for(let s of r.children)console.log(` ${s.channel} (channelCatId: ${y.green(s.channelCatId)})`)}}))),e.addCommand(new V("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 n=await we(t.channelCatId);if(t.json){console.log(JSON.stringify(n,null,2));return}for(let o of n)if(console.log(y.bold(`
39
+ ${o.propName} (propId: ${o.propId})`)),o.propsValues?.length)for(let r of o.propsValues)console.log(` ${r.valueName} (valueId: ${r.valueId})`);else console.log(y.gray(" \uFF08\u4F7F\u7528 brands \u5B50\u547D\u4EE4\u641C\u7D22\uFF09"))}))),e.addCommand(new V("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 n=await xe(t.channelCatId,t.propId,t.key);if(t.json){console.log(JSON.stringify(n,null,2));return}if(!n.length){console.log(y.yellow("\u672A\u627E\u5230\u5339\u914D\u7684\u54C1\u724C"));return}for(let o of n)console.log(` ${o.valueName} (valueId: ${o.valueId})`)}))),e.addCommand(new V("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(p(async t=>{let n=t.files.split(",").map(r=>r.trim()).filter(Boolean);if(n.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 ${n.length} \u5F20\u56FE\u7247...`));let o=await fe(t.shopId,n);if(t.json)console.log(JSON.stringify({success:!0,images:o},null,2));else{console.log(y.green(`\u4E0A\u4F20\u6210\u529F\uFF0C\u5171 ${o.length} \u5F20`));for(let r of o)console.log(` \u56FE\u7247ID: ${r.value}`)}}))),e.addCommand(new V("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 n=t.imageIds.split(",").map(s=>s.trim()),o={account:t.shopId,title:t.title,reservePrice:Number(t.price),categoryId:Number(t.categoryId),channelCatId:t.channelCatId,imageIdList:n,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:!0,supportNfrPolicy:!0,supportSdrPolicy:!0,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: ${o.title}`)),console.log(y.gray(` \u552E\u4EF7: \xA5${o.reservePrice}`)),console.log(y.gray(` \u6210\u8272: ${Jo[o.stuffStatus]??o.stuffStatus}`)),console.log(y.gray(` \u56FE\u7247: ${n.length} \u5F20`)),o.itemAttrList?.length&&console.log(y.gray(` \u5C5E\u6027: ${o.itemAttrList.length} \u9879`)));let r=await he(o);t.json?console.log(JSON.stringify({success:!0,data:r},null,2)):(console.log(y.green("\u6302\u552E\u63D0\u4EA4\u6210\u529F")),console.log(JSON.stringify(r,null,2)))}))),e}function je(){let e=new Xo("goods");return e.description("\u5546\u54C1\u7BA1\u7406"),e.addCommand(Ae()),e.addCommand(Re()),e.addCommand(Ne()),e.addCommand(Oe()),e.addCommand(Ue()),e.addCommand(De()),e.addCommand(Se()),e.addCommand(Ee()),e}import{Command as Qo}from"commander";import k from"chalk";import{promises as _o}from"node:fs";import Mo from"node:path";import Fo from"node:os";import{spawn as zo}from"node:child_process";var ht="@round2ai/r2-cli";function $e(){let e=new Qo("uninstall");return e.description("\u5378\u8F7D R2-CLI \u5E76\u6E05\u9664\u6240\u6709\u914D\u7F6E"),e.action(async()=>{try{console.log(k.yellow(`
40
+ \u26A0\uFE0F \u5373\u5C06\u6267\u884C\u4EE5\u4E0B\u64CD\u4F5C\uFF1A`)),console.log(k.gray(" 1. \u5220\u9664\u914D\u7F6E\u76EE\u5F55 ~/.r2-cli/")),console.log(k.gray(` 2. \u5168\u5C40\u5378\u8F7D ${ht}
41
+ `));let{confirm:t}=await import("@inquirer/prompts");if(!await t({message:"\u786E\u8BA4\u5378\u8F7D\uFF1F",default:!1})){console.log(k.gray("\u5DF2\u53D6\u6D88\u5378\u8F7D"));return}let o=Mo.join(Fo.homedir(),".r2-cli");try{await _o.rm(o,{recursive:!0,force:!0}),console.log(k.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u6E05\u9664"))}catch{console.log(k.yellow("\u26A0\uFE0F \u914D\u7F6E\u76EE\u5F55\u4E0D\u5B58\u5728\u6216\u65E0\u6CD5\u5220\u9664\uFF08\u53EF\u5FFD\u7565\uFF09"))}console.log(k.cyan(`\u6B63\u5728\u5378\u8F7D ${ht}...`)),zo("npm",["uninstall","-g",ht],{stdio:"inherit",shell:!0}).on("exit",s=>{s===0?console.log(k.green(`
42
+ \u2705 ${ht} \u5DF2\u5378\u8F7D`)):(console.log(k.yellow(`
43
+ \u26A0\uFE0F npm \u5378\u8F7D\u5931\u8D25 (exit code: ${s})`)),console.log(k.gray(" \u5982\u901A\u8FC7 yarn/pnpm \u5B89\u88C5\uFF0C\u8BF7\u624B\u52A8\u5378\u8F7D"))),process.exit(s??1)})}catch(t){b(t)}}),e}function qe(e){let t=e.command("auth").description("\u6388\u6743\u7BA1\u7406");t.addCommand(Ot()),t.addCommand(Ut()),t.addCommand(Dt()),t.addCommand(Et()),e.addCommand(je()),e.addCommand($e())}import Be from"chalk";var Ft="@round2ai/r2-cli",Ho=[`https://registry.npmmirror.com/${encodeURIComponent(Ft)}/latest`,`https://registry.npmjs.org/${encodeURIComponent(Ft)}/latest`],Wo=5e3;async function Vo(e){let t=new AbortController,n=setTimeout(()=>t.abort(),Wo);try{let o=await fetch(e,{signal:t.signal});return o.ok?(await o.json()).version??null:null}catch{return null}finally{clearTimeout(n)}}async function Ko(){let e=await Promise.allSettled(Ho.map(Vo));for(let t of e)if(t.status==="fulfilled"&&t.value)return t.value;return null}function Yo(e,t){let n=e.split(".").map(Number),o=t.split(".").map(Number);for(let r=0;r<3;r++)if((n[r]??0)!==(o[r]??0))return(n[r]??0)>(o[r]??0);return!1}async function Ge(e){let t=await Ko();t&&Yo(t,e)&&Zo(e,t)}function Zo(e,t){console.error(Be.yellow(`
44
+ Update available: ${e} \u2192 ${t}`)+Be.gray(`
45
+ Run: npm update -g ${Ft}
46
+ `))}async function nn(){let{default:e}=await import("figlet");console.log(K.cyan.bold(e.textSync("R2-CLI",{font:"Standard",horizontalLayout:"full"}))),console.log(K.gray(` \u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B
47
+ `))}function rn(){let e=new tn;e.name("r2-cli").description("R2-CLI\uFF0C\u5411 AI \u5F00\u653E\u4E8C\u624B\u6F6E\u5962\u4EA4\u6613\u5168\u94FE\u8DEF\u80FD\u529B");let t="0.0.0";for(let o of["../package.json","../../package.json"])try{t=JSON.parse(en(on.join(import.meta.dirname,o),"utf-8")).version;break}catch{}t==="0.0.0"&&console.error(K.yellow("Warning: unable to read version from package.json")),e.version(t,"-v, --version");let n=Ge(t);return e.configureOutput({writeErr:o=>{console.error(K.red(o.replace("error:","").trim()))}}),e.action(async()=>{await nn(),e.help()}),qe(e),{program:e,updateCheckPromise:n}}function Je(){console.log(K.gray(`
48
+ \u64CD\u4F5C\u5DF2\u53D6\u6D88`)),process.exit(130)}process.on("SIGINT",Je);process.on("SIGTERM",Je);var{program:sn,updateCheckPromise:an}=rn();sn.parse(process.argv);an.catch(e=>{console.error(K.gray(`[update-check] ${e instanceof Error?e.message:String(e)}`))});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@round2ai/r2-cli",
3
- "version": "1.0.11",
3
+ "version": "1.0.12-beta.0",
4
4
  "description": "R2-CLI,向 AI 开放二手潮奢交易全链路能力",
5
5
  "main": "dist/r2-cli.js",
6
6
  "type": "module",
@@ -11,7 +11,9 @@
11
11
  "postinstall": "node scripts/install-skills.js",
12
12
  "build": "cross-env NODE_ENV=development node scripts/build.js",
13
13
  "build:prod": "cross-env NODE_ENV=production node scripts/build.js",
14
- "dev": "node scripts/dev.js"
14
+ "dev": "node scripts/dev.js",
15
+ "test": "vitest run",
16
+ "test:watch": "vitest"
15
17
  },
16
18
  "keywords": [
17
19
  "round2ai",
@@ -25,7 +27,7 @@
25
27
  ],
26
28
  "files": [
27
29
  "dist",
28
- "scripts",
30
+ "scripts/install-skills.js",
29
31
  "skills",
30
32
  "package.json",
31
33
  "README.md"
@@ -56,6 +58,7 @@
56
58
  "cross-env": "^10.1.0",
57
59
  "dotenv": "^17.4.2",
58
60
  "esbuild": "^0.28.0",
59
- "typescript": "^6.0.2"
61
+ "typescript": "^6.0.2",
62
+ "vitest": "^4.1.5"
60
63
  }
61
64
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * postinstall: 将 skills/ 复制到 ~/.agents/skills/ + 确保 ~/.claude/skills/ 符号链接存在
2
+ * postinstall: 将 skills/ 复制到 ~/.agents/skills/
3
3
  */
4
4
 
5
5
  import fs from "node:fs";
@@ -10,7 +10,6 @@ import { fileURLToPath } from "node:url";
10
10
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
11
  const pkgSkillsDir = path.join(__dirname, "..", "skills");
12
12
  const agentsDir = path.join(os.homedir(), ".agents", "skills");
13
- const claudeDir = path.join(os.homedir(), ".claude", "skills");
14
13
 
15
14
  if (!fs.existsSync(pkgSkillsDir)) process.exit(0);
16
15
 
@@ -18,13 +17,11 @@ fs.mkdirSync(agentsDir, { recursive: true });
18
17
 
19
18
  for (const name of fs.readdirSync(pkgSkillsDir)) {
20
19
  const rawSrc = path.join(pkgSkillsDir, name);
21
- // npm 包内是真实目录,本地开发可能是 symlink → 解析真实路径
22
20
  let src;
23
21
  try { src = fs.realpathSync(rawSrc); } catch { continue; }
24
22
  if (!fs.statSync(src).isDirectory()) continue;
25
23
 
26
24
  const dest = path.join(agentsDir, name);
27
- // 清空目标目录中的旧残留文件
28
25
  if (fs.existsSync(dest)) {
29
26
  for (const old of fs.readdirSync(dest)) {
30
27
  fs.unlinkSync(path.join(dest, old));
@@ -35,20 +32,4 @@ for (const name of fs.readdirSync(pkgSkillsDir)) {
35
32
  for (const file of fs.readdirSync(src)) {
36
33
  fs.copyFileSync(path.join(src, file), path.join(dest, file));
37
34
  }
38
-
39
- // 确保 ~/.claude/skills/<name> 指向 ~/.agents/skills/<name>
40
- const link = path.join(claudeDir, name);
41
- if (!fs.existsSync(link)) {
42
- fs.mkdirSync(claudeDir, { recursive: true });
43
- const target = dest;
44
- try {
45
- fs.symlinkSync(target, link, "junction");
46
- } catch {
47
- // Windows 权限不足时 fallback:直接复制
48
- fs.mkdirSync(link, { recursive: true });
49
- for (const file of fs.readdirSync(dest)) {
50
- fs.copyFileSync(path.join(dest, file), path.join(link, file));
51
- }
52
- }
53
- }
54
35
  }