beervid-app-cli 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +16 -5
  2. package/dist/cli.mjs +164 -187
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -2,21 +2,32 @@
2
2
 
3
3
  BEERVID 第三方应用 Open API 的 TypeScript CLI 和 Claude Code Skill,提供 TikTok 视频发布、账号授权、数据查询等完整能力。
4
4
 
5
- ## 安装
5
+ ## 安装与调用
6
6
 
7
- ### npm CLI
7
+ ### 全局安装
8
8
 
9
9
  ```bash
10
10
  npm install -g beervid-app-cli
11
11
  beervid --help
12
12
  ```
13
13
 
14
- ### Claude Code Skill
14
+ ### npx 免安装调用
15
15
 
16
- 将本仓库克隆到 Claude Code 的 skills 目录:
16
+ ```bash
17
+ npx beervid-app-cli --help
18
+ npx beervid-app-cli config --show
19
+ npx beervid-app-cli upload --file ./video.mp4
20
+ ```
21
+
22
+ ### node 直接调用
17
23
 
18
24
  ```bash
19
- git clone <repo-url> ~/.claude/skills/beervid-app-cli
25
+ # 克隆仓库后先构建
26
+ npm install && npm run build
27
+
28
+ # 通过 node 运行入口文件
29
+ node dist/cli.mjs --help
30
+ node dist/cli.mjs config --show
20
31
  ```
21
32
 
22
33
  ## 配置
package/dist/cli.mjs CHANGED
@@ -511,134 +511,6 @@ function register6(cli2) {
511
511
  );
512
512
  }
513
513
 
514
- // src/commands/query-products.ts
515
- var VALID_PRODUCT_TYPES = ["shop", "showcase", "all"];
516
- function extractImageUrl(imageStr) {
517
- const match = imageStr.match(/url=([^,}]+)/);
518
- return match?.[1]?.trim() ?? imageStr;
519
- }
520
- async function queryProducts(creatorId, type, pageSize, pageToken) {
521
- return openApiPost("/api/v1/open/tts/products/query", {
522
- creatorUserOpenId: creatorId,
523
- productType: type,
524
- pageSize,
525
- pageToken
526
- });
527
- }
528
- function register7(cli2) {
529
- cli2.command("query-products", "\u67E5\u8BE2 TTS \u5546\u54C1\u5217\u8868").option("--creator-id <id>", "TTS \u8D26\u53F7 creatorUserOpenId\uFF08\u5FC5\u586B\uFF09").option("--product-type <type>", "\u5546\u54C1\u6765\u6E90: shop / showcase / all\uFF08\u9ED8\u8BA4 all\uFF09").option("--page-size <n>", "\u6BCF\u9875\u6570\u91CF\uFF08\u9ED8\u8BA4 20\uFF09").option("--cursor <cursor>", "\u5206\u9875\u6E38\u6807\uFF08\u9996\u9875\u4E0D\u4F20\uFF09").action(
530
- async (options) => {
531
- if (!options.creatorId) {
532
- console.error("\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: --creator-id\n");
533
- console.error("\u7528\u6CD5: beervid query-products --creator-id <id>");
534
- process.exit(1);
535
- }
536
- const creatorId = options.creatorId;
537
- const productType = (options.productType ?? "all").toLowerCase();
538
- const pageSize = parseInt(options.pageSize ?? "20", 10);
539
- const cursor = options.cursor ?? "";
540
- if (!VALID_PRODUCT_TYPES.includes(productType)) {
541
- console.error("\u9519\u8BEF: --product-type \u5FC5\u987B\u4E3A shop\u3001showcase \u6216 all");
542
- process.exit(1);
543
- }
544
- if (Number.isNaN(pageSize) || pageSize <= 0) {
545
- console.error("\u9519\u8BEF: --page-size \u5FC5\u987B\u4E3A\u5927\u4E8E 0 \u7684\u6574\u6570");
546
- process.exit(1);
547
- }
548
- try {
549
- let shopToken = "";
550
- let showcaseToken = "";
551
- if (cursor) {
552
- try {
553
- const decoded = JSON.parse(
554
- Buffer.from(cursor, "base64").toString()
555
- );
556
- shopToken = decoded.shopToken ?? "";
557
- showcaseToken = decoded.showcaseToken ?? "";
558
- } catch {
559
- console.error("\u9519\u8BEF: \u65E0\u6548\u7684 cursor \u683C\u5F0F");
560
- process.exit(1);
561
- }
562
- }
563
- const typesToQuery = productType === "all" ? ["shop", "showcase"] : [productType];
564
- const allProducts = /* @__PURE__ */ new Map();
565
- let nextShopToken = null;
566
- let nextShowcaseToken = null;
567
- let successCount = 0;
568
- const results = await Promise.allSettled(
569
- typesToQuery.map(async (type) => {
570
- const token = type === "shop" ? shopToken : showcaseToken;
571
- const data = await queryProducts(creatorId, type, pageSize, token);
572
- return { type, data };
573
- })
574
- );
575
- for (const result of results) {
576
- if (result.status === "rejected") {
577
- console.error("\u67E5\u8BE2\u5931\u8D25:", result.reason?.message);
578
- continue;
579
- }
580
- const { type, data } = result.value;
581
- successCount += 1;
582
- const items = Array.isArray(data) ? data : [data];
583
- for (const group of items) {
584
- if (type === "shop") nextShopToken = group.nextPageToken ?? null;
585
- if (type === "showcase") nextShowcaseToken = group.nextPageToken ?? null;
586
- for (const product of group.products ?? []) {
587
- if (!allProducts.has(product.id)) {
588
- allProducts.set(product.id, {
589
- id: product.id,
590
- title: product.title,
591
- price: product.price,
592
- images: (product.images ?? []).map(extractImageUrl),
593
- salesCount: product.salesCount ?? 0,
594
- brandName: product.brandName ?? "",
595
- shopName: product.shopName ?? "",
596
- source: product.source ?? type,
597
- reviewStatus: product.reviewStatus,
598
- inventoryStatus: product.inventoryStatus
599
- });
600
- }
601
- }
602
- }
603
- }
604
- if (successCount === 0) {
605
- console.error("\u67E5\u8BE2\u5546\u54C1\u5931\u8D25: \u6240\u6709\u5546\u54C1\u6E90\u90FD\u8BF7\u6C42\u5931\u8D25");
606
- process.exit(1);
607
- }
608
- const productList = Array.from(allProducts.values());
609
- let nextCursor = null;
610
- if (nextShopToken || nextShowcaseToken) {
611
- nextCursor = Buffer.from(
612
- JSON.stringify({
613
- shopToken: nextShopToken ?? "",
614
- showcaseToken: nextShowcaseToken ?? ""
615
- })
616
- ).toString("base64");
617
- }
618
- console.log(`\u67E5\u8BE2\u5230 ${productList.length} \u4E2A\u5546\u54C1:
619
- `);
620
- for (const p of productList) {
621
- console.log(` [${p.source}] ${p.title}`);
622
- console.log(` ID: ${p.id} \u9500\u91CF: ${p.salesCount} \u54C1\u724C: ${p.brandName}`);
623
- if (p.images.length > 0) console.log(` \u56FE\u7247: ${p.images[0]}`);
624
- console.log("");
625
- }
626
- if (nextCursor) {
627
- console.log(`\u4E0B\u4E00\u9875\u6E38\u6807: ${nextCursor}`);
628
- console.log(`\u4F7F\u7528: beervid query-products --creator-id ${creatorId} --cursor ${nextCursor}`);
629
- } else {
630
- console.log("\u5DF2\u5230\u6700\u540E\u4E00\u9875");
631
- }
632
- printResult({ products: productList, nextCursor });
633
- } catch (err) {
634
- rethrowIfProcessExit(err);
635
- console.error("\u67E5\u8BE2\u5546\u54C1\u5931\u8D25:", err.message);
636
- process.exit(1);
637
- }
638
- }
639
- );
640
- }
641
-
642
514
  // src/workflows/index.ts
643
515
  import { createInterface } from "readline/promises";
644
516
  import { stdin as input, stdout as output } from "process";
@@ -748,25 +620,30 @@ async function queryVideoWithRetry(businessId, itemId, intervalSec, maxAttempts)
748
620
  });
749
621
  return { query: null, warnings };
750
622
  }
751
- function extractImageUrl2(imageStr) {
623
+ function extractImageUrl(imageStr) {
752
624
  const match = imageStr.match(/url=([^,}]+)/);
753
625
  return match?.[1]?.trim() ?? imageStr;
754
626
  }
755
627
  function decodeCursor(cursor) {
756
628
  const decoded = JSON.parse(Buffer.from(cursor, "base64").toString());
757
629
  return {
758
- shopToken: decoded.shopToken ?? "",
759
- showcaseToken: decoded.showcaseToken ?? ""
630
+ shopToken: decoded.shopToken === void 0 ? "" : decoded.shopToken,
631
+ showcaseToken: decoded.showcaseToken === void 0 ? "" : decoded.showcaseToken
760
632
  };
761
633
  }
762
634
  function encodeCursor(cursor) {
635
+ if (cursor.shopToken === null && cursor.showcaseToken === null) return null;
763
636
  return Buffer.from(JSON.stringify(cursor)).toString("base64");
764
637
  }
765
638
  async function queryProductsPage(creatorId, productType, pageSize, cursor) {
766
- const typesToQuery = productType === "all" ? ["shop", "showcase"] : [productType];
639
+ const allTypesToQuery = productType === "all" ? ["shop", "showcase"] : [productType];
640
+ const typesToQuery = allTypesToQuery.filter((type) => {
641
+ const token = type === "shop" ? cursor.shopToken : cursor.showcaseToken;
642
+ return token !== null;
643
+ });
767
644
  const allProducts = /* @__PURE__ */ new Map();
768
- let nextShopToken = "";
769
- let nextShowcaseToken = "";
645
+ let nextShopToken = cursor.shopToken;
646
+ let nextShowcaseToken = cursor.showcaseToken;
770
647
  let successCount = 0;
771
648
  const failedSources = [];
772
649
  const results = await Promise.allSettled(
@@ -776,7 +653,7 @@ async function queryProductsPage(creatorId, productType, pageSize, cursor) {
776
653
  creatorUserOpenId: creatorId,
777
654
  productType: type,
778
655
  pageSize,
779
- pageToken
656
+ pageToken: pageToken ?? ""
780
657
  });
781
658
  return { type, data };
782
659
  })
@@ -793,15 +670,16 @@ async function queryProductsPage(creatorId, productType, pageSize, cursor) {
793
670
  const { data } = result.value;
794
671
  const groups = Array.isArray(data) ? data : [data];
795
672
  for (const group of groups) {
796
- if (type === "shop") nextShopToken = group.nextPageToken ?? "";
797
- if (type === "showcase") nextShowcaseToken = group.nextPageToken ?? "";
673
+ const token = group.nextPageToken === void 0 ? null : group.nextPageToken;
674
+ if (type === "shop") nextShopToken = token;
675
+ if (type === "showcase") nextShowcaseToken = token;
798
676
  for (const product of group.products ?? []) {
799
677
  if (!allProducts.has(product.id)) {
800
678
  allProducts.set(product.id, {
801
679
  id: product.id,
802
680
  title: product.title,
803
681
  price: product.price,
804
- images: (product.images ?? []).map(extractImageUrl2),
682
+ images: (product.images ?? []).map(extractImageUrl),
805
683
  salesCount: product.salesCount ?? 0,
806
684
  brandName: product.brandName ?? "",
807
685
  shopName: product.shopName ?? "",
@@ -813,7 +691,7 @@ async function queryProductsPage(creatorId, productType, pageSize, cursor) {
813
691
  }
814
692
  }
815
693
  }
816
- const nextCursor = nextShopToken || nextShowcaseToken ? encodeCursor({ shopToken: nextShopToken, showcaseToken: nextShowcaseToken }) : null;
694
+ const nextCursor = encodeCursor({ shopToken: nextShopToken, showcaseToken: nextShowcaseToken });
817
695
  return {
818
696
  products: Array.from(allProducts.values()),
819
697
  nextCursor,
@@ -860,8 +738,24 @@ async function fetchProductPool(creatorId, productType, pageSize, maxPages) {
860
738
  }
861
739
  };
862
740
  }
741
+ function buildSkippedProductQuerySummary(productType, pageSize) {
742
+ return {
743
+ productType,
744
+ pageSize,
745
+ pagesScanned: 0,
746
+ productCount: 0,
747
+ nextCursor: null,
748
+ reachedPageLimit: false,
749
+ failedSources: []
750
+ };
751
+ }
752
+ function isProductPublishable(product) {
753
+ if (product.reviewStatus && product.reviewStatus.toUpperCase() !== "APPROVED") return false;
754
+ if (product.inventoryStatus && product.inventoryStatus.toUpperCase() !== "IN_STOCK") return false;
755
+ return true;
756
+ }
863
757
  function sortProductsForSelection(products) {
864
- return [...products].sort((a, b) => b.salesCount - a.salesCount);
758
+ return products.filter(isProductPublishable).sort((a, b) => b.salesCount - a.salesCount);
865
759
  }
866
760
  function buildSelectedProductSummary(product, selectionMode) {
867
761
  return {
@@ -879,8 +773,11 @@ async function promptForProductSelection(products) {
879
773
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
880
774
  throw new Error("\u4EA4\u4E92\u6A21\u5F0F\u9700\u8981\u5728 TTY \u7EC8\u7AEF\u4E2D\u8FD0\u884C");
881
775
  }
882
- const candidates = sortProductsForSelection(products).slice(0, 20);
883
- console.log(`\u53EF\u9009\u5546\u54C1\uFF08\u5C55\u793A\u524D ${candidates.length} \u4E2A\uFF0C\u6309\u9500\u91CF\u964D\u5E8F\uFF09\uFF1A`);
776
+ const candidates = products.filter(isProductPublishable).sort((a, b) => b.salesCount - a.salesCount).slice(0, 20);
777
+ if (candidates.length === 0) {
778
+ throw new Error("\u5F53\u524D\u5546\u54C1\u6C60\u4E2D\u6CA1\u6709\u53EF\u53D1\u5E03\u5546\u54C1\uFF08\u5BA1\u6838\u672A\u901A\u8FC7\u6216\u65E0\u5E93\u5B58\uFF09\uFF0C\u5982\u9700\u5F3A\u5236\u6307\u5B9A\u8BF7\u4F7F\u7528 --product-id/--product-title");
779
+ }
780
+ console.log(`\u53EF\u9009\u5546\u54C1\uFF08\u5C55\u793A\u524D ${candidates.length} \u4E2A\uFF0C\u6309\u9500\u91CF\u964D\u5E8F\uFF0C\u5DF2\u8FC7\u6EE4\u4E0D\u53EF\u53D1\u5E03\u5546\u54C1\uFF09\uFF1A`);
884
781
  for (const [index, product] of candidates.entries()) {
885
782
  console.log(
886
783
  `${index + 1}. [${product.source}] ${product.title} | ID: ${product.id} | \u9500\u91CF: ${product.salesCount}`
@@ -904,6 +801,73 @@ async function promptForProductSelection(products) {
904
801
  }
905
802
  }
906
803
 
804
+ // src/commands/query-products.ts
805
+ var VALID_PRODUCT_TYPES = ["shop", "showcase", "all"];
806
+ function register7(cli2) {
807
+ cli2.command("query-products", "\u67E5\u8BE2 TTS \u5546\u54C1\u5217\u8868").option("--creator-id <id>", "TTS \u8D26\u53F7 creatorUserOpenId\uFF08\u5FC5\u586B\uFF09").option("--product-type <type>", "\u5546\u54C1\u6765\u6E90: shop / showcase / all\uFF08\u9ED8\u8BA4 all\uFF09").option("--page-size <n>", "\u6BCF\u9875\u6570\u91CF\uFF08\u9ED8\u8BA4 20\uFF09").option("--cursor <cursor>", "\u5206\u9875\u6E38\u6807\uFF08\u9996\u9875\u4E0D\u4F20\uFF09").action(
808
+ async (options) => {
809
+ if (!options.creatorId) {
810
+ console.error("\u7F3A\u5C11\u5FC5\u586B\u53C2\u6570: --creator-id\n");
811
+ console.error("\u7528\u6CD5: beervid query-products --creator-id <id>");
812
+ process.exit(1);
813
+ }
814
+ const creatorId = options.creatorId;
815
+ const productType = (options.productType ?? "all").toLowerCase();
816
+ const pageSize = parseInt(options.pageSize ?? "20", 10);
817
+ const cursor = options.cursor ?? "";
818
+ if (!VALID_PRODUCT_TYPES.includes(productType)) {
819
+ console.error("\u9519\u8BEF: --product-type \u5FC5\u987B\u4E3A shop\u3001showcase \u6216 all");
820
+ process.exit(1);
821
+ }
822
+ if (Number.isNaN(pageSize) || pageSize <= 0) {
823
+ console.error("\u9519\u8BEF: --page-size \u5FC5\u987B\u4E3A\u5927\u4E8E 0 \u7684\u6574\u6570");
824
+ process.exit(1);
825
+ }
826
+ try {
827
+ let inputCursor = { shopToken: "", showcaseToken: "" };
828
+ if (cursor) {
829
+ try {
830
+ inputCursor = decodeCursor(cursor);
831
+ } catch {
832
+ console.error("\u9519\u8BEF: \u65E0\u6548\u7684 cursor \u683C\u5F0F");
833
+ process.exit(1);
834
+ }
835
+ }
836
+ const pageResult = await queryProductsPage(
837
+ creatorId,
838
+ productType,
839
+ pageSize,
840
+ inputCursor
841
+ );
842
+ if (pageResult.successCount === 0 && pageResult.failedSources.length > 0) {
843
+ console.error("\u67E5\u8BE2\u5546\u54C1\u5931\u8D25: \u6240\u6709\u5546\u54C1\u6E90\u90FD\u8BF7\u6C42\u5931\u8D25");
844
+ process.exit(1);
845
+ }
846
+ const productList = pageResult.products;
847
+ console.log(`\u67E5\u8BE2\u5230 ${productList.length} \u4E2A\u5546\u54C1:
848
+ `);
849
+ for (const p of productList) {
850
+ console.log(` [${p.source}] ${p.title}`);
851
+ console.log(` ID: ${p.id} \u9500\u91CF: ${p.salesCount} \u54C1\u724C: ${p.brandName}`);
852
+ if (p.images.length > 0) console.log(` \u56FE\u7247: ${p.images[0]}`);
853
+ console.log("");
854
+ }
855
+ if (pageResult.nextCursor) {
856
+ console.log(`\u4E0B\u4E00\u9875\u6E38\u6807: ${pageResult.nextCursor}`);
857
+ console.log(`\u4F7F\u7528: beervid query-products --creator-id ${creatorId} --cursor ${pageResult.nextCursor}`);
858
+ } else {
859
+ console.log("\u5DF2\u5230\u6700\u540E\u4E00\u9875");
860
+ }
861
+ printResult({ products: productList, nextCursor: pageResult.nextCursor });
862
+ } catch (err) {
863
+ rethrowIfProcessExit(err);
864
+ console.error("\u67E5\u8BE2\u5546\u54C1\u5931\u8D25:", err.message);
865
+ process.exit(1);
866
+ }
867
+ }
868
+ );
869
+ }
870
+
907
871
  // src/commands/publish-tt-flow.ts
908
872
  function parsePositiveInt(value, optionName, defaultValue) {
909
873
  const parsed = parseInt(value ?? `${defaultValue}`, 10);
@@ -1059,58 +1023,71 @@ function register9(cli2) {
1059
1023
  );
1060
1024
  try {
1061
1025
  console.log("\u5F00\u59CB\u6267\u884C TTS \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B...");
1062
- console.log("1/4 \u6B63\u5728\u67E5\u8BE2\u5546\u54C1\u5217\u8868...");
1063
- const productPool = await fetchProductPool(
1064
- options.creatorId,
1065
- productType,
1066
- pageSize,
1067
- maxProductPages
1068
- );
1069
1026
  const warnings = [];
1070
- if (productPool.summary.reachedPageLimit && productPool.summary.nextCursor) {
1071
- warnings.push({
1072
- code: "PRODUCT_SCAN_LIMIT_REACHED",
1073
- message: `\u5546\u54C1\u626B\u63CF\u5DF2\u8FBE\u5230\u9875\u6570\u4E0A\u9650 ${maxProductPages}\uFF0C\u4ECD\u5B58\u5728\u672A\u62C9\u53D6\u5206\u9875`
1074
- });
1075
- }
1076
- if (productPool.summary.failedSources.length > 0) {
1077
- warnings.push({
1078
- code: "PRODUCT_SOURCE_PARTIAL_FAILURE",
1079
- message: `\u4EE5\u4E0B\u5546\u54C1\u6E90\u8BF7\u6C42\u5931\u8D25: ${productPool.summary.failedSources.join(", ")}\uFF0C\u5546\u54C1\u6C60\u53EF\u80FD\u4E0D\u5B8C\u6574`
1080
- });
1081
- }
1082
- if (productPool.products.length === 0) {
1083
- console.error("TTS \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B\u5931\u8D25: \u5F53\u524D\u5546\u54C1\u6C60\u4E3A\u7A7A\uFF0C\u65E0\u6CD5\u9009\u62E9\u5546\u54C1");
1084
- process.exit(1);
1085
- }
1086
1027
  let selectionMode = "automatic";
1087
1028
  let selectedProduct;
1088
- if (options.productId) {
1029
+ let productPoolSummary;
1030
+ if (options.productId && options.productTitle) {
1089
1031
  selectionMode = "manual";
1090
- const matchedProduct = productPool.products.find(
1091
- (product) => product.id === options.productId
1032
+ console.log("1/4 \u5DF2\u624B\u52A8\u6307\u5B9A\u5546\u54C1\uFF0C\u8DF3\u8FC7\u5546\u54C1\u67E5\u8BE2...");
1033
+ selectedProduct = buildManualProduct(options.productId, options.productTitle);
1034
+ } else {
1035
+ console.log("1/4 \u6B63\u5728\u67E5\u8BE2\u5546\u54C1\u5217\u8868...");
1036
+ const productPool = await fetchProductPool(
1037
+ options.creatorId,
1038
+ productType,
1039
+ pageSize,
1040
+ maxProductPages
1092
1041
  );
1093
- const resolvedTitle = options.productTitle ?? matchedProduct?.title;
1094
- if (!resolvedTitle) {
1095
- console.error(
1096
- "\u9519\u8BEF: \u624B\u52A8\u6307\u5B9A --product-id \u65F6\uFF0C\u5982\u65E0\u6CD5\u4ECE\u5DF2\u626B\u63CF\u5546\u54C1\u6C60\u8865\u9F50\u6807\u9898\uFF0C\u5219\u5FC5\u987B\u663E\u5F0F\u4F20\u5165 --product-title"
1097
- );
1098
- process.exit(1);
1042
+ productPoolSummary = productPool.summary;
1043
+ if (productPool.summary.reachedPageLimit && productPool.summary.nextCursor) {
1044
+ warnings.push({
1045
+ code: "PRODUCT_SCAN_LIMIT_REACHED",
1046
+ message: `\u5546\u54C1\u626B\u63CF\u5DF2\u8FBE\u5230\u9875\u6570\u4E0A\u9650 ${maxProductPages}\uFF0C\u4ECD\u5B58\u5728\u672A\u62C9\u53D6\u5206\u9875`
1047
+ });
1099
1048
  }
1100
- selectedProduct = buildManualProduct(options.productId, resolvedTitle, matchedProduct);
1101
- if (!matchedProduct) {
1049
+ if (productPool.summary.failedSources.length > 0) {
1102
1050
  warnings.push({
1103
- code: "PRODUCT_NOT_IN_SCANNED_POOL",
1104
- message: "\u624B\u52A8\u6307\u5B9A\u7684\u5546\u54C1 ID \u672A\u51FA\u73B0\u5728\u5DF2\u626B\u63CF\u5546\u54C1\u6C60\u4E2D\uFF0C\u5DF2\u4F7F\u7528\u663E\u5F0F\u53C2\u6570\u7EE7\u7EED\u53D1\u5E03"
1051
+ code: "PRODUCT_SOURCE_PARTIAL_FAILURE",
1052
+ message: `\u4EE5\u4E0B\u5546\u54C1\u6E90\u8BF7\u6C42\u5931\u8D25: ${productPool.summary.failedSources.join(", ")}\uFF0C\u5546\u54C1\u6C60\u53EF\u80FD\u4E0D\u5B8C\u6574`
1105
1053
  });
1106
1054
  }
1107
- } else if (options.interactive) {
1108
- selectionMode = "interactive";
1109
- console.log("2/4 \u8BF7\u9009\u62E9\u8981\u6302\u8F66\u7684\u5546\u54C1...");
1110
- selectedProduct = await promptForProductSelection(productPool.products);
1111
- } else {
1112
- console.log("2/4 \u6B63\u5728\u81EA\u52A8\u9009\u62E9\u5546\u54C1\uFF08\u6309\u9500\u91CF\u6700\u9AD8\u4F18\u5148\uFF09...");
1113
- selectedProduct = sortProductsForSelection(productPool.products)[0];
1055
+ if (options.productId) {
1056
+ selectionMode = "manual";
1057
+ const matchedProduct = productPool.products.find(
1058
+ (product) => product.id === options.productId
1059
+ );
1060
+ const resolvedTitle = matchedProduct?.title;
1061
+ if (!resolvedTitle) {
1062
+ console.error(
1063
+ "\u9519\u8BEF: \u624B\u52A8\u6307\u5B9A --product-id \u65F6\uFF0C\u5982\u65E0\u6CD5\u4ECE\u5DF2\u626B\u63CF\u5546\u54C1\u6C60\u8865\u9F50\u6807\u9898\uFF0C\u5219\u5FC5\u987B\u663E\u5F0F\u4F20\u5165 --product-title"
1064
+ );
1065
+ process.exit(1);
1066
+ }
1067
+ selectedProduct = buildManualProduct(options.productId, resolvedTitle, matchedProduct);
1068
+ } else if (options.interactive) {
1069
+ if (productPool.products.length === 0) {
1070
+ console.error("TTS \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B\u5931\u8D25: \u5F53\u524D\u5546\u54C1\u6C60\u4E3A\u7A7A\uFF0C\u65E0\u6CD5\u9009\u62E9\u5546\u54C1");
1071
+ process.exit(1);
1072
+ }
1073
+ selectionMode = "interactive";
1074
+ console.log("2/4 \u8BF7\u9009\u62E9\u8981\u6302\u8F66\u7684\u5546\u54C1...");
1075
+ selectedProduct = await promptForProductSelection(productPool.products);
1076
+ } else {
1077
+ if (productPool.products.length === 0) {
1078
+ console.error("TTS \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B\u5931\u8D25: \u5F53\u524D\u5546\u54C1\u6C60\u4E3A\u7A7A\uFF0C\u65E0\u6CD5\u9009\u62E9\u5546\u54C1");
1079
+ process.exit(1);
1080
+ }
1081
+ console.log("2/4 \u6B63\u5728\u81EA\u52A8\u9009\u62E9\u5546\u54C1\uFF08\u6309\u9500\u91CF\u6700\u9AD8\u4F18\u5148\uFF09...");
1082
+ const publishable = sortProductsForSelection(productPool.products);
1083
+ if (publishable.length === 0) {
1084
+ console.error(
1085
+ "TTS \u5B8C\u6574\u53D1\u5E03\u6D41\u7A0B\u5931\u8D25: \u5546\u54C1\u6C60\u4E2D\u6CA1\u6709\u53EF\u53D1\u5E03\u5546\u54C1\uFF08\u5BA1\u6838\u672A\u901A\u8FC7\u6216\u65E0\u5E93\u5B58\uFF09\uFF0C\u5982\u9700\u5F3A\u5236\u6307\u5B9A\u8BF7\u4F7F\u7528 --product-id/--product-title"
1086
+ );
1087
+ process.exit(1);
1088
+ }
1089
+ selectedProduct = publishable[0];
1090
+ }
1114
1091
  }
1115
1092
  console.log("3/4 \u6B63\u5728\u4E0A\u4F20\u6302\u8F66\u89C6\u9891...");
1116
1093
  const upload = await uploadTtsVideo(options.file, options.creatorId, options.token);
@@ -1130,7 +1107,7 @@ function register9(cli2) {
1130
1107
  }
1131
1108
  const result = {
1132
1109
  flowType: "tts",
1133
- productQuery: productPool.summary,
1110
+ productQuery: productPoolSummary ?? buildSkippedProductQuerySummary(productType, pageSize),
1134
1111
  selectedProduct: buildSelectedProductSummary(selectedProduct, selectionMode),
1135
1112
  upload,
1136
1113
  publish: publishResult.publish,
@@ -1187,7 +1164,7 @@ function register10(cli2) {
1187
1164
 
1188
1165
  // src/cli.ts
1189
1166
  var cli = cac("beervid");
1190
- var cliVersion = true ? "0.2.1" : pkg.version;
1167
+ var cliVersion = true ? "0.2.2" : pkg.version;
1191
1168
  register10(cli);
1192
1169
  register(cli);
1193
1170
  register2(cli);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beervid-app-cli",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "BEERVID App CLI — TikTok video publish, account auth, and data query",
5
5
  "type": "module",
6
6
  "engines": {