siluzan-cso-cli 1.1.17 → 1.1.18-beta.4

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/dist/index.js CHANGED
@@ -1935,246 +1935,38 @@ var require_semver2 = __commonJS({
1935
1935
  }
1936
1936
  });
1937
1937
 
1938
- // src/index.ts
1939
- import { Command, Option } from "commander";
1940
-
1941
- // src/config/defaults.ts
1942
- var BUILD_ENV = "production";
1943
- var DEFAULT_API_BASE = "https://api.siluzan.com";
1944
- var DEFAULT_CSO_BASE = "https://cso.siluzan.com";
1945
- var DEFAULT_WEB_BASE = "https://www.siluzan.com";
1946
- var DEFAULT_AGENT_BASE = "https://agent.mysiluzan.com";
1947
-
1948
- // src/commands/init.ts
1949
- import * as fs2 from "fs/promises";
1950
- import * as fsSync from "fs";
1951
- import * as os from "os";
1952
- import * as path2 from "path";
1953
- import { fileURLToPath } from "url";
1954
-
1955
- // src/templates/load-templates.ts
1956
- import * as fs from "fs/promises";
1957
- import * as path from "path";
1958
- async function getSkillFiles(skillDir, apiBaseUrl) {
1959
- const out = {};
1960
- async function walk(dir, prefix) {
1961
- const entries = await fs.readdir(dir, { withFileTypes: true });
1962
- for (const ent of entries) {
1963
- const rel = prefix ? `${prefix}/${ent.name}` : ent.name;
1964
- const full = path.join(dir, ent.name);
1965
- if (ent.isDirectory()) {
1966
- await walk(full, rel);
1967
- } else {
1968
- let text = await fs.readFile(full, "utf8");
1969
- text = text.replace(/\{\{SILUZAN_API_BASE_URL\}\}/g, apiBaseUrl);
1970
- out[rel] = text;
1971
- }
1972
- }
1973
- }
1974
- await walk(skillDir, "");
1975
- return out;
1976
- }
1977
-
1978
- // src/commands/init.ts
1979
- var __dirname = path2.dirname(fileURLToPath(import.meta.url));
1980
- var SKILL_DIR_NAME = "siluzan-platform";
1981
- var PROJECT_DIRS = {
1982
- agents: (cwd) => path2.join(cwd, ".agents", "skills", SKILL_DIR_NAME),
1983
- cursor: (cwd) => path2.join(cwd, ".cursor", "skills", SKILL_DIR_NAME),
1984
- claude: (cwd) => path2.join(cwd, ".claude", "skills", SKILL_DIR_NAME),
1985
- windsurf: (cwd) => path2.join(cwd, ".windsurf", "skills", SKILL_DIR_NAME),
1986
- gemini: (cwd) => path2.join(cwd, ".gemini", "skills", SKILL_DIR_NAME),
1987
- codex: (cwd) => path2.join(cwd, ".codex", "skills", SKILL_DIR_NAME),
1988
- opencode: (cwd) => path2.join(cwd, ".opencode", "skills", SKILL_DIR_NAME),
1989
- kilo: (cwd) => path2.join(cwd, ".kilo", "skills", SKILL_DIR_NAME),
1990
- openclaw: (cwd) => path2.join(cwd, "skills", SKILL_DIR_NAME),
1991
- workbuddy: (cwd) => path2.join(cwd, ".workbuddy", "skills", SKILL_DIR_NAME)
1992
- };
1993
- var GLOBAL_DIRS = {
1994
- agents: (home) => path2.join(home, ".agents", "skills", SKILL_DIR_NAME),
1995
- cursor: (home) => path2.join(home, ".cursor", "skills", SKILL_DIR_NAME),
1996
- claude: (home) => path2.join(home, ".claude", "skills", SKILL_DIR_NAME),
1997
- windsurf: (home) => path2.join(home, ".codeium", "windsurf", "skills", SKILL_DIR_NAME),
1998
- gemini: (home) => path2.join(home, ".gemini", "skills", SKILL_DIR_NAME),
1999
- codex: (home) => path2.join(home, ".codex", "skills", SKILL_DIR_NAME),
2000
- opencode: (home) => path2.join(home, ".config", "opencode", "skills", SKILL_DIR_NAME),
2001
- kilo: (home) => path2.join(home, ".kilo", "skills", SKILL_DIR_NAME),
2002
- openclaw: (home) => path2.join(home, ".openclaw", "skills", SKILL_DIR_NAME),
2003
- workbuddy: (home) => path2.join(home, ".workbuddy", "skills", SKILL_DIR_NAME)
2004
- };
2005
- var ALL_PLATFORM_KEYS = Object.keys(PROJECT_DIRS);
2006
- function parseTargets(raw) {
2007
- const normalized = raw.trim().toLowerCase();
2008
- if (normalized === "all") {
2009
- return ALL_PLATFORM_KEYS.map((k) => ({ keys: [k], isGlobal: false }));
2010
- }
2011
- const parts = normalized.split(",").map((s) => s.trim());
2012
- const results = [];
2013
- const seen = /* @__PURE__ */ new Set();
2014
- for (const p of parts) {
2015
- let key = p;
2016
- let isGlobal = false;
2017
- if (p === "openclaw-workspace") {
2018
- key = "openclaw";
2019
- isGlobal = false;
2020
- } else if (p === "openclaw-global") {
2021
- key = "openclaw";
2022
- isGlobal = true;
2023
- } else if (p === "openclaw") {
2024
- key = "openclaw";
2025
- isGlobal = false;
2026
- } else if (p === "workbuddy-workspace") {
2027
- key = "workbuddy";
2028
- isGlobal = false;
2029
- } else if (p === "workbuddy-global") {
2030
- key = "workbuddy";
2031
- isGlobal = true;
2032
- } else if (p === "workbuddy") {
2033
- key = "workbuddy";
2034
- isGlobal = false;
2035
- }
2036
- if (!ALL_PLATFORM_KEYS.includes(key)) {
2037
- console.error(
2038
- `\u672A\u77E5\u5E73\u53F0: ${p}\u3002\u53EF\u9009: ${ALL_PLATFORM_KEYS.join(", ")}, openclaw-workspace, openclaw-global, workbuddy-workspace, workbuddy-global, all`
2039
- );
2040
- process.exitCode = 1;
2041
- return [];
2042
- }
2043
- const uid = `${key}:${isGlobal}`;
2044
- if (!seen.has(uid)) {
2045
- seen.add(uid);
2046
- results.push({ keys: [key], isGlobal });
2047
- }
2048
- }
2049
- return results;
2050
- }
2051
- function skillRoot() {
2052
- return path2.join(__dirname, "skill");
2053
- }
2054
- function saveInstalledTargets(newEntries) {
2055
- const CONFIG_FILE4 = path2.join(os.homedir(), ".siluzan", "config.json");
2056
- try {
2057
- fsSync.mkdirSync(path2.dirname(CONFIG_FILE4), { recursive: true });
2058
- let existing = {};
2059
- if (fsSync.existsSync(CONFIG_FILE4)) {
2060
- existing = JSON.parse(fsSync.readFileSync(CONFIG_FILE4, "utf8"));
2061
- }
2062
- const prev = Array.isArray(existing.installedTargets) ? existing.installedTargets : [];
2063
- const merged = /* @__PURE__ */ new Map();
2064
- for (const e of [...prev, ...newEntries]) {
2065
- merged.set(`${e.target}::${e.cwd}`, e);
2066
- }
2067
- fsSync.writeFileSync(
2068
- CONFIG_FILE4,
2069
- JSON.stringify({ ...existing, installedTargets: [...merged.values()] }, null, 2),
2070
- "utf8"
2071
- );
2072
- if (process.platform !== "win32") {
2073
- fsSync.chmodSync(CONFIG_FILE4, 384);
2074
- }
2075
- } catch {
2076
- }
2077
- }
2078
- async function writeSkillFilesToDir(destDir, skillFiles, force) {
2079
- await fs2.mkdir(destDir, { recursive: true });
2080
- let anyWritten = false;
2081
- for (const [relativePath, content] of Object.entries(skillFiles)) {
2082
- const fullPath = path2.join(destDir, relativePath);
2083
- await fs2.mkdir(path2.dirname(fullPath), { recursive: true });
2084
- try {
2085
- await fs2.access(fullPath);
2086
- if (!force) {
2087
- console.warn(`\u8DF3\u8FC7\uFF08\u5DF2\u5B58\u5728\uFF0C\u4F7F\u7528 --force \u8986\u76D6\uFF09: ${fullPath}`);
2088
- continue;
2089
- }
2090
- } catch {
2091
- }
2092
- await fs2.writeFile(fullPath, content, "utf8");
2093
- console.log(`\u5DF2\u5199\u5165: ${fullPath}`);
2094
- anyWritten = true;
2095
- }
2096
- return anyWritten;
2097
- }
2098
- async function runInit(options) {
2099
- const home = os.homedir();
2100
- const skillFiles = await getSkillFiles(skillRoot(), options.apiBaseUrl);
2101
- const installedEntries = [];
2102
- if (options.dir) {
2103
- const destDir = path2.resolve(options.cwd, options.dir);
2104
- console.log(`\u5B89\u88C5\u76EE\u6807\u76EE\u5F55\uFF1A${destDir}`);
2105
- const anyWritten = await writeSkillFilesToDir(destDir, skillFiles, options.force);
2106
- if (anyWritten) {
2107
- installedEntries.push({ target: "custom", cwd: "", dir: destDir });
2108
- }
2109
- } else if (options.global) {
2110
- for (const key of ALL_PLATFORM_KEYS) {
2111
- const destDir = GLOBAL_DIRS[key](home);
2112
- console.log(`[${key} global] \u2192 ${destDir}`);
2113
- const anyWritten = await writeSkillFilesToDir(destDir, skillFiles, options.force);
2114
- if (anyWritten) {
2115
- installedEntries.push({ target: `${key}-global`, cwd: "" });
2116
- }
2117
- }
2118
- } else {
2119
- const targets = parseTargets(options.aiTargets);
2120
- if (targets.length === 0) return;
2121
- for (const entry of targets) {
2122
- for (const key of entry.keys) {
2123
- const destDir = entry.isGlobal ? GLOBAL_DIRS[key](home) : PROJECT_DIRS[key](options.cwd);
2124
- const label = entry.isGlobal ? `${key} global` : key;
2125
- console.log(`[${label}] \u2192 ${destDir}`);
2126
- const anyWritten = await writeSkillFilesToDir(destDir, skillFiles, options.force);
2127
- if (anyWritten) {
2128
- installedEntries.push({
2129
- target: entry.isGlobal ? `${key}-global` : key,
2130
- cwd: entry.isGlobal ? "" : options.cwd
2131
- });
2132
- }
2133
- }
2134
- }
2135
- }
2136
- if (installedEntries.length > 0) {
2137
- saveInstalledTargets(installedEntries);
2138
- }
2139
- console.log("\n\u4E0B\u4E00\u6B65\uFF1A");
2140
- console.log("1. \u9996\u6B21\u4F7F\u7528\u8BF7\u8FD0\u884C\uFF1Asiluzan-cso login \uFF08\u5F15\u5BFC\u6CE8\u518C/\u767B\u5F55\u5E76\u4FDD\u5B58 Token\uFF09");
2141
- console.log("2. \u540E\u7EED\u5347\u7EA7\u8FD0\u884C\uFF1Asiluzan-cso update \uFF08\u81EA\u52A8\u66F4\u65B0 CLI \u4E0E skill \u6587\u4EF6\uFF09");
2142
- }
2143
-
2144
- // src/commands/login.ts
2145
- import * as readline from "readline";
2146
-
2147
1938
  // ../common/dist/index.js
2148
- var import_semver = __toESM(require_semver2(), 1);
2149
- import * as fs3 from "fs";
2150
- import * as path3 from "path";
2151
- import * as os2 from "os";
1939
+ import * as fs from "fs";
1940
+ import * as path from "path";
1941
+ import * as os from "os";
1942
+ import lockfile from "proper-lockfile";
2152
1943
  import * as https from "https";
2153
1944
  import * as http from "http";
2154
1945
  import * as zlib from "zlib";
2155
1946
  import { performance } from "perf_hooks";
2156
- import { randomUUID as _randomUUID } from "crypto";
2157
- import * as fs22 from "fs";
2158
- import * as path22 from "path";
2159
- import { fileURLToPath as fileURLToPath2 } from "url";
2160
- var SILUZAN_DIR = path3.join(os2.homedir(), ".siluzan");
2161
- var CONFIG_FILE = path3.join(SILUZAN_DIR, "config.json");
1947
+ var import_semver = __toESM(require_semver2(), 1);
1948
+ import * as fs2 from "fs";
1949
+ import * as path2 from "path";
1950
+ import { fileURLToPath } from "url";
1951
+ import Table from "cli-table3";
1952
+ var SILUZAN_DIR = path.join(os.homedir(), ".siluzan");
1953
+ var CONFIG_FILE = path.join(SILUZAN_DIR, "config.json");
2162
1954
  function atomicWriteFileSync(targetPath, content, encoding = "utf8") {
2163
- const dir = path3.dirname(targetPath);
2164
- const tmp = path3.join(
1955
+ const dir = path.dirname(targetPath);
1956
+ const tmp = path.join(
2165
1957
  dir,
2166
- `.${path3.basename(targetPath)}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}`
1958
+ `.${path.basename(targetPath)}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2, 8)}`
2167
1959
  );
2168
1960
  try {
2169
- fs3.writeFileSync(tmp, content, encoding);
2170
- fs3.renameSync(tmp, targetPath);
1961
+ fs.writeFileSync(tmp, content, encoding);
1962
+ fs.renameSync(tmp, targetPath);
2171
1963
  } catch (err) {
2172
1964
  try {
2173
- fs3.unlinkSync(tmp);
1965
+ fs.unlinkSync(tmp);
2174
1966
  } catch {
2175
1967
  }
2176
1968
  try {
2177
- fs3.writeFileSync(targetPath, content, encoding);
1969
+ fs.writeFileSync(targetPath, content, encoding);
2178
1970
  } catch {
2179
1971
  throw err;
2180
1972
  }
@@ -2185,11 +1977,11 @@ function readStr(raw, key) {
2185
1977
  return typeof v === "string" && v ? v : void 0;
2186
1978
  }
2187
1979
  function readSharedConfig() {
2188
- if (!fs3.existsSync(CONFIG_FILE)) {
1980
+ if (!fs.existsSync(CONFIG_FILE)) {
2189
1981
  return { authToken: "" };
2190
1982
  }
2191
1983
  try {
2192
- const raw = JSON.parse(fs3.readFileSync(CONFIG_FILE, "utf8"));
1984
+ const raw = JSON.parse(fs.readFileSync(CONFIG_FILE, "utf8"));
2193
1985
  return {
2194
1986
  authToken: readStr(raw, "authToken") ?? "",
2195
1987
  apiKey: readStr(raw, "apiKey"),
@@ -2200,11 +1992,11 @@ function readSharedConfig() {
2200
1992
  }
2201
1993
  }
2202
1994
  function writeSharedConfig(partial) {
2203
- fs3.mkdirSync(SILUZAN_DIR, { recursive: true });
1995
+ fs.mkdirSync(SILUZAN_DIR, { recursive: true });
2204
1996
  let existing = {};
2205
- if (fs3.existsSync(CONFIG_FILE)) {
1997
+ if (fs.existsSync(CONFIG_FILE)) {
2206
1998
  try {
2207
- existing = JSON.parse(fs3.readFileSync(CONFIG_FILE, "utf8"));
1999
+ existing = JSON.parse(fs.readFileSync(CONFIG_FILE, "utf8"));
2208
2000
  } catch {
2209
2001
  }
2210
2002
  }
@@ -2215,12 +2007,59 @@ function writeSharedConfig(partial) {
2215
2007
  atomicWriteFileSync(CONFIG_FILE, JSON.stringify(existing, null, 2));
2216
2008
  if (process.platform !== "win32") {
2217
2009
  try {
2218
- fs3.chmodSync(CONFIG_FILE, 384);
2010
+ fs.chmodSync(CONFIG_FILE, 384);
2219
2011
  } catch {
2220
2012
  console.warn("\u26A0\uFE0F \u672A\u80FD\u6536\u655B\u914D\u7F6E\u6587\u4EF6\u6743\u9650\uFF0C\u8BF7\u624B\u52A8\u6267\u884C\uFF1Achmod 600 " + CONFIG_FILE);
2221
2013
  }
2222
2014
  }
2223
2015
  }
2016
+ function readSharedConfigRaw() {
2017
+ if (!fs.existsSync(CONFIG_FILE)) return {};
2018
+ try {
2019
+ return JSON.parse(fs.readFileSync(CONFIG_FILE, "utf8"));
2020
+ } catch {
2021
+ return {};
2022
+ }
2023
+ }
2024
+ var inProcessLockChain = Promise.resolve();
2025
+ async function mergeWriteSharedConfig(partial) {
2026
+ const next = inProcessLockChain.then(() => doMergeWriteOnce(partial));
2027
+ inProcessLockChain = next.catch(() => void 0);
2028
+ return next;
2029
+ }
2030
+ async function doMergeWriteOnce(partial) {
2031
+ fs.mkdirSync(SILUZAN_DIR, { recursive: true });
2032
+ if (!fs.existsSync(CONFIG_FILE)) {
2033
+ fs.writeFileSync(CONFIG_FILE, "{}", "utf8");
2034
+ if (process.platform !== "win32") {
2035
+ try {
2036
+ fs.chmodSync(CONFIG_FILE, 384);
2037
+ } catch {
2038
+ }
2039
+ }
2040
+ }
2041
+ const release = await lockfile.lock(CONFIG_FILE, {
2042
+ realpath: false,
2043
+ retries: { retries: 30, factor: 1.1, minTimeout: 50, maxTimeout: 600 },
2044
+ stale: 1e4
2045
+ });
2046
+ try {
2047
+ const existing = readSharedConfigRaw();
2048
+ const merged = { ...existing };
2049
+ for (const [k, v] of Object.entries(partial)) {
2050
+ if (v !== void 0) merged[k] = v;
2051
+ }
2052
+ atomicWriteFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2));
2053
+ if (process.platform !== "win32") {
2054
+ try {
2055
+ fs.chmodSync(CONFIG_FILE, 384);
2056
+ } catch {
2057
+ }
2058
+ }
2059
+ } finally {
2060
+ await release();
2061
+ }
2062
+ }
2224
2063
  function clearSharedConfig() {
2225
2064
  writeSharedConfig({ authToken: "", apiKey: "" });
2226
2065
  }
@@ -2244,12 +2083,12 @@ function validateBaseUrl(raw) {
2244
2083
  if (url.protocol !== "https:") {
2245
2084
  return `\u5FC5\u987B\u4F7F\u7528 HTTPS\uFF0C\u5F53\u524D\u534F\u8BAE\uFF1A${url.protocol}`;
2246
2085
  }
2247
- const hostname = url.hostname.toLowerCase();
2086
+ const hostname2 = url.hostname.toLowerCase();
2248
2087
  const ok = ALLOWED_HOSTNAME_SUFFIXES.some(
2249
- (suffix) => hostname === suffix || hostname.endsWith(`.${suffix}`)
2088
+ (suffix) => hostname2 === suffix || hostname2.endsWith(`.${suffix}`)
2250
2089
  );
2251
2090
  if (!ok) {
2252
- return `\u4E3B\u673A\u540D "${hostname}" \u4E0D\u5728\u5141\u8BB8\u5217\u8868\uFF08${ALLOWED_HOSTNAME_SUFFIXES.join("\u3001")}\uFF09\u5185\u3002
2091
+ return `\u4E3B\u673A\u540D "${hostname2}" \u4E0D\u5728\u5141\u8BB8\u5217\u8868\uFF08${ALLOWED_HOSTNAME_SUFFIXES.join("\u3001")}\uFF09\u5185\u3002
2253
2092
  \u5982\u9700\u8FDE\u63A5\u81EA\u5B9A\u4E49\u90E8\u7F72\u7AEF\u70B9\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u767D\u540D\u5355\u3002`;
2254
2093
  }
2255
2094
  return null;
@@ -2286,7 +2125,7 @@ function rawRequest(url, options) {
2286
2125
  const perfOn = isPerfEnabled();
2287
2126
  const t0 = perfOn ? performance.now() : 0;
2288
2127
  const method = options.method ?? "GET";
2289
- return new Promise((resolve22, reject) => {
2128
+ return new Promise((resolve32, reject) => {
2290
2129
  const parsed = new URL(url);
2291
2130
  const transport = parsed.protocol === "https:" ? https : http;
2292
2131
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
@@ -2371,7 +2210,7 @@ function rawRequest(url, options) {
2371
2210
  ok: status >= 200 && status < 300
2372
2211
  });
2373
2212
  }
2374
- resolve22({ status, text: data, headers });
2213
+ resolve32({ status, text: data, headers });
2375
2214
  });
2376
2215
  });
2377
2216
  req.on("timeout", () => {
@@ -2469,12 +2308,11 @@ function isUUID(value) {
2469
2308
  if (typeof value !== "string") return false;
2470
2309
  return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
2471
2310
  }
2472
- var randomUUID = _randomUUID;
2473
2311
  function getCurrentVersion(importMetaUrl) {
2474
2312
  try {
2475
- const __dirname2 = path22.dirname(fileURLToPath2(importMetaUrl));
2476
- const pkgPath = path22.join(__dirname2, "..", "package.json");
2477
- const pkg = JSON.parse(fs22.readFileSync(pkgPath, "utf8"));
2313
+ const __dirname2 = path2.dirname(fileURLToPath(importMetaUrl));
2314
+ const pkgPath = path2.join(__dirname2, "..", "package.json");
2315
+ const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf8"));
2478
2316
  return pkg.version ?? "0.0.0";
2479
2317
  } catch {
2480
2318
  return "0.0.0";
@@ -2503,61 +2341,262 @@ async function fetchNpmVersion(pkgName, tag, timeoutMs = 4e3) {
2503
2341
  return null;
2504
2342
  }
2505
2343
  }
2506
- function deriveMainApiOrigin(apiBase) {
2507
- try {
2508
- const u = new URL(apiBase);
2509
- const host = u.hostname.toLowerCase();
2510
- const isCi = apiBase.includes("-ci");
2511
- if (host.endsWith("siluzan.com") || host.endsWith("siluzan.cn")) {
2512
- if (host.startsWith("tso-api")) {
2513
- const suffix = host.endsWith("siluzan.cn") ? "siluzan.cn" : "siluzan.com";
2514
- const apiHost = isCi ? `api-ci.${suffix}` : `api.${suffix}`;
2515
- return `${u.protocol}//${apiHost}${u.port ? `:${u.port}` : ""}`;
2516
- }
2517
- if (host === "api.siluzan.com" || host === "api-ci.siluzan.com" || host === "api.siluzan.cn" || host === "api-ci.siluzan.cn") {
2518
- return `${u.protocol}//${host}${u.port ? `:${u.port}` : ""}`;
2344
+ function createVersionNotifier(opts) {
2345
+ const {
2346
+ pkgName,
2347
+ binName,
2348
+ cachePrefix,
2349
+ resolveTag,
2350
+ forceUpdateExtra = "",
2351
+ updateAvailableExtra = "",
2352
+ getCurrentVersion: getCurrentVersion22,
2353
+ mergeWriteConfig,
2354
+ readConfigRaw
2355
+ } = opts;
2356
+ const KEY_LAST_CHECK = `${cachePrefix}LastVersionCheck`;
2357
+ const KEY_LATEST_STABLE = `${cachePrefix}LatestStable`;
2358
+ const KEY_LATEST_BETA = `${cachePrefix}LatestBeta`;
2359
+ const KEY_MIN_STABLE = `${cachePrefix}MinRequiredStable`;
2360
+ const KEY_MIN_BETA = `${cachePrefix}MinRequiredBeta`;
2361
+ const KEY_LAST_NOTIFIED = `${cachePrefix}LastNotified`;
2362
+ const HOURS_24 = 24 * 60 * 60 * 1e3;
2363
+ async function fetchVersionByTag(tag, cacheKey, cfg) {
2364
+ const lastCheck = cfg[KEY_LAST_CHECK];
2365
+ if (typeof lastCheck === "string" && cacheKey in cfg) {
2366
+ const lastMs = new Date(lastCheck).getTime();
2367
+ if (Date.now() - lastMs < HOURS_24) {
2368
+ const v = cfg[cacheKey];
2369
+ return typeof v === "string" && v ? v : null;
2519
2370
  }
2520
- return isCi ? "https://api-ci.siluzan.com" : "https://api.siluzan.com";
2521
2371
  }
2522
- return isCi ? "https://api-ci.siluzan.com" : "https://api.siluzan.com";
2523
- } catch {
2524
- return apiBase.includes("-ci") ? "https://api-ci.siluzan.com" : "https://api.siluzan.com";
2372
+ return fetchNpmVersion(pkgName, tag);
2525
2373
  }
2526
- }
2527
- function pickStr(obj, key) {
2528
- const v = obj[key];
2529
- return typeof v === "string" && v.trim() ? v.trim() : void 0;
2530
- }
2531
- function pickCompanyId(data) {
2532
- const direct = pickStr(data, "companyId") ?? pickStr(data, "companyID") ?? pickStr(data, "CompanyId");
2533
- if (direct) return direct;
2534
- const ci = data["companyInfo"];
2535
- if (ci && typeof ci === "object") {
2536
- const o = ci;
2537
- return pickStr(o, "id") ?? pickStr(o, "companyId") ?? pickStr(o, "companyID");
2374
+ async function notifyIfOutdated2() {
2375
+ try {
2376
+ const current = getCurrentVersion22();
2377
+ const tag = resolveTag(current);
2378
+ const isBeta = tag === "beta";
2379
+ const latestCacheKey = isBeta ? KEY_LATEST_BETA : KEY_LATEST_STABLE;
2380
+ const minCacheKey = isBeta ? KEY_MIN_BETA : KEY_MIN_STABLE;
2381
+ const minTag = npmMinRequiredTagForBuildEnv(isBeta ? "test" : "production");
2382
+ const cfg = readConfigRaw();
2383
+ const [latest, minRequired] = await Promise.all([
2384
+ fetchVersionByTag(tag, latestCacheKey, cfg),
2385
+ fetchVersionByTag(minTag, minCacheKey, cfg)
2386
+ ]);
2387
+ await mergeWriteConfig({
2388
+ [KEY_LAST_CHECK]: (/* @__PURE__ */ new Date()).toISOString(),
2389
+ [latestCacheKey]: latest ?? "",
2390
+ [minCacheKey]: minRequired ?? ""
2391
+ });
2392
+ const lastNotified = typeof cfg[KEY_LAST_NOTIFIED] === "string" ? new Date(cfg[KEY_LAST_NOTIFIED]).getTime() : 0;
2393
+ if (Date.now() - lastNotified < HOURS_24) return;
2394
+ const tagLabel = isBeta ? "\uFF08\u6D4B\u8BD5\u7248\uFF09" : "\uFF08\u6B63\u5F0F\u7248\uFF09";
2395
+ if (minRequired && isNewer(current, minRequired)) {
2396
+ await mergeWriteConfig({ [KEY_LAST_NOTIFIED]: (/* @__PURE__ */ new Date()).toISOString() });
2397
+ console.log(
2398
+ `
2399
+ [SILUZAN_FORCE_UPDATE] \u5F53\u524D\u7248\u672C ${current} \u5DF2\u8FC7\u671F\uFF0C\u6700\u4F4E\u8981\u6C42\u7248\u672C ${minRequired}${tagLabel}
2400
+ \u26D4 \u5FC5\u987B\u5148\u5347\u7EA7\u624D\u80FD\u7EE7\u7EED\u4F7F\u7528\uFF0CAgent \u8BF7\u7ACB\u5373\u6267\u884C\uFF1A${binName} update
2401
+ \u6216\u624B\u52A8\uFF1Anpm install -g ${pkgName}@${tag}
2402
+ ` + (forceUpdateExtra ? forceUpdateExtra + "\n" : "")
2403
+ );
2404
+ return;
2405
+ }
2406
+ if (latest && isNewer(current, latest)) {
2407
+ await mergeWriteConfig({ [KEY_LAST_NOTIFIED]: (/* @__PURE__ */ new Date()).toISOString() });
2408
+ console.log(
2409
+ `
2410
+ [SILUZAN_UPDATE_AVAILABLE] \u53D1\u73B0\u65B0\u7248\u672C ${latest}${tagLabel}\uFF08\u5F53\u524D ${current}\uFF09
2411
+ \u{1F4A1} Agent \u8BF7\u7ACB\u5373\u6267\u884C\uFF1A${binName} update
2412
+ \u6216\u624B\u52A8\uFF1Anpm install -g ${pkgName}@${tag}
2413
+ ` + (updateAvailableExtra ? updateAvailableExtra + "\n" : "")
2414
+ );
2415
+ }
2416
+ } catch {
2417
+ }
2538
2418
  }
2539
- return void 0;
2540
- }
2541
- function parseMeResponse(text) {
2542
- try {
2543
- const json = JSON.parse(text);
2544
- const data = json?.data && typeof json.data === "object" ? json.data : json;
2545
- const id = pickStr(data, "entityId") ?? pickStr(data, "id") ?? pickStr(data, "userId") ?? pickStr(data, "accountId");
2546
- const email = pickStr(data, "email");
2547
- const username = pickStr(data, "userName") ?? pickStr(data, "username") ?? pickStr(data, "name") ?? pickStr(data, "phone");
2548
- const companyId = pickCompanyId(data);
2549
- if (!id && !email && !username && !companyId) return null;
2550
- return { id, email, username, companyId };
2551
- } catch {
2552
- return null;
2419
+ async function fetchLatestVersion2() {
2420
+ const current = getCurrentVersion22();
2421
+ const tag = resolveTag(current);
2422
+ return fetchNpmVersion(pkgName, tag);
2553
2423
  }
2424
+ return { notifyIfOutdated: notifyIfOutdated2, fetchLatestVersion: fetchLatestVersion2 };
2554
2425
  }
2555
- async function fetchSiluzanCurrentUser(apiBase, config) {
2556
- const mainOrigin = deriveMainApiOrigin(apiBase);
2557
- const meUrl = `${mainOrigin.replace(/\/$/, "")}/query/account/me`;
2558
- const authHeaders = config.apiKey ? { "x-api-key": config.apiKey } : { Authorization: `Bearer ${config.authToken}` };
2559
- try {
2560
- const res = await rawRequest(meUrl, {
2426
+ var ASCII_TABLE_CHARS = {
2427
+ top: "-",
2428
+ "top-mid": "+",
2429
+ "top-left": "+",
2430
+ "top-right": "+",
2431
+ bottom: "-",
2432
+ "bottom-mid": "+",
2433
+ "bottom-left": "+",
2434
+ "bottom-right": "+",
2435
+ left: "|",
2436
+ "left-mid": "+",
2437
+ mid: "-",
2438
+ "mid-mid": "+",
2439
+ right: "|",
2440
+ "right-mid": "+",
2441
+ middle: "|"
2442
+ };
2443
+ function printCliTable(rows, columns, options) {
2444
+ if (rows.length === 0) return;
2445
+ const plain = options?.plain !== false;
2446
+ const indent = options?.indent ?? " ";
2447
+ const printLine = options?.printLine ?? ((msg) => {
2448
+ console.log(msg);
2449
+ });
2450
+ const table = new Table({
2451
+ head: columns.map((c) => c.header),
2452
+ chars: plain ? { ...ASCII_TABLE_CHARS } : void 0,
2453
+ style: plain ? { head: [], border: [] } : void 0
2454
+ });
2455
+ for (const r of rows) {
2456
+ table.push(columns.map((c) => String(r[c.key] ?? "")));
2457
+ }
2458
+ for (const line of table.toString().split("\n")) {
2459
+ printLine(indent + line);
2460
+ }
2461
+ }
2462
+ function computeTotalPages(total, pageSize) {
2463
+ if (pageSize <= 0) return 0;
2464
+ return Math.ceil(total / pageSize);
2465
+ }
2466
+ function formatPaginationSummary(params) {
2467
+ const totalPages = params.totalPagesOverride !== void 0 ? params.totalPagesOverride : computeTotalPages(params.total, params.pageSize);
2468
+ return `\u9875\u7801/\u5F53\u524D\u9875\uFF1A${params.page}\uFF0C\u603B\u6761\u6570\uFF1A${params.total}\uFF0C\u603B\u9875\u6570\uFF1A${totalPages}\uFF0C\u6BCF\u9875\uFF1A${params.pageSize} \u6761`;
2469
+ }
2470
+ function installProcessHandlers() {
2471
+ process.on("uncaughtException", (err) => {
2472
+ console.error(`
2473
+ \u274C \u672A\u6355\u83B7\u7684\u5F02\u5E38\uFF1A${err.message}`);
2474
+ if (process.argv.includes("--verbose")) console.error(err.stack);
2475
+ process.exit(1);
2476
+ });
2477
+ process.on("unhandledRejection", (reason) => {
2478
+ const msg = reason instanceof Error ? reason.message : String(reason);
2479
+ console.error(`
2480
+ \u274C \u672A\u5904\u7406\u7684\u5F02\u6B65\u9519\u8BEF\uFF1A${msg}`);
2481
+ if (process.argv.includes("--verbose") && reason instanceof Error) {
2482
+ console.error(reason.stack);
2483
+ }
2484
+ process.exit(1);
2485
+ });
2486
+ }
2487
+ function printAuthMissingHelp(binName) {
2488
+ console.error(
2489
+ `
2490
+ \u274C \u672A\u627E\u5230\u8BA4\u8BC1\u51ED\u636E\u3002\u8BF7\u9009\u62E9\u4EE5\u4E0B\u4EFB\u610F\u4E00\u79CD\u65B9\u5F0F\uFF1A
2491
+
2492
+ \u65B9\u5F0F\u4E00\uFF08\u63A8\u8350\uFF09\uFF1AAPI Key
2493
+ \u5728\u4E1D\u8DEF\u8D5E\u300C\u8BBE\u7F6E \u2192 API Key \u7BA1\u7406\u300D\u521B\u5EFA API Key\uFF0C\u7136\u540E\u8FD0\u884C\uFF1A
2494
+ ${binName} login --api-key <YOUR_API_KEY>
2495
+
2496
+ \u65B9\u5F0F\u4E8C\uFF1A\u73AF\u5883\u53D8\u91CF\uFF08CI/CD \u63A8\u8350\uFF09
2497
+ export SILUZAN_API_KEY=<YOUR_API_KEY>
2498
+ # \u6216 export SILUZAN_AUTH_TOKEN=<YOUR_TOKEN>
2499
+
2500
+ \u65B9\u5F0F\u4E09\uFF1AJWT Token
2501
+ ${binName} login
2502
+ `
2503
+ );
2504
+ process.exit(1);
2505
+ }
2506
+ function defineCommand(spec) {
2507
+ const hasListPagination = (spec.flags ?? []).includes("listPagination");
2508
+ const hasWriteCommit = (spec.flags ?? []).includes("writeCommit");
2509
+ return (program2) => {
2510
+ const cmd = program2.command(spec.name).description(spec.description);
2511
+ for (const opt of spec.options ?? []) {
2512
+ const apply = opt.required ? cmd.requiredOption.bind(cmd) : cmd.option.bind(cmd);
2513
+ if (opt.defaultValue !== void 0) {
2514
+ apply(opt.flags, opt.description, opt.defaultValue);
2515
+ } else {
2516
+ apply(opt.flags, opt.description);
2517
+ }
2518
+ }
2519
+ if (hasListPagination) {
2520
+ cmd.option("--page <n>", "\u9875\u7801\uFF08\u4ECE 1 \u5F00\u59CB\uFF09", "1").option("--page-size <n>", "\u6BCF\u9875\u6761\u6570", "20").option("--keyword <text>", "\u641C\u7D22\u5173\u952E\u8BCD");
2521
+ }
2522
+ if (hasWriteCommit) {
2523
+ cmd.option("--commit <text>", "\u672C\u6B21\u5199\u64CD\u4F5C\u8BF4\u660E\uFF08\u5199\u547D\u4EE4\u5FC5\u586B\uFF0C\u4F1A\u5199\u5165\u5BA1\u8BA1\u65E5\u5FD7\uFF09");
2524
+ }
2525
+ cmd.option("--json", "\u8F93\u51FA\u539F\u59CB JSON\uFF08stdout\uFF09").option("--json-out <path>", "JSON \u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84\uFF08\u66FF\u4EE3 --json\uFF09").option("--verbose", "\u8F93\u51FA\u8BE6\u7EC6\u9519\u8BEF\u5806\u6808").option("--token <jwt>", "\u4E34\u65F6\u4F7F\u7528\u7684 JWT Token\uFF08\u8986\u76D6 ~/.siluzan/config.json\uFF09");
2526
+ if (hasWriteCommit) {
2527
+ cmd.hook("preAction", (thisCmd) => {
2528
+ const opts = thisCmd.opts();
2529
+ const commit = (opts.commit ?? "").trim();
2530
+ if (commit === "") {
2531
+ console.error(
2532
+ `
2533
+ \u274C \u5199\u64CD\u4F5C\u5FC5\u987B\u63D0\u4F9B\u8BF4\u660E\uFF1A\u8BF7\u4F7F\u7528 --commit "..." \u63CF\u8FF0\u672C\u6B21\u64CD\u4F5C\u7684\u76EE\u7684\u4E0E\u4E0A\u4E0B\u6587`
2534
+ );
2535
+ process.exit(1);
2536
+ }
2537
+ });
2538
+ }
2539
+ cmd.action(async (raw) => {
2540
+ await spec.handler(raw);
2541
+ });
2542
+ return cmd;
2543
+ };
2544
+ }
2545
+ function deriveMainApiOrigin(apiBase) {
2546
+ try {
2547
+ const u = new URL(apiBase);
2548
+ const host = u.hostname.toLowerCase();
2549
+ const isCi = apiBase.includes("-ci");
2550
+ if (host.endsWith("siluzan.com") || host.endsWith("siluzan.cn")) {
2551
+ if (host.startsWith("tso-api")) {
2552
+ const suffix = host.endsWith("siluzan.cn") ? "siluzan.cn" : "siluzan.com";
2553
+ const apiHost = isCi ? `api-ci.${suffix}` : `api.${suffix}`;
2554
+ return `${u.protocol}//${apiHost}${u.port ? `:${u.port}` : ""}`;
2555
+ }
2556
+ if (host === "api.siluzan.com" || host === "api-ci.siluzan.com" || host === "api.siluzan.cn" || host === "api-ci.siluzan.cn") {
2557
+ return `${u.protocol}//${host}${u.port ? `:${u.port}` : ""}`;
2558
+ }
2559
+ return isCi ? "https://api-ci.siluzan.com" : "https://api.siluzan.com";
2560
+ }
2561
+ return isCi ? "https://api-ci.siluzan.com" : "https://api.siluzan.com";
2562
+ } catch {
2563
+ return apiBase.includes("-ci") ? "https://api-ci.siluzan.com" : "https://api.siluzan.com";
2564
+ }
2565
+ }
2566
+ function pickStr(obj, key) {
2567
+ const v = obj[key];
2568
+ return typeof v === "string" && v.trim() ? v.trim() : void 0;
2569
+ }
2570
+ function pickCompanyId(data) {
2571
+ const direct = pickStr(data, "companyId") ?? pickStr(data, "companyID") ?? pickStr(data, "CompanyId");
2572
+ if (direct) return direct;
2573
+ const ci = data["companyInfo"];
2574
+ if (ci && typeof ci === "object") {
2575
+ const o = ci;
2576
+ return pickStr(o, "id") ?? pickStr(o, "companyId") ?? pickStr(o, "companyID");
2577
+ }
2578
+ return void 0;
2579
+ }
2580
+ function parseMeResponse(text) {
2581
+ try {
2582
+ const json = JSON.parse(text);
2583
+ const data = json?.data && typeof json.data === "object" ? json.data : json;
2584
+ const id = pickStr(data, "entityId") ?? pickStr(data, "id") ?? pickStr(data, "userId") ?? pickStr(data, "accountId");
2585
+ const email = pickStr(data, "email");
2586
+ const username = pickStr(data, "userName") ?? pickStr(data, "username") ?? pickStr(data, "name") ?? pickStr(data, "phone");
2587
+ const companyId = pickCompanyId(data);
2588
+ if (!id && !email && !username && !companyId) return null;
2589
+ return { id, email, username, companyId };
2590
+ } catch {
2591
+ return null;
2592
+ }
2593
+ }
2594
+ async function fetchSiluzanCurrentUser(apiBase, config) {
2595
+ const mainOrigin = deriveMainApiOrigin(apiBase);
2596
+ const meUrl = `${mainOrigin.replace(/\/$/, "")}/query/account/me`;
2597
+ const authHeaders = config.apiKey ? { "x-api-key": config.apiKey } : { Authorization: `Bearer ${config.authToken}` };
2598
+ try {
2599
+ const res = await rawRequest(meUrl, {
2561
2600
  method: "GET",
2562
2601
  headers: {
2563
2602
  "Content-Type": "application/json",
@@ -2583,8 +2622,533 @@ var MAX_SEGMENT_BYTES = 50 * 1024 * 1024;
2583
2622
  var MAX_RETENTION_DAYS = 366 * 5;
2584
2623
  var PRUNE_THROTTLE_MS = 60 * 60 * 1e3;
2585
2624
  var MAX_SNAPSHOT_FILE_BYTES = 2 * 1024 * 1024;
2625
+ var API_KEY_SERVICE_VALUES = {
2626
+ CSO: 0,
2627
+ TSO: 1,
2628
+ CUT: 2
2629
+ };
2630
+ function deriveSsoBaseUrl(anyApiBase) {
2631
+ try {
2632
+ const u = new URL(anyApiBase);
2633
+ u.hostname = u.hostname.replace(/^(tso-api|cso|api)/, "sso");
2634
+ return u.origin;
2635
+ } catch {
2636
+ return "https://sso.siluzan.com";
2637
+ }
2638
+ }
2639
+ function deriveCsoApiBaseUrl(anyApiBase) {
2640
+ try {
2641
+ const u = new URL(anyApiBase);
2642
+ u.hostname = u.hostname.replace(/^(tso-api|api)/, "cso");
2643
+ return u.origin;
2644
+ } catch {
2645
+ return "https://cso.siluzan.com";
2646
+ }
2647
+ }
2648
+ function normalizeChinaPhone(input) {
2649
+ if (!input) return input;
2650
+ const cleaned = input.replace(/[\s\-()\u00A0]/g, "");
2651
+ if (/^\+861\d{10}$/.test(cleaned)) {
2652
+ return cleaned;
2653
+ }
2654
+ if (/^861\d{10}$/.test(cleaned)) {
2655
+ return `+${cleaned}`;
2656
+ }
2657
+ if (/^00861\d{10}$/.test(cleaned)) {
2658
+ return `+${cleaned.slice(2)}`;
2659
+ }
2660
+ if (/^1\d{10}$/.test(cleaned)) {
2661
+ return `+86${cleaned}`;
2662
+ }
2663
+ return cleaned;
2664
+ }
2665
+ function isValidChinaPhone(input) {
2666
+ return /^\+861\d{10}$/.test(normalizeChinaPhone(input));
2667
+ }
2668
+ async function loginByPhoneCode(opts) {
2669
+ const phone = normalizeChinaPhone(opts.phone);
2670
+ const url = `${opts.ssoBaseUrl}/Account/LoginByMiniCode?phone=${encodeURIComponent(
2671
+ phone
2672
+ )}&code=${encodeURIComponent(opts.code)}&key=`;
2673
+ if (opts.verbose) {
2674
+ process.stderr.write(`[phone-login] GET ${url}
2675
+ `);
2676
+ }
2677
+ const res = await rawRequest(url, {
2678
+ method: "GET",
2679
+ headers: {
2680
+ Accept: "application/json",
2681
+ "Accept-Language": "zh-CN"
2682
+ }
2683
+ });
2684
+ if (opts.verbose) {
2685
+ process.stderr.write(
2686
+ `[phone-login] LoginByMiniCode HTTP ${res.status} body=${res.text.slice(0, 500)}
2687
+ `
2688
+ );
2689
+ }
2690
+ if (res.status < 200 || res.status >= 300) {
2691
+ throw new Error(`\u767B\u5F55\u5931\u8D25\uFF1AHTTP ${res.status}`);
2692
+ }
2693
+ let body;
2694
+ try {
2695
+ body = JSON.parse(res.text);
2696
+ } catch {
2697
+ throw new Error(`\u767B\u5F55\u54CD\u5E94\u975E JSON\uFF1A${res.text.slice(0, 120)}`);
2698
+ }
2699
+ const errMsg = body.msg ?? body.Msg ?? "";
2700
+ if (!body.token || typeof body.token === "string") {
2701
+ throw new Error(errMsg || "\u767B\u5F55\u5931\u8D25\uFF08\u540E\u7AEF\u672A\u8FD4\u56DE\u539F\u56E0\uFF09");
2702
+ }
2703
+ const token = body.token;
2704
+ const isError = token.isError ?? token.IsError ?? false;
2705
+ if (isError) {
2706
+ const err = token.errorDescription ?? token.ErrorDescription ?? token.error ?? token.Error ?? "\u672A\u77E5\u9519\u8BEF";
2707
+ throw new Error(`OAuth \u5931\u8D25\uFF1A${err}`);
2708
+ }
2709
+ let accessToken = token.accessToken ?? token.access_token ?? "";
2710
+ let tokenType = token.tokenType ?? token.token_type ?? "Bearer";
2711
+ let expiresIn = token.expiresIn ?? token.expires_in;
2712
+ if (!accessToken) {
2713
+ const rawJson = token.raw ?? token.Raw;
2714
+ if (rawJson && typeof rawJson === "string") {
2715
+ try {
2716
+ const parsed = JSON.parse(rawJson);
2717
+ accessToken = parsed.access_token ?? "";
2718
+ tokenType = parsed.token_type ?? tokenType;
2719
+ expiresIn = parsed.expires_in ?? expiresIn;
2720
+ } catch {
2721
+ }
2722
+ }
2723
+ }
2724
+ if (!accessToken) {
2725
+ throw new Error(
2726
+ `\u767B\u5F55\u54CD\u5E94\u7F3A\u5C11 access_token\uFF08\u54CD\u5E94\u5B57\u6BB5\uFF1A${Object.keys(token).join(", ") || "\u65E0"}\uFF09`
2727
+ );
2728
+ }
2729
+ return { accessToken, tokenType, expiresIn };
2730
+ }
2731
+ async function createApiKeyByBearer(opts) {
2732
+ if (opts.allowedServices.length === 0) {
2733
+ throw new Error("createApiKey \u81F3\u5C11\u9700\u8981\u4F20\u5165\u4E00\u4E2A allowedServices");
2734
+ }
2735
+ if (opts.validDays === void 0 && opts.expiresAt === void 0) {
2736
+ throw new Error("createApiKey \u5FC5\u987B\u6307\u5B9A validDays \u6216 expiresAt");
2737
+ }
2738
+ const body = JSON.stringify({
2739
+ name: opts.name,
2740
+ validDays: opts.validDays,
2741
+ expiresAt: opts.expiresAt,
2742
+ allowedServices: opts.allowedServices.map((s) => API_KEY_SERVICE_VALUES[s])
2743
+ });
2744
+ const url = `${opts.csoBaseUrl}/cso/v1/apikey`;
2745
+ if (opts.verbose) {
2746
+ process.stderr.write(`[phone-login] POST ${url} body=${body}
2747
+ `);
2748
+ }
2749
+ const res = await rawRequest(url, {
2750
+ method: "POST",
2751
+ headers: {
2752
+ "Content-Type": "application/json",
2753
+ Accept: "application/json",
2754
+ "Accept-Language": "zh-CN",
2755
+ Authorization: `Bearer ${opts.bearerToken}`,
2756
+ "Content-Length": String(Buffer.byteLength(body, "utf8"))
2757
+ },
2758
+ body
2759
+ });
2760
+ if (res.status < 200 || res.status >= 300) {
2761
+ throw new Error(`\u521B\u5EFA API Key \u5931\u8D25\uFF1AHTTP ${res.status}\uFF08${res.text.slice(0, 200)}\uFF09`);
2762
+ }
2763
+ let json;
2764
+ try {
2765
+ json = JSON.parse(res.text);
2766
+ } catch {
2767
+ throw new Error(`\u521B\u5EFA API Key \u54CD\u5E94\u975E JSON\uFF1A${res.text.slice(0, 120)}`);
2768
+ }
2769
+ const code = json.code ?? json.Code;
2770
+ if (code !== 1) {
2771
+ throw new Error(`\u521B\u5EFA API Key \u5931\u8D25\uFF1A${json.message ?? json.Message ?? "\u672A\u77E5\u9519\u8BEF"}`);
2772
+ }
2773
+ const data = json.data ?? json.Data;
2774
+ if (!data?.rawKey) {
2775
+ throw new Error("\u521B\u5EFA API Key \u54CD\u5E94\u7F3A\u5C11 rawKey \u5B57\u6BB5");
2776
+ }
2777
+ return data;
2778
+ }
2779
+ async function issueApiKeyWithPhoneCode(opts) {
2780
+ const code = opts.code?.trim() ?? "";
2781
+ if (!code) {
2782
+ throw new Error("\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A");
2783
+ }
2784
+ const tokenInfo = await loginByPhoneCode({
2785
+ ssoBaseUrl: opts.ssoBaseUrl,
2786
+ phone: opts.phone,
2787
+ code,
2788
+ verbose: opts.verbose
2789
+ });
2790
+ const apiKey = await createApiKeyByBearer({
2791
+ csoBaseUrl: opts.csoBaseUrl,
2792
+ bearerToken: tokenInfo.accessToken,
2793
+ name: opts.apiKeyName,
2794
+ validDays: opts.validDays ?? (opts.expiresAt ? void 0 : 90),
2795
+ expiresAt: opts.expiresAt,
2796
+ allowedServices: opts.allowedServices,
2797
+ verbose: opts.verbose
2798
+ });
2799
+ return apiKey;
2800
+ }
2801
+
2802
+ // src/index.ts
2803
+ import { Command } from "commander";
2804
+
2805
+ // src/commands/_register.ts
2806
+ import { Option } from "commander";
2807
+
2808
+ // src/config/defaults.ts
2809
+ var BUILD_ENV = "test";
2810
+ var DEFAULT_API_BASE = "https://api-ci.siluzan.com";
2811
+ var DEFAULT_CSO_BASE = "https://cso-ci.siluzan.com";
2812
+ var DEFAULT_WEB_BASE = "https://www-ci.siluzan.com";
2813
+ var DEFAULT_AGENT_BASE = "https://agent-ci.mysiluzan.com";
2814
+
2815
+ // src/commands/init.ts
2816
+ import * as fs4 from "fs/promises";
2817
+ import * as fsSync from "fs";
2818
+ import * as os2 from "os";
2819
+ import * as path4 from "path";
2820
+ import { fileURLToPath as fileURLToPath2 } from "url";
2821
+
2822
+ // src/templates/load-templates.ts
2823
+ import * as fs3 from "fs/promises";
2824
+ import * as path3 from "path";
2825
+ async function getSkillFiles(skillDir, apiBaseUrl) {
2826
+ const out = {};
2827
+ async function walk(dir, prefix) {
2828
+ const entries = await fs3.readdir(dir, { withFileTypes: true });
2829
+ for (const ent of entries) {
2830
+ const rel = prefix ? `${prefix}/${ent.name}` : ent.name;
2831
+ const full = path3.join(dir, ent.name);
2832
+ if (ent.isDirectory()) {
2833
+ await walk(full, rel);
2834
+ } else {
2835
+ let text = await fs3.readFile(full, "utf8");
2836
+ text = text.replace(/\{\{SILUZAN_API_BASE_URL\}\}/g, apiBaseUrl);
2837
+ out[rel] = text;
2838
+ }
2839
+ }
2840
+ }
2841
+ await walk(skillDir, "");
2842
+ return out;
2843
+ }
2844
+
2845
+ // src/commands/init.ts
2846
+ var __dirname = path4.dirname(fileURLToPath2(import.meta.url));
2847
+ var SKILL_DIR_NAME = "siluzan-platform";
2848
+ var PROJECT_DIRS = {
2849
+ agents: (cwd) => path4.join(cwd, ".agents", "skills", SKILL_DIR_NAME),
2850
+ cursor: (cwd) => path4.join(cwd, ".cursor", "skills", SKILL_DIR_NAME),
2851
+ claude: (cwd) => path4.join(cwd, ".claude", "skills", SKILL_DIR_NAME),
2852
+ windsurf: (cwd) => path4.join(cwd, ".windsurf", "skills", SKILL_DIR_NAME),
2853
+ gemini: (cwd) => path4.join(cwd, ".gemini", "skills", SKILL_DIR_NAME),
2854
+ codex: (cwd) => path4.join(cwd, ".codex", "skills", SKILL_DIR_NAME),
2855
+ opencode: (cwd) => path4.join(cwd, ".opencode", "skills", SKILL_DIR_NAME),
2856
+ kilo: (cwd) => path4.join(cwd, ".kilo", "skills", SKILL_DIR_NAME),
2857
+ openclaw: (cwd) => path4.join(cwd, "skills", SKILL_DIR_NAME),
2858
+ workbuddy: (cwd) => path4.join(cwd, ".workbuddy", "skills", SKILL_DIR_NAME)
2859
+ };
2860
+ var GLOBAL_DIRS = {
2861
+ agents: (home) => path4.join(home, ".agents", "skills", SKILL_DIR_NAME),
2862
+ cursor: (home) => path4.join(home, ".cursor", "skills", SKILL_DIR_NAME),
2863
+ claude: (home) => path4.join(home, ".claude", "skills", SKILL_DIR_NAME),
2864
+ windsurf: (home) => path4.join(home, ".codeium", "windsurf", "skills", SKILL_DIR_NAME),
2865
+ gemini: (home) => path4.join(home, ".gemini", "skills", SKILL_DIR_NAME),
2866
+ codex: (home) => path4.join(home, ".codex", "skills", SKILL_DIR_NAME),
2867
+ opencode: (home) => path4.join(home, ".config", "opencode", "skills", SKILL_DIR_NAME),
2868
+ kilo: (home) => path4.join(home, ".kilo", "skills", SKILL_DIR_NAME),
2869
+ openclaw: (home) => path4.join(home, ".openclaw", "skills", SKILL_DIR_NAME),
2870
+ workbuddy: (home) => path4.join(home, ".workbuddy", "skills", SKILL_DIR_NAME)
2871
+ };
2872
+ var ALL_PLATFORM_KEYS = Object.keys(PROJECT_DIRS);
2873
+ function parseTargets(raw) {
2874
+ const normalized = raw.trim().toLowerCase();
2875
+ if (normalized === "all") {
2876
+ return ALL_PLATFORM_KEYS.map((k) => ({ keys: [k], isGlobal: false }));
2877
+ }
2878
+ const parts = normalized.split(",").map((s) => s.trim());
2879
+ const results = [];
2880
+ const seen = /* @__PURE__ */ new Set();
2881
+ for (const p of parts) {
2882
+ let key = p;
2883
+ let isGlobal = false;
2884
+ if (p === "openclaw-workspace") {
2885
+ key = "openclaw";
2886
+ isGlobal = false;
2887
+ } else if (p === "openclaw-global") {
2888
+ key = "openclaw";
2889
+ isGlobal = true;
2890
+ } else if (p === "openclaw") {
2891
+ key = "openclaw";
2892
+ isGlobal = false;
2893
+ } else if (p === "workbuddy-workspace") {
2894
+ key = "workbuddy";
2895
+ isGlobal = false;
2896
+ } else if (p === "workbuddy-global") {
2897
+ key = "workbuddy";
2898
+ isGlobal = true;
2899
+ } else if (p === "workbuddy") {
2900
+ key = "workbuddy";
2901
+ isGlobal = false;
2902
+ }
2903
+ if (!ALL_PLATFORM_KEYS.includes(key)) {
2904
+ console.error(
2905
+ `\u672A\u77E5\u5E73\u53F0: ${p}\u3002\u53EF\u9009: ${ALL_PLATFORM_KEYS.join(", ")}, openclaw-workspace, openclaw-global, workbuddy-workspace, workbuddy-global, all`
2906
+ );
2907
+ process.exitCode = 1;
2908
+ return [];
2909
+ }
2910
+ const uid = `${key}:${isGlobal}`;
2911
+ if (!seen.has(uid)) {
2912
+ seen.add(uid);
2913
+ results.push({ keys: [key], isGlobal });
2914
+ }
2915
+ }
2916
+ return results;
2917
+ }
2918
+ function skillRoot() {
2919
+ return path4.join(__dirname, "skill");
2920
+ }
2921
+ function saveInstalledTargets(newEntries) {
2922
+ const CONFIG_FILE3 = path4.join(os2.homedir(), ".siluzan", "config.json");
2923
+ try {
2924
+ fsSync.mkdirSync(path4.dirname(CONFIG_FILE3), { recursive: true });
2925
+ let existing = {};
2926
+ if (fsSync.existsSync(CONFIG_FILE3)) {
2927
+ existing = JSON.parse(fsSync.readFileSync(CONFIG_FILE3, "utf8"));
2928
+ }
2929
+ const prev = Array.isArray(existing.installedTargets) ? existing.installedTargets : [];
2930
+ const merged = /* @__PURE__ */ new Map();
2931
+ for (const e of [...prev, ...newEntries]) {
2932
+ merged.set(`${e.target}::${e.cwd}`, e);
2933
+ }
2934
+ fsSync.writeFileSync(
2935
+ CONFIG_FILE3,
2936
+ JSON.stringify({ ...existing, installedTargets: [...merged.values()] }, null, 2),
2937
+ "utf8"
2938
+ );
2939
+ if (process.platform !== "win32") {
2940
+ fsSync.chmodSync(CONFIG_FILE3, 384);
2941
+ }
2942
+ } catch {
2943
+ }
2944
+ }
2945
+ async function writeSkillFilesToDir(destDir, skillFiles, force) {
2946
+ await fs4.mkdir(destDir, { recursive: true });
2947
+ let anyWritten = false;
2948
+ for (const [relativePath, content] of Object.entries(skillFiles)) {
2949
+ const fullPath = path4.join(destDir, relativePath);
2950
+ await fs4.mkdir(path4.dirname(fullPath), { recursive: true });
2951
+ try {
2952
+ await fs4.access(fullPath);
2953
+ if (!force) {
2954
+ console.warn(`\u8DF3\u8FC7\uFF08\u5DF2\u5B58\u5728\uFF0C\u4F7F\u7528 --force \u8986\u76D6\uFF09: ${fullPath}`);
2955
+ continue;
2956
+ }
2957
+ } catch {
2958
+ }
2959
+ await fs4.writeFile(fullPath, content, "utf8");
2960
+ console.log(`\u5DF2\u5199\u5165: ${fullPath}`);
2961
+ anyWritten = true;
2962
+ }
2963
+ return anyWritten;
2964
+ }
2965
+ async function runInit(options) {
2966
+ const home = os2.homedir();
2967
+ const skillFiles = await getSkillFiles(skillRoot(), options.apiBaseUrl);
2968
+ const installedEntries = [];
2969
+ if (options.dir) {
2970
+ const destDir = path4.resolve(options.cwd, options.dir);
2971
+ console.log(`\u5B89\u88C5\u76EE\u6807\u76EE\u5F55\uFF1A${destDir}`);
2972
+ const anyWritten = await writeSkillFilesToDir(destDir, skillFiles, options.force);
2973
+ if (anyWritten) {
2974
+ installedEntries.push({ target: "custom", cwd: "", dir: destDir });
2975
+ }
2976
+ } else if (options.global) {
2977
+ for (const key of ALL_PLATFORM_KEYS) {
2978
+ const destDir = GLOBAL_DIRS[key](home);
2979
+ console.log(`[${key} global] \u2192 ${destDir}`);
2980
+ const anyWritten = await writeSkillFilesToDir(destDir, skillFiles, options.force);
2981
+ if (anyWritten) {
2982
+ installedEntries.push({ target: `${key}-global`, cwd: "" });
2983
+ }
2984
+ }
2985
+ } else {
2986
+ const targets = parseTargets(options.aiTargets);
2987
+ if (targets.length === 0) return;
2988
+ for (const entry of targets) {
2989
+ for (const key of entry.keys) {
2990
+ const destDir = entry.isGlobal ? GLOBAL_DIRS[key](home) : PROJECT_DIRS[key](options.cwd);
2991
+ const label = entry.isGlobal ? `${key} global` : key;
2992
+ console.log(`[${label}] \u2192 ${destDir}`);
2993
+ const anyWritten = await writeSkillFilesToDir(destDir, skillFiles, options.force);
2994
+ if (anyWritten) {
2995
+ installedEntries.push({
2996
+ target: entry.isGlobal ? `${key}-global` : key,
2997
+ cwd: entry.isGlobal ? "" : options.cwd
2998
+ });
2999
+ }
3000
+ }
3001
+ }
3002
+ }
3003
+ if (installedEntries.length > 0) {
3004
+ saveInstalledTargets(installedEntries);
3005
+ }
3006
+ console.log("\n\u4E0B\u4E00\u6B65\uFF1A");
3007
+ console.log("1. \u9996\u6B21\u4F7F\u7528\u8BF7\u8FD0\u884C\uFF1Asiluzan-cso login \uFF08\u5F15\u5BFC\u6CE8\u518C/\u767B\u5F55\u5E76\u4FDD\u5B58 Token\uFF09");
3008
+ console.log("2. \u540E\u7EED\u5347\u7EA7\u8FD0\u884C\uFF1Asiluzan-cso update \uFF08\u81EA\u52A8\u66F4\u65B0 CLI \u4E0E skill \u6587\u4EF6\uFF09");
3009
+ }
2586
3010
 
2587
3011
  // src/commands/login.ts
3012
+ import * as readline from "readline";
3013
+ import * as os3 from "os";
3014
+ function parseAllowedServices(raw) {
3015
+ const allowed = ["CSO", "TSO", "CUT"];
3016
+ if (!raw) return ["CSO", "CUT"];
3017
+ const parts = raw.split(",").map((s) => s.trim().toUpperCase()).filter(Boolean);
3018
+ const result = [];
3019
+ for (const p of parts) {
3020
+ if (!allowed.includes(p)) {
3021
+ throw new Error(`\u672A\u77E5\u670D\u52A1\u540D\u300C${p}\u300D\uFF0C\u53EF\u9009\uFF1A${allowed.join(" / ")}`);
3022
+ }
3023
+ if (!result.includes(p)) result.push(p);
3024
+ }
3025
+ if (result.length === 0) {
3026
+ throw new Error("--services \u81F3\u5C11\u9700\u8981\u6307\u5B9A\u4E00\u4E2A\u670D\u52A1");
3027
+ }
3028
+ return result;
3029
+ }
3030
+ function defaultApiKeyName() {
3031
+ const host = (() => {
3032
+ try {
3033
+ return os3.hostname() || "unknown";
3034
+ } catch {
3035
+ return "unknown";
3036
+ }
3037
+ })();
3038
+ const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
3039
+ return `CLI - ${host} - ${today}`;
3040
+ }
3041
+ function validateAndNormalizePhone(rawInput) {
3042
+ const rawPhone = rawInput?.trim() ?? "";
3043
+ if (!isValidChinaPhone(rawPhone)) {
3044
+ console.error(
3045
+ "\n\u274C \u624B\u673A\u53F7\u683C\u5F0F\u9519\u8BEF\uFF1A\u4EC5\u652F\u6301\u4E2D\u56FD\u5927\u9646\u624B\u673A\u53F7\uFF0C\u53EF\u5E26\u6216\u4E0D\u5E26 +86\uFF08\u5982 13800138000 / +8613800138000\uFF09\u3002\n"
3046
+ );
3047
+ process.exit(1);
3048
+ }
3049
+ return normalizeChinaPhone(rawPhone);
3050
+ }
3051
+ function resolveSsoCsoBase() {
3052
+ const apiBase = process.env.SILUZAN_CSO_API_BASE ?? DEFAULT_API_BASE;
3053
+ const ssoBaseUrl = deriveSsoBaseUrl(apiBase);
3054
+ const csoBaseUrl = process.env.SILUZAN_CSO_BASE ?? DEFAULT_CSO_BASE ?? deriveCsoApiBaseUrl(apiBase);
3055
+ return { ssoBaseUrl, csoBaseUrl };
3056
+ }
3057
+ async function runPhoneLogin(opts) {
3058
+ const phone = validateAndNormalizePhone(opts.phone);
3059
+ const code = opts.code?.trim() ?? "";
3060
+ if (!code) {
3061
+ console.error("\n\u274C \u7F3A\u5C11 --code \u53C2\u6570\u3002\u624B\u673A\u53F7\u767B\u5F55\u662F\u4E24\u6BB5\u5F0F\u8C03\u7528\uFF0C\u8BF7\u6309\u987A\u5E8F\u6267\u884C\uFF1A\n");
3062
+ console.error(` 1) siluzan-cso send-login-code --phone ${phone}`);
3063
+ console.error(` 2) siluzan-cso login --phone ${phone} --code <\u6536\u5230\u76846\u4F4D\u9A8C\u8BC1\u7801>
3064
+ `);
3065
+ console.error("\uFF08\u62C6\u6210\u4E24\u6B65\u662F\u4E3A\u4E86\u907F\u514D AI Agent \u5361\u5728\u4EA4\u4E92\u8F93\u5165\u65F6\u53CD\u590D\u91CD\u8BD5\u5BFC\u81F4\u77ED\u4FE1\u8F70\u70B8\uFF09\n");
3066
+ process.exit(1);
3067
+ }
3068
+ let allowedServices;
3069
+ try {
3070
+ allowedServices = parseAllowedServices(opts.services);
3071
+ } catch (e) {
3072
+ console.error(`
3073
+ \u274C ${e instanceof Error ? e.message : String(e)}
3074
+ `);
3075
+ process.exit(1);
3076
+ return;
3077
+ }
3078
+ if (opts.validDays !== void 0 && opts.expiresAt !== void 0) {
3079
+ console.warn("\u26A0\uFE0F --valid-days \u4E0E --expires-at \u540C\u65F6\u4F20\u5165\uFF0C\u5C06\u4EE5 --expires-at \u4E3A\u51C6\u3002");
3080
+ }
3081
+ const { ssoBaseUrl, csoBaseUrl } = resolveSsoCsoBase();
3082
+ const apiKeyName = opts.name ?? defaultApiKeyName();
3083
+ console.log("\n\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
3084
+ console.log(" Siluzan CSO \u767B\u5F55\uFF08\u624B\u673A\u53F7 + \u77ED\u4FE1\u9A8C\u8BC1\u7801\uFF09");
3085
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n");
3086
+ console.log(` \u624B\u673A\u53F7 : ${phone}`);
3087
+ console.log(` \u9A8C\u8BC1\u7801 : ${code}`);
3088
+ console.log(` SSO : ${ssoBaseUrl}`);
3089
+ console.log(` CSO API : ${csoBaseUrl}`);
3090
+ console.log(` \u670D\u52A1\u8303\u56F4 : ${allowedServices.join(", ")}`);
3091
+ if (opts.expiresAt) {
3092
+ console.log(` \u8FC7\u671F\u65F6\u95F4 : ${opts.expiresAt}`);
3093
+ } else {
3094
+ console.log(` \u6709\u6548\u671F : ${opts.validDays ?? 90} \u5929`);
3095
+ }
3096
+ console.log(` API Key \u540D\u79F0 : ${apiKeyName}
3097
+ `);
3098
+ console.log("\u2192 \u6B63\u5728\u6821\u9A8C\u9A8C\u8BC1\u7801\u5E76\u521B\u5EFA API Key...");
3099
+ try {
3100
+ const created = await issueApiKeyWithPhoneCode({
3101
+ ssoBaseUrl,
3102
+ csoBaseUrl,
3103
+ phone,
3104
+ code,
3105
+ apiKeyName,
3106
+ validDays: opts.expiresAt ? void 0 : opts.validDays ?? 90,
3107
+ expiresAt: opts.expiresAt,
3108
+ allowedServices,
3109
+ verbose: opts.verbose
3110
+ });
3111
+ writeSharedConfig({ apiKey: created.rawKey });
3112
+ console.log("\n\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
3113
+ console.log("\u2705 \u767B\u5F55\u6210\u529F\uFF0CAPI Key \u5DF2\u521B\u5EFA\u5E76\u4FDD\u5B58");
3114
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
3115
+ console.log(` Key ID : ${created.id}`);
3116
+ console.log(` Key Name : ${created.name}`);
3117
+ console.log(` Key (\u663E\u793A) : ${maskSecret(created.rawKey)}`);
3118
+ console.log(` Key (\u8131\u654F) : ${created.keyMasked}`);
3119
+ console.log(` \u751F\u6548\u65F6\u95F4 : ${created.validFrom}`);
3120
+ console.log(` \u8FC7\u671F\u65F6\u95F4 : ${created.expiresAt}`);
3121
+ console.log(` \u5269\u4F59\u5929\u6570 : ${created.remainingDays} \u5929`);
3122
+ console.log(` \u72B6\u6001 : ${created.status}`);
3123
+ console.log(` \u914D\u7F6E\u6587\u4EF6 : ${CONFIG_FILE}`);
3124
+ console.log("\n\u73B0\u5728\u53EF\u4EE5\u8FD0\u884C\uFF1A");
3125
+ console.log(" siluzan-cso list-accounts \u67E5\u770B\u53EF\u7528\u5A92\u4F53\u8D26\u53F7");
3126
+ console.log(" siluzan-cso publish -c <\u914D\u7F6E\u6587\u4EF6> \u53D1\u5E03\u5185\u5BB9\n");
3127
+ } catch (e) {
3128
+ const msg = e instanceof Error ? e.message : String(e);
3129
+ console.error(`
3130
+ \u274C \u767B\u5F55\u5931\u8D25\uFF1A${msg}`);
3131
+ if (/手机未注册|未注册/.test(msg)) {
3132
+ console.error(
3133
+ `
3134
+ \u8BE5\u624B\u673A\u53F7\u5C1A\u672A\u6CE8\u518C\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u3002\u8BF7\u5148\u5728\u7F51\u9875\u7AEF\u6CE8\u518C\uFF1A
3135
+ ${DEFAULT_WEB_BASE}
3136
+ \u6CE8\u518C\u6210\u529F\u540E\u518D\u56DE\u5230 CLI \u91CD\u8BD5\u4E24\u6BB5\u5F0F\u767B\u5F55\uFF1A
3137
+ siluzan-cso send-login-code --phone ${phone}
3138
+ siluzan-cso login --phone ${phone} --code <6\u4F4D\u9A8C\u8BC1\u7801>
3139
+ `
3140
+ );
3141
+ } else if (/验证码错误|验证码/.test(msg)) {
3142
+ console.error(
3143
+ `
3144
+ \u9A8C\u8BC1\u7801\u53EF\u80FD\u5DF2\u8FC7\u671F\u6216\u8F93\u9519\u3002\u8BF7\u91CD\u65B0\u53D1\u7801\u540E\u518D\u8BD5\uFF1A
3145
+ siluzan-cso send-login-code --phone ${phone}
3146
+ `
3147
+ );
3148
+ }
3149
+ process.exit(1);
3150
+ }
3151
+ }
2588
3152
  async function runLogin(opts = {}) {
2589
3153
  if (opts.token !== void 0) {
2590
3154
  const token = opts.token.trim();
@@ -2614,6 +3178,10 @@ async function runLogin(opts = {}) {
2614
3178
  console.log(" siluzan-cso list-accounts \u67E5\u770B\u53EF\u7528\u5A92\u4F53\u8D26\u53F7\n");
2615
3179
  return;
2616
3180
  }
3181
+ if (opts.phone !== void 0) {
3182
+ await runPhoneLogin(opts);
3183
+ return;
3184
+ }
2617
3185
  const shared = readSharedConfig();
2618
3186
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
2619
3187
  const prompt = (q) => new Promise((res) => rl.question(q, (a) => res(a.trim())));
@@ -2662,102 +3230,31 @@ import * as os4 from "os";
2662
3230
  import { spawnSync } from "child_process";
2663
3231
 
2664
3232
  // src/utils/version.ts
2665
- import * as fs4 from "fs";
2666
- import * as path4 from "path";
2667
- import * as os3 from "os";
2668
3233
  var PKG_NAME = "siluzan-cso-cli";
2669
- var CONFIG_FILE2 = path4.join(os3.homedir(), ".siluzan", "config.json");
3234
+ var BIN_NAME = "siluzan-cso";
3235
+ var CACHE_PREFIX = "_cso";
2670
3236
  function getCurrentVersion2() {
2671
3237
  return getCurrentVersion(import.meta.url);
2672
3238
  }
2673
- function readConfigRaw() {
2674
- try {
2675
- return JSON.parse(fs4.readFileSync(CONFIG_FILE2, "utf8"));
2676
- } catch {
2677
- return {};
2678
- }
2679
- }
2680
- function mergeWriteConfig(updates) {
2681
- try {
2682
- fs4.mkdirSync(path4.dirname(CONFIG_FILE2), { recursive: true });
2683
- let existing = {};
2684
- try {
2685
- existing = JSON.parse(fs4.readFileSync(CONFIG_FILE2, "utf8"));
2686
- } catch {
2687
- }
2688
- Object.assign(existing, updates);
2689
- fs4.writeFileSync(CONFIG_FILE2, JSON.stringify(existing, null, 2), "utf8");
2690
- if (process.platform !== "win32") {
2691
- fs4.chmodSync(CONFIG_FILE2, 384);
2692
- }
2693
- } catch {
2694
- }
2695
- }
2696
- async function fetchVersionByTag(tag, cacheKey, cfg) {
2697
- const hours24 = 24 * 60 * 60 * 1e3;
2698
- if (cfg._csoLastVersionCheck && cfg[cacheKey] !== void 0) {
2699
- const lastCheck = new Date(cfg._csoLastVersionCheck).getTime();
2700
- if (Date.now() - lastCheck < hours24) {
2701
- return cfg[cacheKey] || null;
2702
- }
2703
- }
2704
- return fetchNpmVersion(PKG_NAME, tag);
2705
- }
2706
- async function notifyIfOutdated() {
2707
- try {
2708
- const current = getCurrentVersion2();
2709
- const tag = npmDistTagForBuildEnv(BUILD_ENV);
2710
- const isBeta = tag === "beta";
2711
- const latestCacheKey = isBeta ? "_csoLatestBeta" : "_csoLatestStable";
2712
- const minCacheKey = isBeta ? "_csoMinRequiredBeta" : "_csoMinRequiredStable";
2713
- const minTag = npmMinRequiredTagForBuildEnv(BUILD_ENV);
2714
- const cfg = readConfigRaw();
2715
- const [latest, minRequired] = await Promise.all([
2716
- fetchVersionByTag(tag, latestCacheKey, cfg),
2717
- fetchVersionByTag(minTag, minCacheKey, cfg)
2718
- ]);
2719
- mergeWriteConfig({
2720
- _csoLastVersionCheck: (/* @__PURE__ */ new Date()).toISOString(),
2721
- [latestCacheKey]: latest ?? "",
2722
- [minCacheKey]: minRequired ?? ""
2723
- });
2724
- const lastNotified = cfg._csoLastNotified ? new Date(cfg._csoLastNotified).getTime() : 0;
2725
- if (Date.now() - lastNotified < 24 * 60 * 60 * 1e3) return;
2726
- const tagLabel = isBeta ? "\uFF08\u6D4B\u8BD5\u7248\uFF09" : "\uFF08\u6B63\u5F0F\u7248\uFF09";
2727
- if (minRequired && isNewer(current, minRequired)) {
2728
- mergeWriteConfig({ _csoLastNotified: (/* @__PURE__ */ new Date()).toISOString() });
2729
- console.log(
2730
- `
2731
- [SILUZAN_FORCE_UPDATE] \u5F53\u524D\u7248\u672C ${current} \u5DF2\u8FC7\u671F\uFF0C\u6700\u4F4E\u8981\u6C42\u7248\u672C ${minRequired}${tagLabel}
2732
- \u26D4 \u5FC5\u987B\u5148\u5347\u7EA7\u624D\u80FD\u7EE7\u7EED\u4F7F\u7528\uFF0CAgent \u8BF7\u7ACB\u5373\u6267\u884C\uFF1Asiluzan-cso update
2733
- \u6216\u624B\u52A8\uFF1Anpm install -g ${PKG_NAME}@${tag}
2734
- `
2735
- );
2736
- return;
2737
- }
2738
- if (latest && isNewer(current, latest)) {
2739
- mergeWriteConfig({ _csoLastNotified: (/* @__PURE__ */ new Date()).toISOString() });
2740
- console.log(
2741
- `
2742
- [SILUZAN_UPDATE_AVAILABLE] \u53D1\u73B0\u65B0\u7248\u672C ${latest}${tagLabel}\uFF08\u5F53\u524D ${current}\uFF09
2743
- \u{1F4A1} Agent \u8BF7\u7ACB\u5373\u6267\u884C\uFF1Asiluzan-cso update
2744
- \u6216\u624B\u52A8\uFF1Anpm install -g ${PKG_NAME}@${tag}
2745
- `
2746
- );
2747
- }
2748
- } catch {
2749
- }
2750
- }
2751
- async function fetchLatestVersion() {
2752
- const tag = npmDistTagForBuildEnv(BUILD_ENV);
2753
- return fetchNpmVersion(PKG_NAME, tag);
2754
- }
3239
+ var notifier = createVersionNotifier({
3240
+ pkgName: PKG_NAME,
3241
+ binName: BIN_NAME,
3242
+ cachePrefix: CACHE_PREFIX,
3243
+ // cso 按构建环境(BUILD_ENV)决定 dist-tag
3244
+ resolveTag: () => npmDistTagForBuildEnv(BUILD_ENV),
3245
+ getCurrentVersion: getCurrentVersion2,
3246
+ // 阶段 2:使用 common 的文件锁内合并写入,消除 21 进程并发数据竞争
3247
+ mergeWriteConfig: (updates) => mergeWriteSharedConfig(updates),
3248
+ readConfigRaw: () => readSharedConfigRaw()
3249
+ });
3250
+ var notifyIfOutdated = notifier.notifyIfOutdated;
3251
+ var fetchLatestVersion = notifier.fetchLatestVersion;
2755
3252
 
2756
3253
  // src/commands/update.ts
2757
- var CONFIG_FILE3 = path5.join(os4.homedir(), ".siluzan", "config.json");
3254
+ var CONFIG_FILE2 = path5.join(os4.homedir(), ".siluzan", "config.json");
2758
3255
  function readInstalledTargets() {
2759
3256
  try {
2760
- const cfg = JSON.parse(fs5.readFileSync(CONFIG_FILE3, "utf8"));
3257
+ const cfg = JSON.parse(fs5.readFileSync(CONFIG_FILE2, "utf8"));
2761
3258
  return Array.isArray(cfg.installedTargets) ? cfg.installedTargets : [];
2762
3259
  } catch {
2763
3260
  return [];
@@ -2881,10 +3378,7 @@ function loadConfig(tokenArg) {
2881
3378
  const apiKey = process.env.SILUZAN_API_KEY ?? (shared.apiKey ? shared.apiKey : void 0);
2882
3379
  const authToken = tokenArg ?? process.env.SILUZAN_AUTH_TOKEN ?? shared.authToken ?? "";
2883
3380
  if (!apiKey && !authToken) {
2884
- console.error(
2885
- "\n\u274C \u672A\u627E\u5230\u8BA4\u8BC1\u51ED\u636E\u3002\n\n \u65B9\u5F0F\u4E00\uFF08\u63A8\u8350\uFF09\uFF1AAPI Key\n \u5728\u4E1D\u8DEF\u8D5E\u300C\u8BBE\u7F6E \u2192 API Key \u7BA1\u7406\u300D\u521B\u5EFA API Key\uFF0C\u7136\u540E\u8FD0\u884C\uFF1A\n siluzan-cso login --api-key <YOUR_API_KEY>\n\n \u65B9\u5F0F\u4E8C\uFF1A\u73AF\u5883\u53D8\u91CF\uFF08CI/CD \u63A8\u8350\uFF09\n export SILUZAN_API_KEY=<YOUR_API_KEY>\n # \u6216 export SILUZAN_AUTH_TOKEN=<YOUR_TOKEN>\n\n \u65B9\u5F0F\u4E09\uFF1AJWT Token\n siluzan-cso login\n"
2886
- );
2887
- process.exit(1);
3381
+ printAuthMissingHelp("siluzan-cso");
2888
3382
  }
2889
3383
  const apiBaseUrl = process.env.SILUZAN_CSO_API_BASE ?? DEFAULT_API_BASE;
2890
3384
  const csoBaseUrl = process.env.SILUZAN_CSO_BASE ?? DEFAULT_CSO_BASE;
@@ -2892,81 +3386,32 @@ function loadConfig(tokenArg) {
2892
3386
  const apiErr = validateBaseUrl(apiBaseUrl);
2893
3387
  if (apiErr) {
2894
3388
  console.error(`
2895
- \u274C apiBaseUrl \u4E0D\u5408\u6CD5\uFF1A${apiErr}`);
2896
- process.exit(1);
2897
- }
2898
- const csoErr = validateBaseUrl(csoBaseUrl);
2899
- if (csoErr) {
2900
- console.error(`
2901
- \u274C csoBaseUrl \u4E0D\u5408\u6CD5\uFF1A${csoErr}`);
2902
- process.exit(1);
2903
- }
2904
- const agentErr = validateBaseUrl(agentBaseUrl);
2905
- if (agentErr) {
2906
- console.error(`
2907
- \u274C agentBaseUrl \u4E0D\u5408\u6CD5\uFF1A${agentErr}`);
2908
- process.exit(1);
2909
- }
2910
- return {
2911
- apiBaseUrl,
2912
- csoBaseUrl,
2913
- agentBaseUrl,
2914
- authToken,
2915
- apiKey,
2916
- dataPermission: process.env.SILUZAN_DATA_PERMISSION ?? shared.dataPermission
2917
- };
2918
- }
2919
- function apiFetch2(url, config, options = {}, verbose = false) {
2920
- return apiFetch(url, config, options, verbose);
2921
- }
2922
-
2923
- // src/utils/cli-table.ts
2924
- import Table from "cli-table3";
2925
- var ASCII_TABLE_CHARS = {
2926
- top: "-",
2927
- "top-mid": "+",
2928
- "top-left": "+",
2929
- "top-right": "+",
2930
- bottom: "-",
2931
- "bottom-mid": "+",
2932
- "bottom-left": "+",
2933
- "bottom-right": "+",
2934
- left: "|",
2935
- "left-mid": "+",
2936
- mid: "-",
2937
- "mid-mid": "+",
2938
- right: "|",
2939
- "right-mid": "+",
2940
- middle: "|"
2941
- };
2942
- function printCliTable(rows, columns, options) {
2943
- if (rows.length === 0) return;
2944
- const plain = options?.plain !== false;
2945
- const indent = options?.indent ?? " ";
2946
- const printLine = options?.printLine ?? ((msg) => {
2947
- console.log(msg);
2948
- });
2949
- const table = new Table({
2950
- head: columns.map((c) => c.header),
2951
- chars: plain ? { ...ASCII_TABLE_CHARS } : void 0,
2952
- style: plain ? { head: [], border: [] } : void 0
2953
- });
2954
- for (const r of rows) {
2955
- table.push(columns.map((c) => String(r[c.key] ?? "")));
3389
+ \u274C apiBaseUrl \u4E0D\u5408\u6CD5\uFF1A${apiErr}`);
3390
+ process.exit(1);
2956
3391
  }
2957
- for (const line of table.toString().split("\n")) {
2958
- printLine(indent + line);
3392
+ const csoErr = validateBaseUrl(csoBaseUrl);
3393
+ if (csoErr) {
3394
+ console.error(`
3395
+ \u274C csoBaseUrl \u4E0D\u5408\u6CD5\uFF1A${csoErr}`);
3396
+ process.exit(1);
2959
3397
  }
3398
+ const agentErr = validateBaseUrl(agentBaseUrl);
3399
+ if (agentErr) {
3400
+ console.error(`
3401
+ \u274C agentBaseUrl \u4E0D\u5408\u6CD5\uFF1A${agentErr}`);
3402
+ process.exit(1);
3403
+ }
3404
+ return {
3405
+ apiBaseUrl,
3406
+ csoBaseUrl,
3407
+ agentBaseUrl,
3408
+ authToken,
3409
+ apiKey,
3410
+ dataPermission: process.env.SILUZAN_DATA_PERMISSION ?? shared.dataPermission
3411
+ };
2960
3412
  }
2961
-
2962
- // src/utils/pagination.ts
2963
- function computeTotalPages(total, pageSize) {
2964
- if (pageSize <= 0) return 0;
2965
- return Math.ceil(total / pageSize);
2966
- }
2967
- function formatPaginationSummary(params) {
2968
- const totalPages = params.totalPagesOverride !== void 0 ? params.totalPagesOverride : computeTotalPages(params.total, params.pageSize);
2969
- return `\u9875\u7801/\u5F53\u524D\u9875\uFF1A${params.page}\uFF0C\u603B\u6761\u6570\uFF1A${params.total}\uFF0C\u603B\u9875\u6570\uFF1A${totalPages}\uFF0C\u6BCF\u9875\uFF1A${params.pageSize} \u6761`;
3413
+ function apiFetch2(url, config, options = {}, verbose = false) {
3414
+ return apiFetch(url, config, options, verbose);
2970
3415
  }
2971
3416
 
2972
3417
  // src/commands/list-accounts.ts
@@ -3238,6 +3683,23 @@ ${hint}`);
3238
3683
  printCliTable(rows, columns, tableOpts2);
3239
3684
  console.log("\n\u63D0\u793A\uFF1A\u5C06\u3010\u7528\u6237ID\u3011\u5217\u7684\u503C\u4F20\u7ED9 list-accounts --owner <\u7528\u6237ID> \u53EF\u6309\u8D1F\u8D23\u4EBA\u8FC7\u6EE4\u8D26\u53F7\u3002");
3240
3685
  }
3686
+ var register = defineCommand({
3687
+ name: "list-members",
3688
+ description: "\u5217\u51FA\u516C\u53F8\u6240\u6709\u6210\u5458\uFF0C\u663E\u793A\u7528\u6237ID\u4F9B list-accounts --owner \u4F7F\u7528",
3689
+ options: [
3690
+ { flags: "-q, --query <keyword>", description: "\u6309\u59D3\u540D\u6216\u624B\u673A\u53F7\u6A21\u7CCA\u641C\u7D22" },
3691
+ { flags: "--unicode", description: "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", defaultValue: false }
3692
+ ],
3693
+ handler: async (opts) => {
3694
+ await runListMembers({
3695
+ token: opts.token,
3696
+ query: opts.query,
3697
+ json: opts.json,
3698
+ unicode: opts.unicode,
3699
+ verbose: opts.verbose
3700
+ });
3701
+ }
3702
+ });
3241
3703
 
3242
3704
  // src/commands/account-group.ts
3243
3705
  function parseAccountIds(raw) {
@@ -3586,399 +4048,14 @@ async function runAccountGroupRemoveAccounts(options) {
3586
4048
  }
3587
4049
  }
3588
4050
 
3589
- // src/commands/publish.ts
3590
- import * as fs6 from "fs";
3591
- import * as path6 from "path";
4051
+ // src/commands/publish/_shared.ts
3592
4052
  function nowUtc() {
3593
4053
  return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
3594
4054
  }
3595
- var guid = randomUUID;
3596
- function isGuidFormat(s) {
3597
- return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(s);
3598
- }
3599
- function defaultTaskName() {
3600
- const d = /* @__PURE__ */ new Date();
3601
- const pad = (n) => String(n).padStart(2, "0");
3602
- return `\u6279\u91CF\u53D1\u5E03 ${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
3603
- }
3604
- function buildPublishTitle(item, mediaType, override, isImagePost = false) {
3605
- const title = override?.title ?? item.title ?? "";
3606
- const topics = override?.topics ?? item.topics ?? [];
3607
- const rawDesc = override?.description ?? item.description ?? "";
3608
- let description;
3609
- if (isImagePost) {
3610
- description = rawDesc;
3611
- } else {
3612
- description = ["YouTube", "Facebook"].includes(mediaType) ? rawDesc || title : title;
3613
- }
3614
- const defaultTopicPosition = ["YouTube", "Facebook"].includes(mediaType) ? 4 : 2;
3615
- const topicPosition = override?.topicPosition ?? item.topicPosition ?? defaultTopicPosition;
3616
- return { title, description, topics, topicPosition };
3617
- }
3618
- function buildImagePayload(img, currentUserId) {
3619
- return {
3620
- imageUrl: img.imageUrl,
3621
- imageName: img.imageName,
3622
- sourceImageId: img.sourceImageId ?? void 0,
3623
- imageCreateUserId: img.imageCreateUserId ?? currentUserId ?? void 0,
3624
- imageSourceType: img.imageSourceType,
3625
- belongTo: -1,
3626
- belongToId: null,
3627
- replica: false,
3628
- size: img.size ?? 0,
3629
- width: img.width ?? 0,
3630
- height: img.height ?? 0
3631
- };
3632
- }
3633
- function buildCoverPayload(cover, videoId, currentUserId) {
3634
- return {
3635
- imageUrl: cover.imageUrl,
3636
- imageName: cover.imageName,
3637
- imageSourceType: cover.imageSourceType,
3638
- sourceImageId: cover.sourceImageId ?? videoId,
3639
- imageCreateUserId: cover.imageCreateUserId ?? currentUserId ?? void 0,
3640
- // belongTo / belongToId:CLI 无法获取组织信息,统一与前端素材库视频行为保持一致
3641
- belongTo: -1,
3642
- belongToId: null,
3643
- replica: false,
3644
- coverTsp: 0,
3645
- compositeCover: false,
3646
- size: cover.size ?? 0,
3647
- width: cover.width ?? 0,
3648
- height: cover.height ?? 0
3649
- };
3650
- }
3651
- function toSendType(mode) {
3652
- return mode === "scheduled" ? 2 : 1;
3653
- }
3654
- function finalizeChannels(channels, sentKey) {
3655
- for (const ch of Object.values(channels)) {
3656
- let chSendType = 1;
3657
- let chPublishAt = null;
3658
- for (const acc of ch.mediaAccountInfos) {
3659
- const items = acc[sentKey] ?? [];
3660
- for (const v of items) {
3661
- if (v.sendType <= 1) continue;
3662
- if (v.sendType > chSendType) {
3663
- chSendType = v.sendType;
3664
- chPublishAt = v.publishAt;
3665
- } else if (v.sendType === chSendType && v.publishAt && (!chPublishAt || new Date(v.publishAt) < new Date(chPublishAt))) {
3666
- chPublishAt = v.publishAt;
3667
- }
3668
- }
3669
- }
3670
- ch.videoType = chSendType > 1 ? 2 : 1;
3671
- ch.publishAts = chSendType > 1 && chPublishAt ? [chPublishAt] : [];
3672
- }
3673
- }
3674
- var UUID_HINT = "\uFF08\u8BF7\u5148\u8FD0\u884C `siluzan-cso list-accounts --json` \u83B7\u53D6\u6B63\u786E\u7684 UUID \u503C\uFF0C\u4E0D\u8981\u4F7F\u7528\u5360\u4F4D\u7B26\u6587\u672C\uFF09";
3675
- function buildVideoChannels(videos, currentUserId) {
3676
- const channels = {};
3677
- const contents = [];
3678
- const errorList = [];
3679
- let globalSendType = 1;
3680
- for (const item of videos) {
3681
- if (!item.accounts?.length) errorList.push(`\u89C6\u9891 "${item.videoName}" \u672A\u8BBE\u7F6E\u8D26\u53F7`);
3682
- if (!item.title) errorList.push(`\u89C6\u9891 "${item.videoName}" \u672A\u586B\u5199\u6807\u9898`);
3683
- if (!item.cover?.imageUrl) errorList.push(`\u89C6\u9891 "${item.videoName}" \u5C01\u9762\u53C2\u6570\u7F3A\u5931`);
3684
- if (!isGuidFormat(item.videoId)) {
3685
- errorList.push(
3686
- `\u89C6\u9891 "${item.videoName}" \u7684 videoId "${item.videoId}" \u4E0D\u662F\u5408\u6CD5 UUID \u683C\u5F0F ${UUID_HINT}`
3687
- );
3688
- }
3689
- let itemSendType = 1;
3690
- for (const account of item.accounts ?? []) {
3691
- if (!isGuidFormat(account.entityId)) {
3692
- errorList.push(
3693
- `\u8D26\u53F7 "${account.mediaCustomerName}" \u7684 entityId "${account.entityId}" \u4E0D\u662F\u5408\u6CD5 UUID \u683C\u5F0F ${UUID_HINT}`
3694
- );
3695
- }
3696
- if (!isGuidFormat(account.externalMediaAccountTokenId)) {
3697
- errorList.push(
3698
- `\u8D26\u53F7 "${account.mediaCustomerName}" \u7684 externalMediaAccountTokenId "${account.externalMediaAccountTokenId}" \u4E0D\u662F\u5408\u6CD5 UUID \u683C\u5F0F ${UUID_HINT}`
3699
- );
3700
- }
3701
- const mediaType = account.mediaAccountType;
3702
- const sendType = toSendType(item.publishMode);
3703
- const publishAtUtc = item.publishAt ? new Date(item.publishAt).toISOString() : null;
3704
- if (item.publishMode === "scheduled" && !item.publishAt) {
3705
- errorList.push(`\u89C6\u9891 "${item.videoName}" \u8BBE\u7F6E\u4E86\u5B9A\u65F6\u53D1\u5E03\u4F46\u672A\u586B\u5199 publishAt`);
3706
- }
3707
- if (sendType > itemSendType) itemSendType = sendType;
3708
- const override = item.platformOverrides?.[mediaType];
3709
- const publishTitle = buildPublishTitle(item, mediaType, override);
3710
- const youTubeVideoStatus = mediaType === "YouTube" ? {
3711
- privacyStatus: item.youtubePrivacy ?? "public",
3712
- instantPremiere: false
3713
- } : null;
3714
- const toBeSent = {
3715
- videoId: item.videoId,
3716
- sendType,
3717
- publishAt: publishAtUtc,
3718
- publishTitle,
3719
- publishCover: buildCoverPayload(item.cover, item.videoId, currentUserId),
3720
- youTubeVideoStatus
3721
- };
3722
- const accountInfo = {
3723
- mediaAccountId: account.entityId,
3724
- mediaCustomerId: account.mediaCustomerId,
3725
- mediaCustomerName: account.mediaCustomerName,
3726
- externalMediaAccountTokenId: account.externalMediaAccountTokenId
3727
- };
3728
- if (channels[mediaType]) {
3729
- const existing = channels[mediaType].mediaAccountInfos.find(
3730
- (i) => i.mediaAccountId === account.entityId
3731
- );
3732
- if (existing) {
3733
- existing.videoToBeSent.push(toBeSent);
3734
- } else {
3735
- channels[mediaType].mediaAccountInfos.push({ ...accountInfo, videoToBeSent: [toBeSent] });
3736
- }
3737
- } else {
3738
- channels[mediaType] = {
3739
- mediaType,
3740
- mediaAccountInfos: [{ ...accountInfo, videoToBeSent: [toBeSent] }]
3741
- };
3742
- }
3743
- }
3744
- if (itemSendType > globalSendType) globalSendType = itemSendType;
3745
- contents.push({
3746
- videoId: item.videoId,
3747
- // 素材库视频:sourceVideoId 与 videoId 相同;非素材库:null
3748
- sourceVideoId: item.isMaterialCenter ? item.videoId : null,
3749
- videoUrl: item.videoUrl,
3750
- videoName: item.videoName,
3751
- width: item.width ?? 0,
3752
- height: item.height ?? 0,
3753
- videoSize: item.videoSize ?? 0,
3754
- duration: item.duration ?? 0,
3755
- // 实际请求中 videoMd5 为 null(非空字符串)
3756
- videoMd5: item.videoMd5 ?? null,
3757
- isMaterialCenter: item.isMaterialCenter ?? false,
3758
- // videoCreateUserId:优先取配置里的值,回落到当前 token 的 sub(上传者 ID)
3759
- videoCreateUserId: item.videoCreateUserId ?? currentUserId,
3760
- // belongTo/-ToId:CLI 无组织上下文,统一 -1/null(与前端素材库视频行为一致)
3761
- belongTo: -1,
3762
- belongToId: null,
3763
- replica: false,
3764
- // mediaAccountIds:后端用于建立视频与账号的关联,缺少此字段会导致发布失败
3765
- mediaAccountIds: (item.accounts ?? []).map((a) => a.entityId),
3766
- // POI 地理位置:默认 poiWay=3(不使用 POI)
3767
- poiWay: 3,
3768
- poiId: "",
3769
- poiName: "",
3770
- defaultTitle: {
3771
- title: item.title,
3772
- description: item.description ?? "",
3773
- topicPosition: 2,
3774
- topics: item.topics ?? []
3775
- },
3776
- // defaultCover 补全所有后端字段(与 publishCover 保持结构一致)
3777
- defaultCover: buildCoverPayload(item.cover, item.videoId, currentUserId)
3778
- });
3779
- }
3780
- finalizeChannels(channels, "videoToBeSent");
3781
- return { channels, videoType: globalSendType, contents, errorList };
3782
- }
3783
- function buildImageChannels(posts, currentUserId) {
3784
- const channels = {};
3785
- const contents = [];
3786
- const errorList = [];
3787
- let globalSendType = 1;
3788
- const validPosts = posts.filter(
3789
- (item) => item.images?.some((img) => img.imageUrl) || (item.title ?? "").trim()
3790
- );
3791
- if (validPosts.length === 0) {
3792
- errorList.push("\u6CA1\u6709\u53EF\u53D1\u5E03\u7684\u5E16\u5B50\uFF0C\u8BF7\u81F3\u5C11\u4E3A\u6BCF\u4E2A\u5E16\u5B50\u6DFB\u52A0\u56FE\u7247\u6216\u6587\u6848");
3793
- return { channels, videoType: 1, contents, errorList };
3794
- }
3795
- for (const item of validPosts) {
3796
- const vGuid = item.vGuid ?? guid();
3797
- if (!item.accounts?.length) errorList.push("\u56FE\u6587\u5E16\u5B50\u672A\u8BBE\u7F6E\u8D26\u53F7");
3798
- let itemSendType = 1;
3799
- for (const account of item.accounts ?? []) {
3800
- if (!isGuidFormat(account.entityId)) {
3801
- errorList.push(
3802
- `\u8D26\u53F7 "${account.mediaCustomerName}" \u7684 entityId "${account.entityId}" \u4E0D\u662F\u5408\u6CD5 UUID \u683C\u5F0F ${UUID_HINT}`
3803
- );
3804
- }
3805
- if (!isGuidFormat(account.externalMediaAccountTokenId)) {
3806
- errorList.push(
3807
- `\u8D26\u53F7 "${account.mediaCustomerName}" \u7684 externalMediaAccountTokenId "${account.externalMediaAccountTokenId}" \u4E0D\u662F\u5408\u6CD5 UUID \u683C\u5F0F ${UUID_HINT}`
3808
- );
3809
- }
3810
- const mediaType = account.mediaAccountType;
3811
- const sendType = toSendType(item.publishMode);
3812
- const publishAtUtc = item.publishAt ? new Date(item.publishAt).toISOString() : null;
3813
- if (item.publishMode === "scheduled" && !item.publishAt) {
3814
- errorList.push("\u56FE\u6587\u5E16\u5B50\u8BBE\u7F6E\u4E86\u5B9A\u65F6\u53D1\u5E03\u4F46\u672A\u586B\u5199 publishAt");
3815
- }
3816
- if (sendType > itemSendType) itemSendType = sendType;
3817
- const override = item.platformOverrides?.[mediaType];
3818
- const publishTitle = buildPublishTitle(item, mediaType, override, true);
3819
- const toBeSent = {
3820
- imageGroupId: vGuid,
3821
- sendType,
3822
- publishAt: publishAtUtc,
3823
- publishTitle
3824
- };
3825
- const accountInfo = {
3826
- mediaAccountId: account.entityId,
3827
- mediaCustomerId: account.mediaCustomerId,
3828
- mediaCustomerName: account.mediaCustomerName,
3829
- externalMediaAccountTokenId: account.externalMediaAccountTokenId
3830
- };
3831
- if (channels[mediaType]) {
3832
- const existing = channels[mediaType].mediaAccountInfos.find(
3833
- (i) => i.mediaAccountId === account.entityId
3834
- );
3835
- if (existing) {
3836
- existing.imageTextToBeSent.push(toBeSent);
3837
- } else {
3838
- channels[mediaType].mediaAccountInfos.push({
3839
- ...accountInfo,
3840
- imageTextToBeSent: [toBeSent]
3841
- });
3842
- }
3843
- } else {
3844
- channels[mediaType] = {
3845
- mediaType,
3846
- mediaAccountInfos: [{ ...accountInfo, imageTextToBeSent: [toBeSent] }]
3847
- };
3848
- }
3849
- }
3850
- if (itemSendType > globalSendType) globalSendType = itemSendType;
3851
- contents.push({
3852
- imageGroupId: vGuid,
3853
- // 补全每张图片的后端必填字段(belongTo、replica、imageCreateUserId 等)
3854
- images: (item.images ?? []).map((img) => buildImagePayload(img, currentUserId)),
3855
- mediaAccountIds: (item.accounts ?? []).map((a) => a.entityId)
3856
- });
3857
- }
3858
- finalizeChannels(channels, "imageTextToBeSent");
3859
- return { channels, videoType: globalSendType, contents, errorList };
3860
- }
3861
- function formatTopics(topics) {
3862
- if (!topics?.length) return "";
3863
- return topics.map((t) => `#${t}`).join(" ");
3864
- }
3865
- function formatPublishMode(mode, publishAt) {
3866
- if (mode === "scheduled") {
3867
- return publishAt ? `\u5B9A\u65F6\u53D1\u5E03\uFF08${publishAt}\uFF09` : "\u5B9A\u65F6\u53D1\u5E03\uFF08\u26A0\uFE0F \u672A\u586B\u5199 publishAt\uFF09";
3868
- }
3869
- return "\u7ACB\u5373\u53D1\u5E03";
3870
- }
3871
- function printDryRun(input, taskName, isDomestic, body, verbose) {
3872
- const SEP = "\u2500".repeat(54);
3873
- console.log("\n\u2705 [dry-run] \u53D1\u5E03\u53C2\u6570\u9884\u89C8\uFF08\u672A\u5B9E\u9645\u63D0\u4EA4\uFF09\n");
3874
- console.log(`\u4EFB\u52A1\u540D \uFF1A${taskName}`);
3875
- console.log(`\u5185\u5BB9\u7C7B\u578B \uFF1A${input.contentType === 1 ? "\u89C6\u9891" : "\u56FE\u6587"}`);
3876
- console.log(`\u5E73\u53F0\u6A21\u5F0F \uFF1A${isDomestic ? "\u5185\u8D38" : "\u5916\u8D38"}`);
3877
- if (input.contentType === 1) {
3878
- const items = input.videos;
3879
- console.log(`\u89C6\u9891\u6570\u91CF \uFF1A${items.length} \u4E2A`);
3880
- for (let i = 0; i < items.length; i++) {
3881
- const item = items[i];
3882
- console.log(`
3883
- ${SEP}`);
3884
- console.log(` \u89C6\u9891 ${i + 1} / ${items.length}\uFF1A${item.videoName}`);
3885
- console.log(SEP);
3886
- console.log(` \u89C6\u9891 ID \uFF1A${item.videoId}`);
3887
- console.log(` \u6807\u9898 \uFF1A${item.title || "\u26A0\uFE0F \u672A\u586B\u5199"}`);
3888
- if (item.description) {
3889
- console.log(` \u63CF\u8FF0 \uFF1A${item.description}`);
3890
- }
3891
- const topicsStr = formatTopics(item.topics);
3892
- if (topicsStr) {
3893
- console.log(` \u6807\u7B7E \uFF1A${topicsStr}`);
3894
- }
3895
- console.log(` \u53D1\u5E03\u6A21\u5F0F \uFF1A${formatPublishMode(item.publishMode, item.publishAt)}`);
3896
- console.log(` \u5C01\u9762 URL \uFF1A${item.cover?.imageUrl || "\u26A0\uFE0F \u672A\u8BBE\u7F6E"}`);
3897
- if (item.cover?.sourceImageId) {
3898
- console.log(` \u5C01\u9762 ID \uFF1A${item.cover.sourceImageId}`);
3899
- }
3900
- const byPlatform = /* @__PURE__ */ new Map();
3901
- for (const acc of item.accounts ?? []) {
3902
- const list = byPlatform.get(acc.mediaAccountType) ?? [];
3903
- list.push(acc);
3904
- byPlatform.set(acc.mediaAccountType, list);
3905
- }
3906
- const totalAccounts = item.accounts?.length ?? 0;
3907
- console.log(`
3908
- \u8D26\u53F7\uFF08${totalAccounts} \u4E2A\uFF0C${byPlatform.size} \u4E2A\u5E73\u53F0\uFF09\uFF1A`);
3909
- for (const [platform, accounts] of byPlatform) {
3910
- const override = item.platformOverrides?.[platform];
3911
- console.log(`
3912
- \u25AA ${platform}`);
3913
- if (override) {
3914
- const pt = buildPublishTitle(item, platform, override);
3915
- if (override.title) console.log(` \u6807\u9898\u8986\u76D6 \uFF1A${pt.title}`);
3916
- if (override.description) console.log(` \u63CF\u8FF0\u8986\u76D6 \uFF1A${pt.description}`);
3917
- const ovTopics = formatTopics(override.topics);
3918
- if (ovTopics) console.log(` \u6807\u7B7E\u8986\u76D6 \uFF1A${ovTopics}`);
3919
- }
3920
- for (const acc of accounts) {
3921
- console.log(` \xB7 ${acc.mediaCustomerName}\uFF08${acc.mediaCustomerId}\uFF09`);
3922
- }
3923
- }
3924
- }
3925
- console.log(`
3926
- ${SEP}`);
3927
- } else {
3928
- const items = input.posts;
3929
- console.log(`\u56FE\u6587\u6570\u91CF \uFF1A${items.length} \u4E2A`);
3930
- for (let i = 0; i < items.length; i++) {
3931
- const item = items[i];
3932
- console.log(`
3933
- ${SEP}`);
3934
- console.log(` \u56FE\u6587 ${i + 1} / ${items.length}`);
3935
- console.log(SEP);
3936
- console.log(` \u6807\u9898 \uFF1A${item.title || "\u26A0\uFE0F \u672A\u586B\u5199"}`);
3937
- if (item.description) {
3938
- console.log(` \u63CF\u8FF0 \uFF1A${item.description}`);
3939
- }
3940
- const topicsStr = formatTopics(item.topics);
3941
- if (topicsStr) {
3942
- console.log(` \u6807\u7B7E \uFF1A${topicsStr}`);
3943
- }
3944
- console.log(` \u56FE\u7247\u6570\u91CF \uFF1A${item.images?.length ?? 0} \u5F20`);
3945
- console.log(` \u53D1\u5E03\u6A21\u5F0F \uFF1A${formatPublishMode(item.publishMode, item.publishAt)}`);
3946
- const byPlatform = /* @__PURE__ */ new Map();
3947
- for (const acc of item.accounts ?? []) {
3948
- const list = byPlatform.get(acc.mediaAccountType) ?? [];
3949
- list.push(acc);
3950
- byPlatform.set(acc.mediaAccountType, list);
3951
- }
3952
- const totalAccounts = item.accounts?.length ?? 0;
3953
- console.log(`
3954
- \u8D26\u53F7\uFF08${totalAccounts} \u4E2A\uFF0C${byPlatform.size} \u4E2A\u5E73\u53F0\uFF09\uFF1A`);
3955
- for (const [platform, accounts] of byPlatform) {
3956
- const override = item.platformOverrides?.[platform];
3957
- console.log(`
3958
- \u25AA ${platform}`);
3959
- if (override) {
3960
- const pt = buildPublishTitle(item, platform, override, true);
3961
- if (override.title) console.log(` \u6807\u9898\u8986\u76D6 \uFF1A${pt.title}`);
3962
- if (override.description) console.log(` \u63CF\u8FF0\u8986\u76D6 \uFF1A${pt.description}`);
3963
- const ovTopics = formatTopics(override.topics);
3964
- if (ovTopics) console.log(` \u6807\u7B7E\u8986\u76D6 \uFF1A${ovTopics}`);
3965
- }
3966
- for (const acc of accounts) {
3967
- console.log(` \xB7 ${acc.mediaCustomerName}\uFF08${acc.mediaCustomerId}\uFF09`);
3968
- }
3969
- }
3970
- }
3971
- console.log(`
3972
- ${SEP}`);
3973
- }
3974
- if (verbose) {
3975
- const verboseBody = { ...body, contents: JSON.parse(body.contents) };
3976
- console.log("\n\u5B8C\u6574 JSON \u8BF7\u6C42\u4F53\uFF08--verbose\uFF0Ccontents \u5DF2\u5C55\u5F00\uFF09\uFF1A\n");
3977
- console.log(JSON.stringify(verboseBody, null, 2));
3978
- } else {
3979
- console.log("\n\u2139\uFE0F \u52A0 --verbose \u53C2\u6570\u53EF\u67E5\u770B\u5B8C\u6574 JSON \u8BF7\u6C42\u4F53\u3002");
3980
- }
3981
- }
4055
+
4056
+ // src/commands/publish/commands.ts
4057
+ import * as fs6 from "fs";
4058
+ import * as path6 from "path";
3982
4059
  async function runPublish(options) {
3983
4060
  const configPath = path6.resolve(options.config);
3984
4061
  if (!fs6.existsSync(configPath)) {
@@ -4084,7 +4161,7 @@ async function runPublish(options) {
4084
4161
  }
4085
4162
  }
4086
4163
 
4087
- // src/commands/upload.ts
4164
+ // src/commands/upload/_shared.ts
4088
4165
  import * as fs7 from "fs";
4089
4166
  import * as os5 from "os";
4090
4167
  import * as path7 from "path";
@@ -4113,211 +4190,14 @@ var SENSITIVE_PATH_PREFIXES = [
4113
4190
  path7.join(os5.homedir(), ".env")
4114
4191
  // 常用本地环境变量文件
4115
4192
  ];
4116
- var SENSITIVE_ABSOLUTE_PATHS = ["/etc/passwd", "/etc/shadow", "/etc/hosts"];
4117
- function validateUploadPath(resolved) {
4118
- const normalized = resolved.toLowerCase();
4119
- for (const prefix of SENSITIVE_PATH_PREFIXES) {
4120
- if (normalized === prefix.toLowerCase() || normalized.startsWith(prefix.toLowerCase() + path7.sep)) {
4121
- return `\u7981\u6B62\u4E0A\u4F20\u654F\u611F\u76EE\u5F55\u4E0B\u7684\u6587\u4EF6\uFF1A${prefix}`;
4122
- }
4123
- }
4124
- for (const abs of SENSITIVE_ABSOLUTE_PATHS) {
4125
- if (normalized === abs.toLowerCase()) {
4126
- return `\u7981\u6B62\u4E0A\u4F20\u7CFB\u7EDF\u654F\u611F\u6587\u4EF6\uFF1A${abs}`;
4127
- }
4128
- }
4129
- const base = path7.basename(resolved).toLowerCase();
4130
- if (base === ".env" || base.startsWith(".env.")) {
4131
- return `\u7981\u6B62\u4E0A\u4F20\u73AF\u5883\u53D8\u91CF\u6587\u4EF6\uFF08${path7.basename(resolved)}\uFF09\uFF0C\u53EF\u80FD\u5305\u542B\u5BC6\u94A5`;
4132
- }
4133
- return null;
4134
- }
4135
- var DEFAULT_FOLDER_ID = "77777777-7777-7777-7777-777777777777";
4136
4193
  var BLOCK_SIZE = 2 * 1024 * 1024;
4137
- var VIDEO_EXTS = [
4138
- ".mp4",
4139
- ".mov",
4140
- ".avi",
4141
- ".mkv",
4142
- ".flv",
4143
- ".f4v",
4144
- ".rmvb",
4145
- ".rm",
4146
- ".vob",
4147
- ".wmv",
4148
- ".3gp",
4149
- ".asf",
4150
- ".mpeg",
4151
- ".m4v",
4152
- ".mpg"
4153
- ];
4154
- var IMAGE_EXTS = [".jpg", ".jpeg", ".png", ".gif", ".arw"];
4155
- function detectKind(filePath) {
4156
- const ext = path7.extname(filePath).toLowerCase();
4157
- if (VIDEO_EXTS.includes(ext)) return "video";
4158
- if (IMAGE_EXTS.includes(ext)) return "image";
4159
- throw new Error(
4160
- `\u65E0\u6CD5\u8BC6\u522B\u6587\u4EF6\u7C7B\u578B\uFF1A${ext}\u3002
4161
- \u89C6\u9891\uFF1A${VIDEO_EXTS.join(", ")}
4162
- \u56FE\u7247\uFF1A${IMAGE_EXTS.join(", ")}`
4163
- );
4164
- }
4165
- function getMimeType(filePath) {
4166
- const map = {
4167
- ".mp4": "video/mp4",
4168
- ".mov": "video/quicktime",
4169
- ".avi": "video/avi",
4170
- ".mkv": "video/x-matroska",
4171
- ".flv": "video/x-flv",
4172
- ".wmv": "video/x-ms-wmv",
4173
- ".3gp": "video/3gpp",
4174
- ".jpg": "image/jpeg",
4175
- ".jpeg": "image/jpeg",
4176
- ".png": "image/png",
4177
- ".gif": "image/gif"
4178
- };
4179
- return map[path7.extname(filePath).toLowerCase()] ?? "application/octet-stream";
4180
- }
4181
- var guid2 = randomUUID;
4182
- async function generateSas(config, verbose = false) {
4183
- const url = `${config.csoBaseUrl}/cutapi/v1/material/generateuploadsas?account=cutapi&expirationMinutes=120`;
4184
- const res = await apiFetch2(url, config, {}, verbose);
4185
- if (res.code !== 1 || !res.data) {
4186
- throw new Error("\u7533\u8BF7\u4E0A\u4F20\u51ED\u8BC1\u5931\u8D25\uFF0C\u670D\u52A1\u7AEF\u8FD4\u56DE\u5F02\u5E38");
4187
- }
4188
- return res.data;
4189
- }
4190
- async function uploadToAzure(filePath, sas, onProgress) {
4191
- const ext = path7.extname(filePath);
4192
- const blobName = `${guid2()}${ext}`;
4193
- const containerClient = new ContainerClient(sas.sasUri);
4194
- const blockBlobClient = containerClient.getBlockBlobClient(blobName);
4195
- const fileSize = fs7.statSync(filePath).size;
4196
- await blockBlobClient.uploadFile(filePath, {
4197
- blockSize: BLOCK_SIZE,
4198
- blobHTTPHeaders: { blobContentType: getMimeType(filePath) },
4199
- onProgress: (ev) => {
4200
- if (onProgress && fileSize > 0) {
4201
- onProgress(Math.round(ev.loadedBytes / fileSize * 100));
4202
- }
4203
- }
4204
- });
4205
- const resourceUrl = `${sas.containerUri}/${blobName}`;
4206
- return { resourceUrl, blobName };
4207
- }
4208
- async function notifyUploaded(config, body, verbose = false) {
4209
- const url = `${config.csoBaseUrl}/cutapi/v1/material/uploadednotify`;
4210
- const res = await apiFetch2(
4211
- url,
4212
- config,
4213
- {
4214
- method: "POST",
4215
- body: JSON.stringify(body)
4216
- },
4217
- verbose
4218
- );
4219
- if (res.code !== 1 || !res.data?.id) {
4220
- const detail = verbose ? `\uFF1A${JSON.stringify(res)}` : "";
4221
- throw new Error(`\u7D20\u6750\u6CE8\u518C\u5931\u8D25${detail}`);
4222
- }
4223
- return res.data.id;
4224
- }
4225
- async function fetchMaterialInfo(config, id, verbose = false) {
4226
- try {
4227
- const url = `${config.csoBaseUrl}/cutapi/v1/material/${id}`;
4228
- const res = await apiFetch2(url, config, {}, verbose);
4229
- return res.data ?? {};
4230
- } catch {
4231
- return {};
4232
- }
4233
- }
4234
- function readMp4Duration(filePath) {
4235
- try {
4236
- const fileSize = fs7.statSync(filePath).size;
4237
- const chunkSize = Math.min(fileSize, 256 * 1024);
4238
- const bufEnd = Buffer.alloc(chunkSize);
4239
- const fdEnd = fs7.openSync(filePath, "r");
4240
- fs7.readSync(fdEnd, bufEnd, 0, chunkSize, fileSize - chunkSize);
4241
- fs7.closeSync(fdEnd);
4242
- const bufStart = Buffer.alloc(chunkSize);
4243
- const fdStart = fs7.openSync(filePath, "r");
4244
- fs7.readSync(fdStart, bufStart, 0, chunkSize, 0);
4245
- fs7.closeSync(fdStart);
4246
- const durationSec = parseMvhdFromBuffer(bufEnd) ?? parseMvhdFromBuffer(bufStart);
4247
- if (durationSec === null || durationSec <= 0) return null;
4248
- const h = Math.floor(durationSec / 3600);
4249
- const m = Math.floor(durationSec % 3600 / 60);
4250
- const s = Math.floor(durationSec % 60);
4251
- const ms = Math.round(durationSec % 1 * 1e3);
4252
- return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}.${String(ms).padStart(3, "0")}`;
4253
- } catch {
4254
- return null;
4255
- }
4256
- }
4257
- function parseMvhdFromBuffer(buf) {
4258
- const marker = Buffer.from("6d766864", "hex");
4259
- const idx = buf.lastIndexOf(marker);
4260
- if (idx < 4) return null;
4261
- const dataStart = idx + 4;
4262
- const version = buf[dataStart];
4263
- let timescale;
4264
- let durationVal;
4265
- if (version === 0) {
4266
- timescale = buf.readUInt32BE(dataStart + 1 + 3 + 4 + 4);
4267
- durationVal = buf.readUInt32BE(dataStart + 1 + 3 + 4 + 4 + 4);
4268
- } else if (version === 1) {
4269
- timescale = buf.readUInt32BE(dataStart + 1 + 3 + 8 + 8);
4270
- durationVal = buf.readUInt32BE(dataStart + 1 + 3 + 8 + 8 + 4 + 4);
4271
- } else {
4272
- return null;
4273
- }
4274
- if (timescale === 0) return null;
4275
- return durationVal / timescale;
4276
- }
4277
- function readImageDimensions(filePath) {
4278
- try {
4279
- const buf = fs7.readFileSync(filePath);
4280
- const dim = imageSize(buf);
4281
- return { width: dim.width, height: dim.height, format: (dim.type ?? "").toUpperCase() };
4282
- } catch {
4283
- return { width: 0, height: 0 };
4284
- }
4285
- }
4286
- async function uploadImageFile(filePath, config, verbose = false) {
4287
- const fileName = path7.basename(filePath);
4288
- const fileSize = fs7.statSync(filePath).size;
4289
- const format = path7.extname(filePath).replace(".", "").toUpperCase();
4290
- const sas = await generateSas(config, verbose);
4291
- const { resourceUrl } = await uploadToAzure(filePath, sas, void 0);
4292
- const dim = readImageDimensions(filePath);
4293
- const materialId = await notifyUploaded(
4294
- config,
4295
- {
4296
- folderId: DEFAULT_FOLDER_ID,
4297
- name: fileName,
4298
- url: resourceUrl,
4299
- fileSize,
4300
- type: 1,
4301
- source: 1,
4302
- blobAccount: sas.accountName,
4303
- blobContainer: sas.containerName,
4304
- format,
4305
- image: dim
4306
- },
4307
- verbose
4308
- );
4309
- const matInfo = await fetchMaterialInfo(config, materialId, verbose);
4310
- return {
4311
- resourceUrl,
4312
- materialId,
4313
- belongToId: matInfo?.belongToId,
4314
- belongTo: matInfo?.belongTo,
4315
- userId: matInfo?.userId
4316
- };
4317
- }
4194
+
4195
+ // src/commands/upload/commands.ts
4196
+ import * as fs8 from "fs";
4197
+ import * as path8 from "path";
4318
4198
  async function runUpload(options) {
4319
- const filePath = path7.resolve(options.file);
4320
- if (!fs7.existsSync(filePath)) {
4199
+ const filePath = path8.resolve(options.file);
4200
+ if (!fs8.existsSync(filePath)) {
4321
4201
  console.error(`
4322
4202
  \u274C \u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${filePath}`);
4323
4203
  process.exit(1);
@@ -4330,9 +4210,9 @@ async function runUpload(options) {
4330
4210
  }
4331
4211
  const kind = options.kind ?? detectKind(filePath);
4332
4212
  const config = loadConfig(options.token);
4333
- const fileName = path7.basename(filePath);
4334
- const fileSize = fs7.statSync(filePath).size;
4335
- const format = path7.extname(filePath).replace(".", "").toUpperCase();
4213
+ const fileName = path8.basename(filePath);
4214
+ const fileSize = fs8.statSync(filePath).size;
4215
+ const format = path8.extname(filePath).replace(".", "").toUpperCase();
4336
4216
  if (kind === "video" && !options.cover) {
4337
4217
  console.error("\n\u274C \u4E0A\u4F20\u89C6\u9891\u65F6\u5FC5\u987B\u901A\u8FC7 --cover <\u56FE\u7247\u8DEF\u5F84> \u6307\u5B9A\u5C01\u9762\u56FE\u7247");
4338
4218
  process.exit(1);
@@ -4347,8 +4227,8 @@ async function runUpload(options) {
4347
4227
  let coverUserId;
4348
4228
  const { verbose = false } = options;
4349
4229
  if (kind === "video" && options.cover) {
4350
- const coverPath = path7.resolve(options.cover);
4351
- if (!fs7.existsSync(coverPath)) {
4230
+ const coverPath = path8.resolve(options.cover);
4231
+ if (!fs8.existsSync(coverPath)) {
4352
4232
  console.error(`
4353
4233
  \u274C \u5C01\u9762\u56FE\u7247\u4E0D\u5B58\u5728\uFF1A${coverPath}`);
4354
4234
  process.exit(1);
@@ -4360,7 +4240,7 @@ async function runUpload(options) {
4360
4240
  process.exit(1);
4361
4241
  }
4362
4242
  console.log(`
4363
- 0\uFE0F\u20E3 \u4E0A\u4F20\u5C01\u9762\u56FE\u7247\uFF1A${path7.basename(coverPath)} \u2026`);
4243
+ 0\uFE0F\u20E3 \u4E0A\u4F20\u5C01\u9762\u56FE\u7247\uFF1A${path8.basename(coverPath)} \u2026`);
4364
4244
  try {
4365
4245
  const coverResult = await uploadImageFile(coverPath, config, verbose);
4366
4246
  thumbUrl = coverResult.resourceUrl;
@@ -4464,7 +4344,7 @@ async function runUpload(options) {
4464
4344
  ...matInfo?.duration ? { duration: matInfo.duration } : {},
4465
4345
  cover: {
4466
4346
  imageUrl: verbose ? coverUrl || "\uFF08\u8BF7\u624B\u52A8\u586B\u5199\u5C01\u9762\u56FE\u7247 URL\uFF09" : thumbUrl,
4467
- imageName: options.cover ? path7.basename(options.cover) : "cover.jpg",
4347
+ imageName: options.cover ? path8.basename(options.cover) : "cover.jpg",
4468
4348
  imageSourceType: 1,
4469
4349
  sourceImageId: coverMaterialId || void 0,
4470
4350
  imageCreateUserId: coverUserId || void 0,
@@ -4484,326 +4364,30 @@ async function runUpload(options) {
4484
4364
  sourceImageId: materialId,
4485
4365
  size: fileSize,
4486
4366
  ...matInfo?.image ? { width: matInfo.image.width, height: matInfo.image.height } : {}
4487
- };
4488
- console.log("\n\u2500\u2500 \u5C06\u4EE5\u4E0B\u5185\u5BB9\u7C98\u8D34\u5230 publish-config.json \u7684 posts[].images[] \u6216 cover\uFF1A\n");
4489
- console.log(JSON.stringify(imageConfig, null, 2));
4490
- }
4491
- }
4492
-
4493
- // src/commands/report.ts
4494
- import * as fs8 from "fs";
4495
- import * as path8 from "path";
4496
- var DEFAULT_METHOD = "Day";
4497
- var DEFAULT_WORKS_ORDER = "play";
4498
- var REPORT_MODULES = [
4499
- "operation",
4500
- "total-fans",
4501
- "fans-analysis",
4502
- "hot-topic",
4503
- "works",
4504
- "hot-comment-word",
4505
- "comment-top10",
4506
- "video-duration",
4507
- "video-distribution",
4508
- "comment-trend",
4509
- "fans-trend",
4510
- "new-fans-trend",
4511
- "homepage-visit"
4512
- ];
4513
- var MODULE_ALIAS = {
4514
- operation: "operation",
4515
- totalfans: "total-fans",
4516
- "total-fans": "total-fans",
4517
- fans: "fans-analysis",
4518
- "fans-analysis": "fans-analysis",
4519
- topic: "hot-topic",
4520
- "hot-topic": "hot-topic",
4521
- works: "works",
4522
- "hot-comment-word": "hot-comment-word",
4523
- hotcommentword: "hot-comment-word",
4524
- commenttop10: "comment-top10",
4525
- "comment-top10": "comment-top10",
4526
- videoduration: "video-duration",
4527
- "video-duration": "video-duration",
4528
- videodistribution: "video-distribution",
4529
- "video-distribution": "video-distribution",
4530
- commenttrend: "comment-trend",
4531
- "comment-trend": "comment-trend",
4532
- fanstrend: "fans-trend",
4533
- "fans-trend": "fans-trend",
4534
- newfanstrend: "new-fans-trend",
4535
- "new-fans-trend": "new-fans-trend",
4536
- homepagevisit: "homepage-visit",
4537
- "homepage-visit": "homepage-visit"
4538
- };
4539
- function exitWithError(message) {
4540
- console.error(`
4541
- \u274C ${message}
4542
- `);
4543
- process.exit(1);
4544
- }
4545
- function normalizeDateInput(value, kind) {
4546
- const hasTime = /[T\s]\d{1,2}:\d{1,2}(:\d{1,2})?/.test(value);
4547
- const date = hasTime ? new Date(value) : /* @__PURE__ */ new Date(`${value}${kind === "start" ? "T00:00:00" : "T23:59:59"}`);
4548
- if (Number.isNaN(date.getTime())) {
4549
- exitWithError(`\u65E5\u671F\u683C\u5F0F\u4E0D\u5408\u6CD5\uFF1A${value}\u3002\u8BF7\u4F7F\u7528 YYYY-MM-DD \u6216 ISO \u65E5\u671F\u65F6\u95F4\u3002`);
4550
- }
4551
- return date;
4552
- }
4553
- function formatUtcDateTime(date) {
4554
- const pad = (n) => String(n).padStart(2, "0");
4555
- return `${date.getUTCFullYear()}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())} ${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())}`;
4556
- }
4557
- function getDefaultDateRange(days = 30) {
4558
- const end = /* @__PURE__ */ new Date();
4559
- end.setDate(end.getDate() - 1);
4560
- end.setHours(23, 59, 59, 0);
4561
- const start = new Date(end);
4562
- start.setDate(start.getDate() - (days - 1));
4563
- start.setHours(0, 0, 0, 0);
4564
- return { startDate: start, endDate: end };
4565
- }
4566
- function parseMediaCustomerIds(value) {
4567
- if (!value || value.length === 0) return [];
4568
- const ids = value.flatMap((part) => part.split(",")).map((s) => s.trim()).filter(Boolean);
4569
- return Array.from(new Set(ids));
4570
- }
4571
- function ensureMethod(value) {
4572
- if (!value) return DEFAULT_METHOD;
4573
- if (value === "Day" || value === "Week" || value === "Moth") return value;
4574
- exitWithError(`--method \u4EC5\u652F\u6301 Day / Week / Moth\uFF0C\u6536\u5230\uFF1A${value}`);
4575
- }
4576
- function ensureWorksOrder(value) {
4577
- if (!value) return DEFAULT_WORKS_ORDER;
4578
- if (value === "play" || value === "digg" || value === "fullplay") return value;
4579
- exitWithError(`--order \u4EC5\u652F\u6301 play / digg / fullplay\uFF0C\u6536\u5230\uFF1A${value}`);
4580
- }
4581
- function parseModules(input) {
4582
- if (!input || input.length === 0) return [...REPORT_MODULES];
4583
- const modules = [];
4584
- for (const part of input) {
4585
- for (const raw of part.split(",")) {
4586
- const key = raw.trim().toLowerCase();
4587
- if (!key) continue;
4588
- const mapped = MODULE_ALIAS[key];
4589
- if (!mapped) {
4590
- exitWithError(`\u672A\u77E5\u6A21\u5757\uFF1A${raw}\u3002\u53EF\u9009\u503C\uFF1A${REPORT_MODULES.join(", ")}`);
4591
- }
4592
- modules.push(mapped);
4593
- }
4594
- }
4595
- return Array.from(new Set(modules));
4596
- }
4597
- function buildRuntime(opts) {
4598
- if (!opts.media) {
4599
- exitWithError("\u8BF7\u901A\u8FC7 --media \u6307\u5B9A\u5A92\u4F53\u7C7B\u578B\uFF0C\u4F8B\u5982 Douyin\u3001YouTube\u3002");
4600
- }
4601
- const config = loadConfig(opts.token);
4602
- const days = opts.days && opts.days > 0 ? opts.days : 30;
4603
- const { startDate: defaultStart, endDate: defaultEnd } = getDefaultDateRange(days);
4604
- const startDate = opts.start ? normalizeDateInput(opts.start, "start") : defaultStart;
4605
- const endDate = opts.end ? normalizeDateInput(opts.end, "end") : defaultEnd;
4606
- if (startDate.getTime() > endDate.getTime()) {
4607
- exitWithError("--start \u4E0D\u80FD\u665A\u4E8E --end");
4608
- }
4609
- const baseQuery = {
4610
- csoPlatformType: 2,
4611
- mediaTypes: [opts.media],
4612
- mediaCustomerIds: parseMediaCustomerIds(opts.maids),
4613
- startDate: formatUtcDateTime(startDate),
4614
- endDate: formatUtcDateTime(endDate)
4615
- };
4616
- return {
4617
- config,
4618
- baseQuery,
4619
- method: ensureMethod(opts.method),
4620
- verbose: Boolean(opts.verbose)
4621
- };
4622
- }
4623
- function createQueryString(query) {
4624
- const params = new URLSearchParams();
4625
- for (const [key, value] of Object.entries(query)) {
4626
- if (Array.isArray(value)) {
4627
- for (const item of value) {
4628
- params.append(key, item);
4629
- }
4630
- continue;
4631
- }
4632
- params.append(key, String(value));
4633
- }
4634
- return params.toString();
4635
- }
4636
- async function getWithQuery(runtime, endpoint, query) {
4637
- const url = `${runtime.config.csoBaseUrl}/cso/v1/accountData/${endpoint}?${createQueryString(query)}`;
4638
- const res = await apiFetch2(url, runtime.config, {}, runtime.verbose);
4639
- if (res.code !== 1) {
4640
- throw new Error(res.message || `\u8BF7\u6C42\u5931\u8D25\uFF1A${endpoint}`);
4641
- }
4642
- return res.data;
4643
- }
4644
- var MODULE_TITLES = {
4645
- "total-fans": "\u603B\u7C89\u4E1D\u6570",
4646
- "fans-analysis": "\u7C89\u4E1D\u5206\u6790",
4647
- "hot-topic": "\u70ED\u95E8\u8BDD\u9898",
4648
- "hot-comment-word": "\u70ED\u95E8\u8BC4\u8BBA\u8BCD",
4649
- "comment-top10": "\u8BC4\u8BBA Top10",
4650
- "video-duration": "\u89C6\u9891\u65F6\u957F\u5206\u5E03",
4651
- "video-distribution": "\u89C6\u9891\u5206\u5E03",
4652
- "comment-trend": "\u8BC4\u8BBA\u8D8B\u52BF",
4653
- "fans-trend": "\u7C89\u4E1D\u8D8B\u52BF",
4654
- "new-fans-trend": "\u65B0\u589E\u7C89\u4E1D\u8D8B\u52BF",
4655
- "homepage-visit": "\u4E3B\u9875\u8BBF\u95EE\u8D8B\u52BF"
4656
- };
4657
- function renderMarkdownArrayOfObjects(rows) {
4658
- if (rows.length === 0) {
4659
- return;
4660
- }
4661
- const keys = Object.keys(rows[0]);
4662
- console.log("| " + keys.join(" | ") + " |");
4663
- console.log("| " + keys.map(() => "---").join(" | ") + " |");
4664
- for (const row of rows) {
4665
- console.log("| " + keys.map((k) => String(row[k] ?? "-")).join(" | ") + " |");
4666
- }
4667
- console.log();
4668
- }
4669
- function isTimeSeries(arr) {
4670
- if (arr.length === 0) return false;
4671
- const first = arr[0];
4672
- if ("date" in first && "count" in first) return true;
4673
- if ("name" in first && "value" in first) {
4674
- const name = first.name;
4675
- return typeof name === "number" || typeof name === "string" && /^\d{4}-\d{2}-\d{2}/.test(name);
4676
- }
4677
- return false;
4678
- }
4679
- function renderTimeSeries(arr) {
4680
- const keyField = "date" in arr[0] ? "date" : "name";
4681
- const valField = "count" in arr[0] ? "count" : "value";
4682
- const nonZero = arr.filter((item) => {
4683
- const v = item[valField];
4684
- return v !== null && v !== void 0 && Number(v) !== 0;
4685
- });
4686
- if (nonZero.length === 0) {
4687
- console.log(`_\uFF08${arr.length}\u6761\u5747\u4E3A0\uFF09_
4688
- `);
4689
- return;
4690
- }
4691
- if (nonZero.length <= 6) {
4692
- const pairs = nonZero.map((item) => `${item[keyField]}:${item[valField]}`).join(", ");
4693
- const zeroCount = arr.length - nonZero.length;
4694
- console.log(`${pairs}${zeroCount > 0 ? `\uFF08\u5176\u4F59${zeroCount}\u6761\u4E3A0\uFF09` : ""}
4695
- `);
4696
- return;
4697
- }
4698
- renderMarkdownArrayOfObjects(arr);
4699
- }
4700
- function renderMarkdownValue(data) {
4701
- if (data === null || data === void 0) return;
4702
- if (Array.isArray(data)) {
4703
- if (data.length === 0) return;
4704
- if (typeof data[0] === "object" && data[0] !== null) {
4705
- const rows = data;
4706
- if (isTimeSeries(rows)) {
4707
- renderTimeSeries(rows);
4708
- } else {
4709
- renderMarkdownArrayOfObjects(rows);
4710
- }
4711
- } else {
4712
- for (const item of data) console.log(`- ${String(item)}`);
4713
- console.log();
4714
- }
4715
- return;
4716
- }
4717
- if (typeof data === "object") {
4718
- const obj = data;
4719
- const keys = Object.keys(obj);
4720
- if (keys.length === 0) return;
4721
- const summaryParts = [];
4722
- for (const key of keys) {
4723
- const val = obj[key];
4724
- if (Array.isArray(val) && val.length > 0 && typeof val[0] === "object") {
4725
- if (summaryParts.length > 0) {
4726
- console.log(summaryParts.join(" | ") + "\n");
4727
- summaryParts.length = 0;
4728
- }
4729
- console.log(`**${key}**`);
4730
- renderMarkdownValue(val);
4731
- } else if (!Array.isArray(val)) {
4732
- summaryParts.push(`${key}: ${JSON.stringify(val)}`);
4733
- }
4734
- }
4735
- if (summaryParts.length > 0) console.log(summaryParts.join(" | ") + "\n");
4736
- return;
4737
- }
4738
- console.log(String(data) + "\n");
4739
- }
4740
- function printMarkdownFetch(runtime, includeModules, sections) {
4741
- const accountScope = runtime.baseQuery.mediaCustomerIds.length > 0 ? runtime.baseQuery.mediaCustomerIds.join(", ") : "\u5168\u90E8\u8D26\u53F7";
4742
- const startDay = runtime.baseQuery.startDate.slice(0, 10);
4743
- const endDay = runtime.baseQuery.endDate.slice(0, 10);
4744
- console.log(
4745
- `# \u8FD0\u8425\u62A5\u8868\uFF5C${runtime.baseQuery.mediaTypes.join(",")}\uFF5C${accountScope}\uFF5C${startDay}~${endDay}\uFF5C${runtime.method}
4746
- `
4747
- );
4748
- if (sections.operation && typeof sections.operation === "object") {
4749
- const op = sections.operation;
4750
- const core = Array.isArray(op.coreData) ? [...op.coreData] : [];
4751
- if (typeof sections["total-fans"] === "number") {
4752
- if (!core.some((item) => item.name === "TotalFans")) {
4753
- core.push({
4754
- name: "TotalFans",
4755
- value: sections["total-fans"],
4756
- incrementRate: null
4757
- });
4758
- }
4759
- }
4760
- console.log("## \u6838\u5FC3\u6307\u6807\n");
4761
- if (core.length > 0) {
4762
- console.log("| \u6307\u6807 | \u5F53\u524D\u503C | \u73AF\u6BD4(%) |");
4763
- console.log("| --- | --- | --- |");
4764
- for (const item of core) {
4765
- const val = item.value === null || item.value === void 0 ? "-" : String(item.value);
4766
- const rate = item.incrementRate === null || item.incrementRate === void 0 ? "-" : String(item.incrementRate);
4767
- console.log(`| ${item.name} | ${val} | ${rate} |`);
4768
- }
4769
- console.log();
4770
- } else {
4771
- console.log("_\uFF08\u65E0\u6838\u5FC3\u6307\u6807\u6570\u636E\uFF09_\n");
4772
- }
4773
- }
4774
- if (Array.isArray(sections.works)) {
4775
- const works = sections.works;
4776
- console.log("## \u89C6\u9891\u660E\u7EC6\n");
4777
- if (works.length > 0) {
4778
- console.log("| \u6392\u540D | \u6807\u9898 | \u64AD\u653E | \u70B9\u8D5E | \u8BC4\u8BBA |");
4779
- console.log("| --- | --- | --- | --- | --- |");
4780
- works.forEach((item, idx) => {
4781
- const title = String(item.title ?? item.name ?? "-");
4782
- const play = String(item.play ?? item.playCount ?? "-");
4783
- const digg = String(item.digg ?? item.likeCount ?? "-");
4784
- const comment = String(item.comment ?? item.commentCount ?? "-");
4785
- console.log(`| ${idx + 1} | ${title} | ${play} | ${digg} | ${comment} |`);
4786
- });
4787
- console.log();
4788
- } else {
4789
- console.log("_\uFF08\u65E0\u89C6\u9891\u6570\u636E\uFF09_\n");
4790
- }
4367
+ };
4368
+ console.log("\n\u2500\u2500 \u5C06\u4EE5\u4E0B\u5185\u5BB9\u7C98\u8D34\u5230 publish-config.json \u7684 posts[].images[] \u6216 cover\uFF1A\n");
4369
+ console.log(JSON.stringify(imageConfig, null, 2));
4791
4370
  }
4792
- const otherModules = includeModules.filter(
4793
- (m) => m !== "operation" && m !== "works" && m !== "total-fans"
4794
- );
4795
- for (const moduleName of otherModules) {
4796
- const data = sections[moduleName];
4797
- if (data === null || data === void 0) continue;
4798
- if (Array.isArray(data) && data.length === 0) continue;
4799
- if (typeof data === "object" && !Array.isArray(data) && Object.keys(data).length === 0)
4371
+ }
4372
+
4373
+ // src/commands/report/_shared.ts
4374
+ function createQueryString2(query) {
4375
+ const params = new URLSearchParams();
4376
+ for (const [key, value] of Object.entries(query)) {
4377
+ if (Array.isArray(value)) {
4378
+ for (const item of value) {
4379
+ params.append(key, item);
4380
+ }
4800
4381
  continue;
4801
- const title = MODULE_TITLES[moduleName] ?? moduleName;
4802
- console.log(`## ${title}
4803
- `);
4804
- renderMarkdownValue(data);
4382
+ }
4383
+ params.append(key, String(value));
4805
4384
  }
4385
+ return params.toString();
4806
4386
  }
4387
+
4388
+ // src/commands/report/commands.ts
4389
+ import * as fs9 from "fs";
4390
+ import * as path9 from "path";
4807
4391
  async function runReportFetch(options) {
4808
4392
  const runtime = buildRuntime(options);
4809
4393
  const includeModules = parseModules(options.include);
@@ -4925,7 +4509,7 @@ async function runReportFetch(options) {
4925
4509
  }
4926
4510
  printMarkdownFetch(runtime, includeModules, sections);
4927
4511
  }
4928
- function parsePositiveInt(value, optionName, defaultValue) {
4512
+ function parsePositiveInt2(value, optionName, defaultValue) {
4929
4513
  if (!value) return defaultValue;
4930
4514
  const num = Number(value);
4931
4515
  if (!Number.isInteger(num) || num <= 0) {
@@ -4955,10 +4539,10 @@ function renderRecordTable(list, unicode = false) {
4955
4539
  }
4956
4540
  async function runReportRecords(options) {
4957
4541
  const config = loadConfig(options.token);
4958
- const page = parsePositiveInt(options.page, "--page", 1);
4959
- const size = parsePositiveInt(options.pageSize, "--page-size", 20);
4542
+ const page = parsePositiveInt2(options.page, "--page", 1);
4543
+ const size = parsePositiveInt2(options.pageSize, "--page-size", 20);
4960
4544
  const verbose = Boolean(options.verbose);
4961
- const url = `${config.csoBaseUrl}/cso/v1/accountData/OperationsReportRecord/2?` + createQueryString({ page, size });
4545
+ const url = `${config.csoBaseUrl}/cso/v1/accountData/OperationsReportRecord/2?` + createQueryString2({ page, size });
4962
4546
  let data;
4963
4547
  try {
4964
4548
  const res = await apiFetch2(url, config, {}, verbose);
@@ -4987,7 +4571,7 @@ function defaultDownloadPath(recordId) {
4987
4571
  const now = /* @__PURE__ */ new Date();
4988
4572
  const pad = (n) => String(n).padStart(2, "0");
4989
4573
  const name = `operations-report-${recordId}-${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}.pdf`;
4990
- return path8.resolve(process.cwd(), name);
4574
+ return path9.resolve(process.cwd(), name);
4991
4575
  }
4992
4576
  async function downloadFile(url, output) {
4993
4577
  const res = await fetch(url);
@@ -4995,7 +4579,7 @@ async function downloadFile(url, output) {
4995
4579
  throw new Error(`\u4E0B\u8F7D\u5931\u8D25\uFF0CHTTP ${res.status}`);
4996
4580
  }
4997
4581
  const buffer = Buffer.from(await res.arrayBuffer());
4998
- fs8.writeFileSync(output, buffer);
4582
+ fs9.writeFileSync(output, buffer);
4999
4583
  }
5000
4584
  async function runReportDownload(options) {
5001
4585
  if (!options.id) {
@@ -5003,7 +4587,7 @@ async function runReportDownload(options) {
5003
4587
  }
5004
4588
  const config = loadConfig(options.token);
5005
4589
  const verbose = Boolean(options.verbose);
5006
- const url = `${config.csoBaseUrl}/cso/v1/accountData/DownLoadOperationsReport/2?` + createQueryString({ id: options.id });
4590
+ const url = `${config.csoBaseUrl}/cso/v1/accountData/DownLoadOperationsReport/2?` + createQueryString2({ id: options.id });
5007
4591
  let pdfUrl = "";
5008
4592
  try {
5009
4593
  const res = await apiFetch2(url, config, { method: "POST" }, verbose);
@@ -5015,7 +4599,7 @@ async function runReportDownload(options) {
5015
4599
  const msg = error.message;
5016
4600
  exitWithError(`\u83B7\u53D6\u4E0B\u8F7D\u5730\u5740\u5931\u8D25\uFF1A${msg}`);
5017
4601
  }
5018
- const output = path8.resolve(options.output ? options.output : defaultDownloadPath(options.id));
4602
+ const output = path9.resolve(options.output ? options.output : defaultDownloadPath(options.id));
5019
4603
  try {
5020
4604
  await downloadFile(pdfUrl, output);
5021
4605
  } catch (error) {
@@ -5028,9 +4612,7 @@ async function runReportDownload(options) {
5028
4612
  `);
5029
4613
  }
5030
4614
 
5031
- // src/commands/planning.ts
5032
- import * as fs9 from "fs";
5033
- import * as path9 from "path";
4615
+ // src/commands/planning/_shared.ts
5034
4616
  var TOPIC_FOLDER_ID = "88888888-8888-8888-0000-888888888888";
5035
4617
  var DEFAULT_CONTENT_TYPES = [
5036
4618
  { id: "post", label: "\u56FE\u6587" },
@@ -5061,7 +4643,7 @@ function normalizeApiPayload(raw) {
5061
4643
  }
5062
4644
  return raw;
5063
4645
  }
5064
- function createQueryString2(query) {
4646
+ function createQueryString3(query) {
5065
4647
  const params = new URLSearchParams();
5066
4648
  for (const [key, value] of Object.entries(query)) {
5067
4649
  if (value === void 0 || value === null || value === "") continue;
@@ -5069,7 +4651,7 @@ function createQueryString2(query) {
5069
4651
  }
5070
4652
  return params.toString();
5071
4653
  }
5072
- function parsePositiveInt2(value, optionName, defaultValue) {
4654
+ function parsePositiveInt3(value, optionName, defaultValue) {
5073
4655
  if (!value) return defaultValue;
5074
4656
  const num = Number(value);
5075
4657
  if (!Number.isInteger(num) || num <= 0) {
@@ -5220,12 +4802,16 @@ async function requestPlanning(config, endpoint, init = {}, verbose = false) {
5220
4802
  };
5221
4803
  return apiFetch2(url, config, { ...init, headers }, verbose);
5222
4804
  }
4805
+
4806
+ // src/commands/planning/commands.ts
4807
+ import * as fs10 from "fs";
4808
+ import * as path10 from "path";
5223
4809
  async function runPlanningEnterprises(options) {
5224
4810
  const config = loadConfig(options.token);
5225
4811
  const verbose = Boolean(options.verbose);
5226
- const pageSize = parsePositiveInt2(options.pageSize, "--page-size", 100);
4812
+ const pageSize = parsePositiveInt3(options.pageSize, "--page-size", 100);
5227
4813
  const belongToId = String(options.belongToId ?? "").trim();
5228
- const query = createQueryString2({
4814
+ const query = createQueryString3({
5229
4815
  folderId: TOPIC_FOLDER_ID,
5230
4816
  belongTo: 0,
5231
4817
  belongToId,
@@ -5505,10 +5091,10 @@ async function runPlanningGenerate(options) {
5505
5091
  async function runPlanningList(options) {
5506
5092
  const config = loadConfig(options.token);
5507
5093
  const verbose = Boolean(options.verbose);
5508
- const pageIndex = parsePositiveInt2(options.pageIndex, "--page-index", 1);
5509
- const pageSize = parsePositiveInt2(options.pageSize, "--page-size", 10);
5094
+ const pageIndex = parsePositiveInt3(options.pageIndex, "--page-index", 1);
5095
+ const pageSize = parsePositiveInt3(options.pageSize, "--page-size", 10);
5510
5096
  const yearMonth = options.yearMonth ? ensureYearMonth(options.yearMonth, "--year-month") : void 0;
5511
- const query = createQueryString2({
5097
+ const query = createQueryString3({
5512
5098
  enterpriseId: options.enterpriseId?.trim() || void 0,
5513
5099
  yearMonth,
5514
5100
  pageIndex,
@@ -5721,13 +5307,13 @@ function inferEnterpriseNameFromPlan(plan) {
5721
5307
  }
5722
5308
  async function loadPlanFromSource(options, config) {
5723
5309
  if (options.input) {
5724
- const inputPath = path9.resolve(options.input);
5725
- if (!fs9.existsSync(inputPath)) {
5310
+ const inputPath = path10.resolve(options.input);
5311
+ if (!fs10.existsSync(inputPath)) {
5726
5312
  exitWithError2(`\u8F93\u5165\u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${inputPath}`);
5727
5313
  }
5728
5314
  let raw = "";
5729
5315
  try {
5730
- raw = fs9.readFileSync(inputPath, "utf-8");
5316
+ raw = fs10.readFileSync(inputPath, "utf-8");
5731
5317
  } catch (error) {
5732
5318
  exitWithError2(`\u8BFB\u53D6\u8F93\u5165\u6587\u4EF6\u5931\u8D25\uFF1A${error.message}`);
5733
5319
  }
@@ -5761,9 +5347,9 @@ async function runPlanningExportTxt(options) {
5761
5347
  const defaultName = sanitizeFilename(
5762
5348
  `\u5185\u5BB9\u9009\u9898\u65B9\u5411\u89C4\u5212_${enterpriseName}_${plan.yearMonth ?? "unknown"}.txt`
5763
5349
  );
5764
- const outputPath = path9.resolve(options.output ? options.output : defaultName);
5350
+ const outputPath = path10.resolve(options.output ? options.output : defaultName);
5765
5351
  try {
5766
- fs9.writeFileSync(outputPath, text, "utf-8");
5352
+ fs10.writeFileSync(outputPath, text, "utf-8");
5767
5353
  } catch (error) {
5768
5354
  exitWithError2(`\u5199\u5165\u5BFC\u51FA\u6587\u4EF6\u5931\u8D25\uFF1A${error.message}`);
5769
5355
  }
@@ -5778,86 +5364,7 @@ async function runPlanningExportTxt(options) {
5778
5364
  `);
5779
5365
  }
5780
5366
 
5781
- // src/commands/task.ts
5782
- var TASK_MEDIA_MAP = {
5783
- Kuaishou: 11,
5784
- Douyin: 12,
5785
- TikTokBusinessAccount: 13,
5786
- WeChatChannel: 14,
5787
- Facebook: 5,
5788
- YouTube: 8,
5789
- Instagram: 18,
5790
- Linkedin: 19,
5791
- Twitter: 22
5792
- };
5793
- function exitWithError3(message) {
5794
- console.error(`
5795
- \u274C ${message}
5796
- `);
5797
- process.exit(1);
5798
- }
5799
- function parsePositiveInt3(input, field, defaultValue) {
5800
- if (!input) return defaultValue;
5801
- const n = Number(input);
5802
- if (!Number.isInteger(n) || n <= 0) {
5803
- exitWithError3(`${field} \u5FC5\u987B\u662F\u6B63\u6574\u6570\uFF0C\u6536\u5230\uFF1A${input}`);
5804
- }
5805
- return n;
5806
- }
5807
- function parseTaskStatus(input) {
5808
- if (!input) return -1;
5809
- const n = Number(input);
5810
- if (n === -1 || n === 0 || n === 1 || n === 2) return n;
5811
- exitWithError3(`--status \u4EC5\u652F\u6301 -1 | 0 | 1 | 2\uFF0C\u6536\u5230\uFF1A${input}`);
5812
- }
5813
- function parseContentType(input) {
5814
- if (!input || input === "all") return void 0;
5815
- if (input === "video") return "Video";
5816
- if (input === "image-text") return "ImageText";
5817
- exitWithError3(`--content-type \u4EC5\u652F\u6301 all | video | image-text\uFF0C\u6536\u5230\uFF1A${input}`);
5818
- }
5819
- function formatDateRange(datePreset, startDateInput, endDateInput) {
5820
- if (startDateInput || endDateInput) {
5821
- if (!startDateInput || !endDateInput) {
5822
- exitWithError3("\u4F7F\u7528\u81EA\u5B9A\u4E49\u65F6\u95F4\u65F6\uFF0C--start-date \u548C --end-date \u5FC5\u987B\u540C\u65F6\u63D0\u4F9B");
5823
- }
5824
- return {
5825
- startDate: `${startDateInput} 00:00:00`,
5826
- endDate: `${endDateInput} 23:59:59`
5827
- };
5828
- }
5829
- if (!datePreset || datePreset === "all") {
5830
- return { startDate: "", endDate: "" };
5831
- }
5832
- const now = /* @__PURE__ */ new Date();
5833
- const start = new Date(now);
5834
- if (datePreset === "week") start.setDate(now.getDate() - 7);
5835
- if (datePreset === "month") start.setMonth(now.getMonth() - 1);
5836
- if (datePreset === "year") start.setFullYear(now.getFullYear() - 1);
5837
- const pad = (v) => String(v).padStart(2, "0");
5838
- const fmt = (d) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
5839
- return {
5840
- startDate: `${fmt(start)} 00:00:00`,
5841
- endDate: `${fmt(now)} 23:59:59`
5842
- };
5843
- }
5844
- function createQueryString3(query) {
5845
- const params = new URLSearchParams();
5846
- for (const [key, value] of Object.entries(query)) {
5847
- if (value === void 0 || value === null) continue;
5848
- params.append(key, String(value));
5849
- }
5850
- return params.toString();
5851
- }
5852
- function resolveMediaTypeForApi(input) {
5853
- const trimmed = input.trim();
5854
- if (!trimmed) exitWithError3("\u5A92\u4F53\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A");
5855
- if (/^\d+$/.test(trimmed)) return trimmed;
5856
- if (trimmed in TASK_MEDIA_MAP) return String(TASK_MEDIA_MAP[trimmed]);
5857
- exitWithError3(
5858
- `\u672A\u77E5\u5A92\u4F53\u7C7B\u578B\uFF1A${input}\u3002\u53EF\u7528\u503C\uFF1A${Object.keys(TASK_MEDIA_MAP).join(", ")} \u6216\u6570\u5B57 ID`
5859
- );
5860
- }
5367
+ // src/commands/task/_shared.ts
5861
5368
  function statusLabel(status) {
5862
5369
  if (status === 0) return "\u6267\u884C\u4E2D";
5863
5370
  if (status === 1) return "\u5DF2\u5B8C\u6210";
@@ -5872,40 +5379,15 @@ function itemStatusLabel(status) {
5872
5379
  if (status === 9) return "\u5B9A\u65F6\u53D1\u5E03";
5873
5380
  return status === void 0 ? "-" : String(status);
5874
5381
  }
5875
- function tableOpts(unicode) {
5876
- return unicode ? { plain: false } : void 0;
5877
- }
5878
5382
  function isTaskMutationSuccess(code) {
5879
5383
  return code === 1 || code !== 400;
5880
5384
  }
5881
- async function postForm(endpoint, body, options) {
5882
- const config = loadConfig(options.token);
5883
- return apiFetch2(
5884
- `${config.csoBaseUrl}${endpoint}`,
5885
- config,
5886
- {
5887
- method: "POST",
5888
- headers: { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" },
5889
- body: new URLSearchParams(body).toString()
5890
- },
5891
- Boolean(options.verbose)
5892
- );
5893
- }
5894
- async function postNoBody(endpoint, options) {
5895
- const config = loadConfig(options.token);
5896
- return apiFetch2(
5897
- `${config.csoBaseUrl}${endpoint}`,
5898
- config,
5899
- {
5900
- method: "POST"
5901
- },
5902
- Boolean(options.verbose)
5903
- );
5904
- }
5385
+
5386
+ // src/commands/task/commands.ts
5905
5387
  async function runTaskList(options) {
5906
5388
  const config = loadConfig(options.token);
5907
- const page = parsePositiveInt3(options.page, "--page", 1);
5908
- const size = parsePositiveInt3(options.size, "--size", 10);
5389
+ const page = parsePositiveInt(options.page, "--page", 1);
5390
+ const size = parsePositiveInt(options.size, "--size", 10);
5909
5391
  const status = parseTaskStatus(options.status);
5910
5392
  const contentType = parseContentType(options.contentType);
5911
5393
  const { startDate, endDate } = formatDateRange(
@@ -5918,14 +5400,14 @@ async function runTaskList(options) {
5918
5400
  let creator = options.creator ?? "";
5919
5401
  if (options.mine) {
5920
5402
  if (!options.mineName) {
5921
- exitWithError3("\u4F7F\u7528 --mine \u65F6\u9700\u8981\u63D0\u4F9B --mine-name <\u4F60\u7684\u7528\u6237\u540D>");
5403
+ exitWithError("\u4F7F\u7528 --mine \u65F6\u9700\u8981\u63D0\u4F9B --mine-name <\u4F60\u7684\u7528\u6237\u540D>");
5922
5404
  }
5923
5405
  creator = options.mineName;
5924
5406
  } else if (options.keyword) {
5925
5407
  if (options.searchType === "creator") creator = options.keyword;
5926
5408
  else taskName = options.keyword;
5927
5409
  }
5928
- const url = `${config.csoBaseUrl}/cso/v1/task/taskList/2?${createQueryString3({
5410
+ const url = `${config.csoBaseUrl}/cso/v1/task/taskList/2?${createQueryString({
5929
5411
  page,
5930
5412
  size,
5931
5413
  status,
@@ -5948,7 +5430,7 @@ async function runTaskList(options) {
5948
5430
  if (!res.data) throw new Error(res.message || "\u670D\u52A1\u7AEF\u672A\u8FD4\u56DE\u5217\u8868\u6570\u636E");
5949
5431
  data = res.data;
5950
5432
  } catch (error) {
5951
- exitWithError3(`\u83B7\u53D6\u4EFB\u52A1\u5217\u8868\u5931\u8D25\uFF1A${error.message}`);
5433
+ exitWithError(`\u83B7\u53D6\u4EFB\u52A1\u5217\u8868\u5931\u8D25\uFF1A${error.message}`);
5952
5434
  }
5953
5435
  const list = Array.isArray(data.list) ? data.list : [];
5954
5436
  const total = data.total ?? 0;
@@ -5984,12 +5466,12 @@ async function runTaskList(options) {
5984
5466
  console.log();
5985
5467
  }
5986
5468
  async function runTaskDetail(options) {
5987
- if (!options.publishId) exitWithError3("\u8BF7\u63D0\u4F9B --publish-id");
5469
+ if (!options.publishId) exitWithError("\u8BF7\u63D0\u4F9B --publish-id");
5988
5470
  const config = loadConfig(options.token);
5989
- const page = parsePositiveInt3(options.page, "--page", 1);
5990
- const size = parsePositiveInt3(options.size, "--size", 10);
5471
+ const page = parsePositiveInt(options.page, "--page", 1);
5472
+ const size = parsePositiveInt(options.size, "--size", 10);
5991
5473
  const mediaType = options.media ? resolveMediaTypeForApi(options.media) : null;
5992
- const url = `${config.csoBaseUrl}/cso/v1/task/taskDetail/2?${createQueryString3({
5474
+ const url = `${config.csoBaseUrl}/cso/v1/task/taskDetail/2?${createQueryString({
5993
5475
  publishId: options.publishId,
5994
5476
  page,
5995
5477
  size,
@@ -6006,7 +5488,7 @@ async function runTaskDetail(options) {
6006
5488
  if (!res.data) throw new Error(res.message || "\u670D\u52A1\u7AEF\u672A\u8FD4\u56DE\u8BE6\u60C5\u6570\u636E");
6007
5489
  data = res.data;
6008
5490
  } catch (error) {
6009
- exitWithError3(`\u83B7\u53D6\u4EFB\u52A1\u8BE6\u60C5\u5931\u8D25\uFF1A${error.message}`);
5491
+ exitWithError(`\u83B7\u53D6\u4EFB\u52A1\u8BE6\u60C5\u5931\u8D25\uFF1A${error.message}`);
6010
5492
  }
6011
5493
  const list = Array.isArray(data.list) ? data.list : [];
6012
5494
  const raw = data;
@@ -6059,17 +5541,17 @@ async function runTaskMutation(endpoint, body, options, successText) {
6059
5541
  try {
6060
5542
  res = body ? await postForm(endpoint, body, options) : await postNoBody(endpoint, options);
6061
5543
  } catch (error) {
6062
- exitWithError3(`${successText}\u5931\u8D25\uFF1A${error.message}`);
5544
+ exitWithError(`${successText}\u5931\u8D25\uFF1A${error.message}`);
6063
5545
  }
6064
5546
  if (!isTaskMutationSuccess(res.code)) {
6065
- exitWithError3(res.message || `${successText}\u5931\u8D25\uFF08code=${res.code}\uFF09`);
5547
+ exitWithError(res.message || `${successText}\u5931\u8D25\uFF08code=${res.code}\uFF09`);
6066
5548
  }
6067
5549
  console.log(`
6068
5550
  \u2705 ${successText}\u6210\u529F
6069
5551
  `);
6070
5552
  }
6071
5553
  async function runTaskStart(options) {
6072
- if (!options.publishId) exitWithError3("\u8BF7\u63D0\u4F9B --publish-id");
5554
+ if (!options.publishId) exitWithError("\u8BF7\u63D0\u4F9B --publish-id");
6073
5555
  await runTaskMutation(
6074
5556
  "/cso/v1/task/startTask",
6075
5557
  { publishId: options.publishId },
@@ -6078,7 +5560,7 @@ async function runTaskStart(options) {
6078
5560
  );
6079
5561
  }
6080
5562
  async function runTaskStop(options) {
6081
- if (!options.publishId) exitWithError3("\u8BF7\u63D0\u4F9B --publish-id");
5563
+ if (!options.publishId) exitWithError("\u8BF7\u63D0\u4F9B --publish-id");
6082
5564
  await runTaskMutation(
6083
5565
  "/cso/v1/task/stopTask",
6084
5566
  { publishId: options.publishId },
@@ -6087,7 +5569,7 @@ async function runTaskStop(options) {
6087
5569
  );
6088
5570
  }
6089
5571
  async function runTaskDelete(options) {
6090
- if (!options.publishId) exitWithError3("\u8BF7\u63D0\u4F9B --publish-id");
5572
+ if (!options.publishId) exitWithError("\u8BF7\u63D0\u4F9B --publish-id");
6091
5573
  await runTaskMutation(
6092
5574
  "/cso/v1/task/deleteTask",
6093
5575
  { publishId: options.publishId },
@@ -6096,8 +5578,8 @@ async function runTaskDelete(options) {
6096
5578
  );
6097
5579
  }
6098
5580
  async function runTaskRename(options) {
6099
- if (!options.publishId) exitWithError3("\u8BF7\u63D0\u4F9B --publish-id");
6100
- if (!options.name?.trim()) exitWithError3("\u8BF7\u63D0\u4F9B\u975E\u7A7A\u7684 --name");
5581
+ if (!options.publishId) exitWithError("\u8BF7\u63D0\u4F9B --publish-id");
5582
+ if (!options.name?.trim()) exitWithError("\u8BF7\u63D0\u4F9B\u975E\u7A7A\u7684 --name");
6101
5583
  let res;
6102
5584
  try {
6103
5585
  res = await postForm(
@@ -6109,25 +5591,25 @@ async function runTaskRename(options) {
6109
5591
  options
6110
5592
  );
6111
5593
  } catch (error) {
6112
- exitWithError3(`\u91CD\u547D\u540D\u4EFB\u52A1\u5931\u8D25\uFF1A${error.message}`);
5594
+ exitWithError(`\u91CD\u547D\u540D\u4EFB\u52A1\u5931\u8D25\uFF1A${error.message}`);
6113
5595
  }
6114
5596
  if (res.code !== 1) {
6115
- exitWithError3(res.message || `\u91CD\u547D\u540D\u4EFB\u52A1\u5931\u8D25\uFF08code=${res.code}\uFF09`);
5597
+ exitWithError(res.message || `\u91CD\u547D\u540D\u4EFB\u52A1\u5931\u8D25\uFF08code=${res.code}\uFF09`);
6116
5598
  }
6117
5599
  console.log("\n\u2705 \u91CD\u547D\u540D\u4EFB\u52A1\u6210\u529F\n");
6118
5600
  }
6119
5601
  async function runTaskCheckEdit(options) {
6120
- if (!options.publishId) exitWithError3("\u8BF7\u63D0\u4F9B --publish-id");
5602
+ if (!options.publishId) exitWithError("\u8BF7\u63D0\u4F9B --publish-id");
6121
5603
  const config = loadConfig(options.token);
6122
- const url = `${config.csoBaseUrl}/cso/v1/task/checkAllowChange?${createQueryString3({ publishId: options.publishId })}`;
5604
+ const url = `${config.csoBaseUrl}/cso/v1/task/checkAllowChange?${createQueryString({ publishId: options.publishId })}`;
6123
5605
  let res;
6124
5606
  try {
6125
5607
  res = await apiFetch2(url, config, {}, Boolean(options.verbose));
6126
5608
  } catch (error) {
6127
- exitWithError3(`\u68C0\u67E5\u53EF\u7F16\u8F91\u72B6\u6001\u5931\u8D25\uFF1A${error.message}`);
5609
+ exitWithError(`\u68C0\u67E5\u53EF\u7F16\u8F91\u72B6\u6001\u5931\u8D25\uFF1A${error.message}`);
6128
5610
  }
6129
5611
  if (res.code !== 1 || !res.data) {
6130
- exitWithError3(res.message || `\u68C0\u67E5\u53EF\u7F16\u8F91\u72B6\u6001\u5931\u8D25\uFF08code=${res.code}\uFF09`);
5612
+ exitWithError(res.message || `\u68C0\u67E5\u53EF\u7F16\u8F91\u72B6\u6001\u5931\u8D25\uFF08code=${res.code}\uFF09`);
6131
5613
  }
6132
5614
  const allowChange = Boolean(res.data.allowChange);
6133
5615
  if (options.json) {
@@ -6142,7 +5624,7 @@ allowChange: ${allowChange ? "true" : "false"}`);
6142
5624
  console.log();
6143
5625
  }
6144
5626
  async function runTaskItemDelete(options) {
6145
- if (!options.itemId) exitWithError3("\u8BF7\u63D0\u4F9B --item-id");
5627
+ if (!options.itemId) exitWithError("\u8BF7\u63D0\u4F9B --item-id");
6146
5628
  await runTaskMutation(
6147
5629
  `/cso/v1/task/deletePublishItem/${options.itemId}`,
6148
5630
  null,
@@ -6151,17 +5633,17 @@ async function runTaskItemDelete(options) {
6151
5633
  );
6152
5634
  }
6153
5635
  async function runTaskItemRepublish(options) {
6154
- if (!options.itemId) exitWithError3("\u8BF7\u63D0\u4F9B --item-id");
5636
+ if (!options.itemId) exitWithError("\u8BF7\u63D0\u4F9B --item-id");
6155
5637
  await runTaskMutation(`/cso/v1/task/rePublish/${options.itemId}`, null, options, "\u91CD\u65B0\u53D1\u5E03");
6156
5638
  }
6157
5639
  async function runTaskItemRunNow(options) {
6158
- if (!options.itemId) exitWithError3("\u8BF7\u63D0\u4F9B --item-id");
5640
+ if (!options.itemId) exitWithError("\u8BF7\u63D0\u4F9B --item-id");
6159
5641
  await runTaskMutation(`/cso/v1/task/runPublish/${options.itemId}`, null, options, "\u7ACB\u5373\u53D1\u5E03");
6160
5642
  }
6161
5643
  async function runTaskCommentList(options) {
6162
5644
  const config = loadConfig(options.token);
6163
5645
  const mediaType = resolveMediaTypeForApi(options.mediaType);
6164
- const url = `${config.csoBaseUrl}/cso/v1/comment/listByVideoId/2/${mediaType}?${createQueryString3(
5646
+ const url = `${config.csoBaseUrl}/cso/v1/comment/listByVideoId/2/${mediaType}?${createQueryString(
6165
5647
  {
6166
5648
  videoId: encodeURIComponent(options.videoId),
6167
5649
  mediaCustomerId: options.mediaCustomerId
@@ -6180,7 +5662,7 @@ async function runTaskCommentList(options) {
6180
5662
  }
6181
5663
  data = res.data;
6182
5664
  } catch (error) {
6183
- exitWithError3(`\u83B7\u53D6\u8BC4\u8BBA\u5217\u8868\u5931\u8D25\uFF1A${error.message}`);
5665
+ exitWithError(`\u83B7\u53D6\u8BC4\u8BBA\u5217\u8868\u5931\u8D25\uFF1A${error.message}`);
6184
5666
  }
6185
5667
  const list = Array.isArray(data.list) ? data.list : [];
6186
5668
  const total = data.total ?? 0;
@@ -6775,7 +6257,7 @@ async function runRagList(options) {
6775
6257
  }
6776
6258
 
6777
6259
  // src/commands/config.ts
6778
- import * as fs10 from "fs";
6260
+ import * as fs11 from "fs";
6779
6261
  function cmdConfigShow() {
6780
6262
  const shared = readSharedConfig();
6781
6263
  const envApiKey = process.env.SILUZAN_API_KEY;
@@ -6845,398 +6327,384 @@ function cmdConfigClear() {
6845
6327
  `);
6846
6328
  }
6847
6329
 
6848
- // src/index.ts
6849
- process.on("uncaughtException", (err) => {
6850
- console.error(`
6851
- \u274C \u672A\u6355\u83B7\u7684\u5F02\u5E38\uFF1A${err.message}`);
6852
- if (process.argv.includes("--verbose")) console.error(err.stack);
6853
- process.exit(1);
6854
- });
6855
- process.on("unhandledRejection", (reason) => {
6856
- const msg = reason instanceof Error ? reason.message : String(reason);
6857
- console.error(`
6858
- \u274C \u672A\u5904\u7406\u7684\u5F02\u6B65\u9519\u8BEF\uFF1A${msg}`);
6859
- if (process.argv.includes("--verbose") && reason instanceof Error) console.error(reason.stack);
6860
- process.exit(1);
6861
- });
6862
- var program = new Command();
6863
- program.name("siluzan-cso").description("Siluzan \u5E73\u53F0 Skill \u5DE5\u5177\uFF1A\u521D\u59CB\u5316\u3001\u8D26\u53F7\u67E5\u8BE2\u3001\u4E0A\u4F20\u3001\u56FE\u6587/\u89C6\u9891\u53D1\u5E03").version(getCurrentVersion2());
6864
- var configCmd = program.command("config").description("\u67E5\u770B\u6216\u8BBE\u7F6E Siluzan \u8BA4\u8BC1\u914D\u7F6E\uFF08~/.siluzan/config.json\uFF09");
6865
- configCmd.command("show").description("\u5C55\u793A\u5F53\u524D\u5DF2\u4FDD\u5B58\u7684\u914D\u7F6E\uFF08Token \u8131\u654F\u663E\u793A\uFF09").action(() => cmdConfigShow());
6866
- configCmd.command("set").description("\u4FDD\u5B58\u914D\u7F6E\u5230 ~/.siluzan/config.json\uFF0C\u540E\u7EED\u547D\u4EE4\u81EA\u52A8\u8BFB\u53D6").option("--api-key <key>", "API Key\uFF08\u63A8\u8350\uFF0C\u4E0E siluzan-tso \u5171\u7528\uFF0C\u4F18\u5148\u7EA7\u9AD8\u4E8E token\uFF09").option("-t, --token <token>", "\u7528\u6237 Auth Token\uFF08JWT\uFF09").action((opts) => {
6867
- cmdConfigSet({ apiKey: opts.apiKey, token: opts.token });
6868
- });
6869
- configCmd.command("clear").description("\u6E05\u7A7A\u5DF2\u4FDD\u5B58\u7684 Token").action(() => cmdConfigClear());
6870
- program.command("login").description("\u5F15\u5BFC\u5B8C\u6210 Siluzan \u8D26\u53F7\u767B\u5F55\uFF0C\u4FDD\u5B58 API Key \u5230\u672C\u5730").option("--api-key <key>", "\u76F4\u63A5\u4FDD\u5B58 API Key\uFF08\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u6D41\u7A0B\uFF0C\u4E0E siluzan-tso \u5171\u7528\uFF09").addOption(new Option("--token <token>", "\u76F4\u63A5\u4FDD\u5B58 JWT Token").hideHelp()).action(async (opts) => {
6871
- await runLogin({ apiKey: opts.apiKey, token: opts.token });
6872
- });
6873
- program.command("update").description("\u68C0\u67E5\u5E76\u66F4\u65B0 siluzan-cso-cli \u81F3\u6700\u65B0\u7248\u672C\uFF0C\u540C\u6B65\u5237\u65B0\u6240\u6709\u5DF2\u5B89\u88C5\u7684 skill \u6587\u4EF6").option("--force", "\u8DF3\u8FC7\u7248\u672C\u6BD4\u8F83\uFF0C\u5F3A\u5236\u91CD\u65B0\u5B89\u88C5\u5E76\u5237\u65B0 skill \u6587\u4EF6", false).option("--skip-init", "\u4EC5\u66F4\u65B0 CLI\uFF0C\u4E0D\u91CD\u65B0\u521D\u59CB\u5316 skill \u6587\u4EF6", false).action(async (opts) => {
6874
- await runUpdate({ force: opts.force, skipInit: opts.skipInit });
6875
- });
6876
- program.command("init").description(
6877
- "\u5C06 Skill \u6587\u4EF6\u5199\u5165 AI \u52A9\u624B\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5199\u5165\u6240\u6709\u5E73\u53F0\u7684\u9879\u76EE\u7EA7\u76EE\u5F55\uFF0C--global \u5199\u5165\u5168\u5C40\u76EE\u5F55\uFF09"
6878
- ).option(
6879
- "-a, --ai <targets>",
6880
- "\u76EE\u6807\u5E73\u53F0\uFF0C\u9017\u53F7\u5206\u9694\uFF1Acursor,claude,agents,windsurf,gemini,codex,opencode,kilo,openclaw,workbuddy,all",
6881
- "all"
6882
- ).option(
6883
- "-d, --dir <path>",
6884
- "\u5C06 Skill \u6587\u4EF6\u76F4\u63A5\u5199\u5165\u6307\u5B9A\u76EE\u5F55\uFF08\u7EDD\u5BF9\u6216\u76F8\u5BF9\u8DEF\u5F84\uFF09\uFF0C\u4E0E --ai/--global \u4E92\u65A5\uFF0C\u4F18\u5148\u7EA7\u66F4\u9AD8"
6885
- ).option("-g, --global", "\u5199\u5165\u6240\u6709\u5E73\u53F0\u7684\u5168\u5C40 skill \u76EE\u5F55\uFF08~/.xxx/skills/\uFF09", false).option("-f, --force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684 Skill \u6587\u4EF6", false).action(async (opts) => {
6886
- await runInit({
6887
- cwd: process.cwd(),
6888
- aiTargets: opts.ai,
6889
- dir: opts.dir,
6890
- global: Boolean(opts.global),
6891
- force: Boolean(opts.force),
6892
- apiBaseUrl: DEFAULT_API_BASE
6330
+ // src/commands/_register.ts
6331
+ function registerCsoCommands(program2) {
6332
+ const configCmd = program2.command("config").description("\u67E5\u770B\u6216\u8BBE\u7F6E Siluzan \u8BA4\u8BC1\u914D\u7F6E\uFF08~/.siluzan/config.json\uFF09");
6333
+ configCmd.command("show").description("\u5C55\u793A\u5F53\u524D\u5DF2\u4FDD\u5B58\u7684\u914D\u7F6E\uFF08Token \u8131\u654F\u663E\u793A\uFF09").action(() => cmdConfigShow());
6334
+ configCmd.command("set").description("\u4FDD\u5B58\u914D\u7F6E\u5230 ~/.siluzan/config.json\uFF0C\u540E\u7EED\u547D\u4EE4\u81EA\u52A8\u8BFB\u53D6").option("--api-key <key>", "API Key\uFF08\u63A8\u8350\uFF0C\u4E0E siluzan-tso \u5171\u7528\uFF0C\u4F18\u5148\u7EA7\u9AD8\u4E8E token\uFF09").option("-t, --token <token>", "\u7528\u6237 Auth Token\uFF08JWT\uFF09").action((opts) => {
6335
+ cmdConfigSet({ apiKey: opts.apiKey, token: opts.token });
6893
6336
  });
6894
- });
6895
- program.command("authorize").description(
6896
- "\u53D1\u8D77\u5A92\u4F53\u5E73\u53F0 OAuth \u6388\u6743\uFF08YouTube/TikTokBusinessAccount/Instagram/Facebook/LinkedIn/Twitter \u7B49\uFF09\uFF0C\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u6388\u6743\u540E\u8DF3\u56DE\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u7BA1\u7406\u9875"
6897
- ).requiredOption(
6898
- "--media-type <type>",
6899
- "\u5A92\u4F53\u5E73\u53F0\u7C7B\u578B\uFF0C\u5982 YouTube / TikTokBusinessAccount / Instagram / Facebook / LinkedIn / Twitter"
6900
- ).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6901
- await runAuthorize(opts);
6902
- });
6903
- program.command("list-accounts").description(
6904
- "\u5217\u51FA\u5A92\u4F53\u8D26\u53F7\u5217\u8868\uFF0C\u9ED8\u8BA4\u5C55\u793A\u7C89\u4E1D\u6570/\u4F5C\u54C1\u6570/\u64AD\u653E\u6570\u7B49\u6570\u636E\u603B\u89C8\uFF1B\u652F\u6301\u5206\u9875\u3001\u5E73\u53F0/\u540D\u79F0/\u72B6\u6001/\u8D1F\u8D23\u4EBA\u8FC7\u6EE4"
6905
- ).option("--name <name>", "\u6309\u8D26\u53F7\u540D\u79F0\u6A21\u7CCA\u641C\u7D22").option("--media-type <type>", "\u6309\u5E73\u53F0\u7C7B\u578B\u8FC7\u6EE4\uFF08\u5982 \u6296\u97F3\u3001YouTube\u3001TikTok \u7B49\uFF09").option(
6906
- "--state <state>",
6907
- "\u6309\u72B6\u6001\u8FC7\u6EE4\uFF1Aall\uFF08\u5168\u90E8\uFF09| normal\uFF08\u6B63\u5E38\uFF09| abnormal\uFF08\u5F02\u5E38/\u8FC7\u671F\uFF09\uFF0C\u9ED8\u8BA4 all",
6908
- "all"
6909
- ).option(
6910
- "--owner <owner>",
6911
- "\u6309\u8D1F\u8D23\u4EBA\u8FC7\u6EE4\uFF08\u4F20\u5165\u7528\u6237 ID\uFF0C\u53EF\u4ECE --json \u8FD4\u56DE\u7684 ownerInfo[].id \u5B57\u6BB5\u83B7\u53D6\uFF09"
6912
- ).option("--page <n>", "\u9875\u7801\uFF08\u9ED8\u8BA4 1\uFF09", "1").option("--page-size <n>", "\u6BCF\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 20\uFF09", "20").option("--json", "\u4EE5 JSON \u8F93\u51FA\u8D26\u53F7\u5217\u8868\uFF08\u542B\u603B\u89C8\u6570\u636E\uFF0C\u7528\u4E8E\u811A\u672C\u6216\u914D\u7F6E\u6587\u4EF6\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", false).option("--verbose", "\u663E\u793A\u5B8C\u6574\u4EE4\u724C\u6807\u8BC6\uFF08\u9ED8\u8BA4\u8131\u654F\uFF09", false).action(
6913
- async (opts) => {
6914
- const state = opts.state;
6915
- await runListAccounts({
6916
- token: opts.token,
6917
- name: opts.name,
6918
- mediaType: opts.mediaType,
6919
- state: state === "all" ? void 0 : state,
6920
- owner: opts.owner,
6921
- page: opts.page ? parseInt(opts.page, 10) : void 0,
6922
- pageSize: opts.pageSize ? parseInt(opts.pageSize, 10) : void 0,
6923
- json: opts.json,
6924
- unicode: opts.unicode,
6925
- verbose: opts.verbose
6926
- });
6927
- }
6928
- );
6929
- var accountGroupCmd = program.command("account-group").description("\u8D26\u53F7\u5206\u7EC4\u7BA1\u7406\uFF1A\u67E5\u8BE2\u3001\u65B0\u5EFA\u3001\u7F16\u8F91\u3001\u5220\u9664\u5206\u7EC4");
6930
- accountGroupCmd.command("list").description("\u67E5\u8BE2\u8D26\u53F7\u5206\u7EC4\u5217\u8868").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u5B8C\u6574\u5206\u7EC4\u6570\u636E\uFF08\u542B mediaAccountInfos\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6931
- async (opts) => {
6932
- await runAccountGroupList({
6933
- token: opts.token,
6934
- json: opts.json,
6935
- unicode: opts.unicode,
6936
- verbose: opts.verbose
6937
- });
6938
- }
6939
- );
6940
- accountGroupCmd.command("create").description("\u65B0\u5EFA\u8D26\u53F7\u5206\u7EC4").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").requiredOption("--name <name>", "\u5206\u7EC4\u540D\u79F0").option(
6941
- "--accounts <ids>",
6942
- "\u7EC4\u5185\u8D26\u53F7\u7684 mediaCustomerId\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u53EF\u4ECE list-accounts --json \u83B7\u53D6\uFF09"
6943
- ).option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u7ED3\u679C", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6944
- async (opts) => {
6945
- await runAccountGroupCreate({
6946
- token: opts.token,
6947
- name: opts.name,
6948
- accounts: opts.accounts,
6949
- json: opts.json,
6950
- verbose: opts.verbose
6951
- });
6952
- }
6953
- );
6954
- accountGroupCmd.command("update").description("\u7F16\u8F91\u5DF2\u6709\u8D26\u53F7\u5206\u7EC4\uFF08\u66F4\u65B0\u540D\u79F0\u6216\u8D26\u53F7\u5217\u8868\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").requiredOption("--id <groupId>", "\u5206\u7EC4 ID\uFF08\u6765\u81EA account-group list \u7684 id \u5B57\u6BB5\uFF09").requiredOption("--name <name>", "\u65B0\u5206\u7EC4\u540D\u79F0").option("--accounts <ids>", "\u7EC4\u5185\u8D26\u53F7\u7684 mediaCustomerId\uFF0C\u9017\u53F7\u5206\u9694\uFF1B\u4E0D\u4F20\u5219\u6E05\u7A7A\u5206\u7EC4\u5185\u8D26\u53F7").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u7ED3\u679C", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6955
- async (opts) => {
6956
- await runAccountGroupUpdate({
6957
- token: opts.token,
6958
- id: opts.id,
6959
- name: opts.name,
6960
- accounts: opts.accounts,
6961
- json: opts.json,
6962
- verbose: opts.verbose
6963
- });
6964
- }
6965
- );
6966
- accountGroupCmd.command("delete").description("\u5220\u9664\u8D26\u53F7\u5206\u7EC4\uFF08\u4E0D\u53EF\u5220\u9664\u300C\u672A\u5206\u7EC4\u300D\u865A\u62DF\u5206\u7EC4\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").requiredOption("--id <groupId>", "\u5206\u7EC4 ID\uFF08\u6765\u81EA account-group list \u7684 id \u5B57\u6BB5\uFF09").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u7ED3\u679C", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6967
- await runAccountGroupDelete({
6968
- token: opts.token,
6969
- id: opts.id,
6970
- json: opts.json,
6971
- verbose: opts.verbose
6337
+ configCmd.command("clear").description("\u6E05\u7A7A\u5DF2\u4FDD\u5B58\u7684 Token").action(() => cmdConfigClear());
6338
+ program2.command("login").description("\u5F15\u5BFC\u5B8C\u6210 Siluzan \u8D26\u53F7\u767B\u5F55\uFF0C\u4FDD\u5B58 API Key \u5230\u672C\u5730").option("--api-key <key>", "\u76F4\u63A5\u4FDD\u5B58 API Key\uFF08\u8DF3\u8FC7\u4EA4\u4E92\u5F0F\u6D41\u7A0B\uFF0C\u4E0E siluzan-tso \u5171\u7528\uFF09").addOption(new Option("--token <token>", "\u76F4\u63A5\u4FDD\u5B58 JWT Token").hideHelp()).action(async (opts) => {
6339
+ await runLogin({ apiKey: opts.apiKey, token: opts.token });
6972
6340
  });
6973
- });
6974
- accountGroupCmd.command("add-accounts").description("\u5411\u5206\u7EC4\u8FFD\u52A0\u8D26\u53F7\uFF08\u81EA\u52A8\u5408\u5E76\uFF0C\u4E0D\u5F71\u54CD\u5DF2\u6709\u8D26\u53F7\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").requiredOption("--id <groupId>", "\u5206\u7EC4 ID\uFF08\u6765\u81EA account-group list \u7684 id \u5B57\u6BB5\uFF09").requiredOption("--accounts <ids>", "\u8981\u6DFB\u52A0\u7684 mediaCustomerId\uFF0C\u9017\u53F7\u5206\u9694").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u7ED3\u679C", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6975
- async (opts) => {
6976
- await runAccountGroupAddAccounts({
6977
- token: opts.token,
6978
- id: opts.id,
6979
- accounts: opts.accounts,
6980
- json: opts.json,
6981
- verbose: opts.verbose
6982
- });
6983
- }
6984
- );
6985
- accountGroupCmd.command("remove-accounts").description("\u4ECE\u5206\u7EC4\u79FB\u9664\u6307\u5B9A\u8D26\u53F7\uFF08\u4E0D\u5F71\u54CD\u5176\u4ED6\u5DF2\u6709\u8D26\u53F7\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").requiredOption("--id <groupId>", "\u5206\u7EC4 ID\uFF08\u6765\u81EA account-group list \u7684 id \u5B57\u6BB5\uFF09").requiredOption("--accounts <ids>", "\u8981\u79FB\u9664\u7684 mediaCustomerId\uFF0C\u9017\u53F7\u5206\u9694").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u7ED3\u679C", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6986
- async (opts) => {
6987
- await runAccountGroupRemoveAccounts({
6988
- token: opts.token,
6989
- id: opts.id,
6990
- accounts: opts.accounts,
6991
- json: opts.json,
6992
- verbose: opts.verbose
6341
+ program2.command("update").description("\u68C0\u67E5\u5E76\u66F4\u65B0 siluzan-cso-cli \u81F3\u6700\u65B0\u7248\u672C\uFF0C\u540C\u6B65\u5237\u65B0\u6240\u6709\u5DF2\u5B89\u88C5\u7684 skill \u6587\u4EF6").option("--force", "\u8DF3\u8FC7\u7248\u672C\u6BD4\u8F83\uFF0C\u5F3A\u5236\u91CD\u65B0\u5B89\u88C5\u5E76\u5237\u65B0 skill \u6587\u4EF6", false).option("--skip-init", "\u4EC5\u66F4\u65B0 CLI\uFF0C\u4E0D\u91CD\u65B0\u521D\u59CB\u5316 skill \u6587\u4EF6", false).action(async (opts) => {
6342
+ await runUpdate({ force: opts.force, skipInit: opts.skipInit });
6343
+ });
6344
+ program2.command("init").description(
6345
+ "\u5C06 Skill \u6587\u4EF6\u5199\u5165 AI \u52A9\u624B\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5199\u5165\u6240\u6709\u5E73\u53F0\u7684\u9879\u76EE\u7EA7\u76EE\u5F55\uFF0C--global \u5199\u5165\u5168\u5C40\u76EE\u5F55\uFF09"
6346
+ ).option(
6347
+ "-a, --ai <targets>",
6348
+ "\u76EE\u6807\u5E73\u53F0\uFF0C\u9017\u53F7\u5206\u9694\uFF1Acursor,claude,agents,windsurf,gemini,codex,opencode,kilo,openclaw,workbuddy,all",
6349
+ "all"
6350
+ ).option(
6351
+ "-d, --dir <path>",
6352
+ "\u5C06 Skill \u6587\u4EF6\u76F4\u63A5\u5199\u5165\u6307\u5B9A\u76EE\u5F55\uFF08\u7EDD\u5BF9\u6216\u76F8\u5BF9\u8DEF\u5F84\uFF09\uFF0C\u4E0E --ai/--global \u4E92\u65A5\uFF0C\u4F18\u5148\u7EA7\u66F4\u9AD8"
6353
+ ).option("-g, --global", "\u5199\u5165\u6240\u6709\u5E73\u53F0\u7684\u5168\u5C40 skill \u76EE\u5F55\uFF08~/.xxx/skills/\uFF09", false).option("-f, --force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684 Skill \u6587\u4EF6", false).action(async (opts) => {
6354
+ await runInit({
6355
+ cwd: process.cwd(),
6356
+ aiTargets: opts.ai,
6357
+ dir: opts.dir,
6358
+ global: Boolean(opts.global),
6359
+ force: Boolean(opts.force),
6360
+ apiBaseUrl: DEFAULT_API_BASE
6993
6361
  });
6994
- }
6995
- );
6996
- var personaCmd = program.command("persona").description("CSO \u4EBA\u8BBE\uFF1A\u67E5\u8BE2\u5E73\u53F0\u4EBA\u8BBE\u4E0E styleGuide\uFF08Markdown\uFF09");
6997
- personaCmd.command("list").description("\u62C9\u53D6\u4EBA\u8BBE\u5217\u8868\uFF08POST /cso/v1/platformdata/GetPersonas\uFF0C\u4E0E Web \u7AEF\u4E00\u81F4\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--id <id>", "\u53EA\u663E\u793A\u6307\u5B9A\u4EBA\u8BBE id").option("--name <text>", "\u6309\u4EBA\u8BBE\u540D\u79F0\u5B50\u4E32\u8FC7\u6EE4").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON\uFF08\u542B styleGuide\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6998
- async (opts) => {
6999
- await runPersonaList({
6362
+ });
6363
+ program2.command("authorize").description(
6364
+ "\u53D1\u8D77\u5A92\u4F53\u5E73\u53F0 OAuth \u6388\u6743\uFF08YouTube/TikTokBusinessAccount/Instagram/Facebook/LinkedIn/Twitter \u7B49\uFF09\uFF0C\u5728\u6D4F\u89C8\u5668\u4E2D\u5B8C\u6210\u6388\u6743\u540E\u8DF3\u56DE\u4E1D\u8DEF\u8D5E\u8D26\u53F7\u7BA1\u7406\u9875"
6365
+ ).requiredOption(
6366
+ "--media-type <type>",
6367
+ "\u5A92\u4F53\u5E73\u53F0\u7C7B\u578B\uFF0C\u5982 YouTube / TikTokBusinessAccount / Instagram / Facebook / LinkedIn / Twitter"
6368
+ ).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6369
+ await runAuthorize(opts);
6370
+ });
6371
+ program2.command("list-accounts").description(
6372
+ "\u5217\u51FA\u5A92\u4F53\u8D26\u53F7\u5217\u8868\uFF0C\u9ED8\u8BA4\u5C55\u793A\u7C89\u4E1D\u6570/\u4F5C\u54C1\u6570/\u64AD\u653E\u6570\u7B49\u6570\u636E\u603B\u89C8\uFF1B\u652F\u6301\u5206\u9875\u3001\u5E73\u53F0/\u540D\u79F0/\u72B6\u6001/\u8D1F\u8D23\u4EBA\u8FC7\u6EE4"
6373
+ ).option("--name <name>", "\u6309\u8D26\u53F7\u540D\u79F0\u6A21\u7CCA\u641C\u7D22").option("--media-type <type>", "\u6309\u5E73\u53F0\u7C7B\u578B\u8FC7\u6EE4\uFF08\u5982 \u6296\u97F3\u3001YouTube\u3001TikTok \u7B49\uFF09").option(
6374
+ "--state <state>",
6375
+ "\u6309\u72B6\u6001\u8FC7\u6EE4\uFF1Aall\uFF08\u5168\u90E8\uFF09| normal\uFF08\u6B63\u5E38\uFF09| abnormal\uFF08\u5F02\u5E38/\u8FC7\u671F\uFF09\uFF0C\u9ED8\u8BA4 all",
6376
+ "all"
6377
+ ).option(
6378
+ "--owner <owner>",
6379
+ "\u6309\u8D1F\u8D23\u4EBA\u8FC7\u6EE4\uFF08\u4F20\u5165\u7528\u6237 ID\uFF0C\u53EF\u4ECE --json \u8FD4\u56DE\u7684 ownerInfo[].id \u5B57\u6BB5\u83B7\u53D6\uFF09"
6380
+ ).option("--page <n>", "\u9875\u7801\uFF08\u9ED8\u8BA4 1\uFF09", "1").option("--page-size <n>", "\u6BCF\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 20\uFF09", "20").option("--json", "\u4EE5 JSON \u8F93\u51FA\u8D26\u53F7\u5217\u8868\uFF08\u542B\u603B\u89C8\u6570\u636E\uFF0C\u7528\u4E8E\u811A\u672C\u6216\u914D\u7F6E\u6587\u4EF6\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", false).option("--verbose", "\u663E\u793A\u5B8C\u6574\u4EE4\u724C\u6807\u8BC6\uFF08\u9ED8\u8BA4\u8131\u654F\uFF09", false).action(
6381
+ async (opts) => {
6382
+ const state = opts.state;
6383
+ await runListAccounts({
6384
+ token: opts.token,
6385
+ name: opts.name,
6386
+ mediaType: opts.mediaType,
6387
+ state: state === "all" ? void 0 : state,
6388
+ owner: opts.owner,
6389
+ page: opts.page ? parseInt(opts.page, 10) : void 0,
6390
+ pageSize: opts.pageSize ? parseInt(opts.pageSize, 10) : void 0,
6391
+ json: opts.json,
6392
+ unicode: opts.unicode,
6393
+ verbose: opts.verbose
6394
+ });
6395
+ }
6396
+ );
6397
+ const accountGroupCmd = program2.command("account-group").description("\u8D26\u53F7\u5206\u7EC4\u7BA1\u7406\uFF1A\u67E5\u8BE2\u3001\u65B0\u5EFA\u3001\u7F16\u8F91\u3001\u5220\u9664\u5206\u7EC4");
6398
+ accountGroupCmd.command("list").description("\u67E5\u8BE2\u8D26\u53F7\u5206\u7EC4\u5217\u8868").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u5B8C\u6574\u5206\u7EC4\u6570\u636E\uFF08\u542B mediaAccountInfos\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6399
+ async (opts) => {
6400
+ await runAccountGroupList({
6401
+ token: opts.token,
6402
+ json: opts.json,
6403
+ unicode: opts.unicode,
6404
+ verbose: opts.verbose
6405
+ });
6406
+ }
6407
+ );
6408
+ accountGroupCmd.command("create").description("\u65B0\u5EFA\u8D26\u53F7\u5206\u7EC4").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").requiredOption("--name <name>", "\u5206\u7EC4\u540D\u79F0").option(
6409
+ "--accounts <ids>",
6410
+ "\u7EC4\u5185\u8D26\u53F7\u7684 mediaCustomerId\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u53EF\u4ECE list-accounts --json \u83B7\u53D6\uFF09"
6411
+ ).option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u7ED3\u679C", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6412
+ async (opts) => {
6413
+ await runAccountGroupCreate({
6414
+ token: opts.token,
6415
+ name: opts.name,
6416
+ accounts: opts.accounts,
6417
+ json: opts.json,
6418
+ verbose: opts.verbose
6419
+ });
6420
+ }
6421
+ );
6422
+ accountGroupCmd.command("update").description("\u7F16\u8F91\u5DF2\u6709\u8D26\u53F7\u5206\u7EC4\uFF08\u66F4\u65B0\u540D\u79F0\u6216\u8D26\u53F7\u5217\u8868\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").requiredOption("--id <groupId>", "\u5206\u7EC4 ID\uFF08\u6765\u81EA account-group list \u7684 id \u5B57\u6BB5\uFF09").requiredOption("--name <name>", "\u65B0\u5206\u7EC4\u540D\u79F0").option("--accounts <ids>", "\u7EC4\u5185\u8D26\u53F7\u7684 mediaCustomerId\uFF0C\u9017\u53F7\u5206\u9694\uFF1B\u4E0D\u4F20\u5219\u6E05\u7A7A\u5206\u7EC4\u5185\u8D26\u53F7").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u7ED3\u679C", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6423
+ async (opts) => {
6424
+ await runAccountGroupUpdate({
6425
+ token: opts.token,
6426
+ id: opts.id,
6427
+ name: opts.name,
6428
+ accounts: opts.accounts,
6429
+ json: opts.json,
6430
+ verbose: opts.verbose
6431
+ });
6432
+ }
6433
+ );
6434
+ accountGroupCmd.command("delete").description("\u5220\u9664\u8D26\u53F7\u5206\u7EC4\uFF08\u4E0D\u53EF\u5220\u9664\u300C\u672A\u5206\u7EC4\u300D\u865A\u62DF\u5206\u7EC4\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").requiredOption("--id <groupId>", "\u5206\u7EC4 ID\uFF08\u6765\u81EA account-group list \u7684 id \u5B57\u6BB5\uFF09").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u7ED3\u679C", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6435
+ await runAccountGroupDelete({
7000
6436
  token: opts.token,
7001
6437
  id: opts.id,
7002
- name: opts.name,
7003
- json: opts.json,
7004
- unicode: opts.unicode,
7005
- verbose: opts.verbose
7006
- });
7007
- }
7008
- );
7009
- var ragCmd = program.command("rag").description(
7010
- "RAG \u77E5\u8BC6\u5E93\u68C0\u7D22\uFF08\u4EC5\u5199\u7A3F/\u4E09\u5E93\uFF1B\u9ED8\u8BA4 belongToId=account/me \u7684 companyId\uFF0C\u9ED8\u8BA4 tags=\u4E09\u5E93\uFF09"
7011
- );
7012
- ragCmd.command("list").description(
7013
- "\u5217\u51FA\u5F53\u524D\u4F01\u4E1A\u4E0B\u6240\u6709\u77E5\u8BC6\u5E93\u6587\u4EF6\u5939\uFF08GET cutapi/v1/material/querylist\uFF09\uFF0C\u4F9B AI \u9009\u62E9\u68C0\u7D22\u8303\u56F4"
7014
- ).option("--belong-to-id <id>", "\u4F01\u4E1A ID\uFF1B\u4E0D\u4F20\u5219\u4ECE GET /query/account/me \u53D6 companyId").option("--rag-only", "\u4EC5\u663E\u793A\u5DF2\u5EFA RAG \u5411\u91CF\u7D22\u5F15\uFF08ragStatus=true\uFF09\u7684\u77E5\u8BC6\u5E93", false).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7015
- async (opts) => {
7016
- await runRagList({
7017
- belongToId: opts.belongToId,
7018
- ragOnly: opts.ragOnly,
7019
- token: opts.token,
7020
- json: opts.json,
7021
- verbose: opts.verbose
7022
- });
7023
- }
7024
- );
7025
- ragCmd.command("query").description("\u6309\u5173\u952E\u8BCD\u68C0\u7D22\u5DF2\u7EB3\u5165\u5411\u91CF\u7684\u77E5\u8BC6\u7247\u6BB5\uFF08GET cutapi/v1/material/queryknowledges\uFF09").requiredOption("-q, --query <text>", "\u68C0\u7D22\u5173\u952E\u8BCD\u6216\u95EE\u53E5").option("--belong-to-id <id>", "\u4F01\u4E1A ID\uFF1B\u4E0D\u4F20\u5219\u4ECE GET /query/account/me \u53D6 companyId").option("--source-id <ids>", "\u7D20\u6750\u6587\u4EF6 ID\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u53EF\u9009\uFF0Cqueryknowledges \u7684 sourceid\uFF09").option("--folder-id <ids>", "\u6587\u4EF6\u5939 ID\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u53EF\u9009\uFF0Ccomid\uFF09").option("--top-k <n>", "\u8FD4\u56DE\u6761\u6570\uFF0C3\u201330\uFF08\u9ED8\u8BA4 7\uFF09", "7").option("--belong-to <n>", "\u5F52\u5C5E\u7C7B\u578B\uFF08\u9ED8\u8BA4 0\uFF0C\u4F01\u4E1A\uFF09", "0").option("--tags <tags>", "\u6807\u7B7E\u8FC7\u6EE4\uFF0C\u9017\u53F7\u5206\u9694\uFF1B\u4E0D\u4F20\u5219\u4E0D\u8FC7\u6EE4\u6807\u7B7E\uFF08\u5168\u91CF\u68C0\u7D22\uFF09").option("--category <categories>", "\u5206\u7C7B\u8FC7\u6EE4\uFF0C\u9017\u53F7\u5206\u9694").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7026
- async (opts) => {
7027
- await runRagQuery({
7028
- query: opts.query,
7029
- belongToId: opts.belongToId,
7030
- sourceId: opts.sourceId,
7031
- folderId: opts.folderId,
7032
- topK: opts.topK ? parseInt(opts.topK, 10) : void 0,
7033
- belongTo: opts.belongTo !== void 0 ? parseInt(opts.belongTo, 10) : void 0,
7034
- tags: opts.tags,
7035
- category: opts.category,
7036
- token: opts.token,
7037
- json: opts.json,
7038
- unicode: opts.unicode,
7039
- verbose: opts.verbose
7040
- });
7041
- }
7042
- );
7043
- program.command("list-members").description("\u5217\u51FA\u516C\u53F8\u6240\u6709\u6210\u5458\uFF0C\u663E\u793A\u7528\u6237ID\u4F9B list-accounts --owner \u4F7F\u7528").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("-q, --query <keyword>", "\u6309\u59D3\u540D\u6216\u624B\u673A\u53F7\u6A21\u7CCA\u641C\u7D22").option("--json", "\u4EE5 JSON \u8F93\u51FA\u6210\u5458\u5217\u8868", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", false).option("--verbose", "\u8F93\u51FA\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7044
- async (opts) => {
7045
- await runListMembers({
7046
- token: opts.token,
7047
- query: opts.query,
7048
6438
  json: opts.json,
7049
- unicode: opts.unicode,
7050
- verbose: opts.verbose
7051
- });
7052
- }
7053
- );
7054
- program.command("upload").description("\u4E0A\u4F20\u672C\u5730\u89C6\u9891\u6216\u56FE\u7247\u5230 Siluzan \u7D20\u6750\u5E93\uFF0C\u8F93\u51FA\u53EF\u76F4\u63A5\u586B\u5165 publish-config.json \u7684\u5B57\u6BB5").requiredOption("-f, --file <path>", "\u672C\u5730\u6587\u4EF6\u8DEF\u5F84").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--kind <video|image>", "\u624B\u52A8\u6307\u5B9A\u6587\u4EF6\u7C7B\u578B\uFF08\u9ED8\u8BA4\u6309\u6269\u5C55\u540D\u81EA\u52A8\u5224\u65AD\uFF09").option("--cover <path>", "\u5C01\u9762\u56FE\u7247\u8DEF\u5F84\uFF08\u4E0A\u4F20\u89C6\u9891\u65F6\u5FC5\u987B\u63D0\u4F9B\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F\u53CA\u5B8C\u6574 URL\uFF08\u9ED8\u8BA4\u9690\u85CF\u542B\u7B7E\u540D URL\uFF09", false).action(
7055
- async (opts) => {
7056
- await runUpload({
7057
- file: opts.file,
7058
- token: opts.token,
7059
- kind: opts.kind,
7060
- cover: opts.cover,
7061
6439
  verbose: opts.verbose
7062
6440
  });
7063
- }
7064
- );
7065
- program.command("extract-cover").description(
7066
- "\u4ECE\u89C6\u9891\u6587\u4EF6\u622A\u53D6\u5C01\u9762\u5E27\uFF0C\u6309\u5E73\u53F0\u89C4\u683C\uFF08YouTube/TikTok/Twitter \u7B49\uFF09\u88C1\u526A\u7F29\u653E\uFF0C\u53EF\u9009\u81EA\u52A8\u4E0A\u4F20"
7067
- ).requiredOption("-f, --file <path>", "\u89C6\u9891\u6587\u4EF6\u8DEF\u5F84\uFF08MP4/MOV/MKV \u7B49\uFF09").option(
7068
- "-t, --time <seconds...>",
7069
- "\u622A\u5E27\u65F6\u95F4\u70B9\uFF08\u79D2\uFF0C\u53EF\u591A\u4E2A\uFF09\uFF0C\u5982 -t 0 3 10 \u622A\u53D6\u7B2C 0\u30013\u300110 \u79D2\u5E27\uFF08\u9ED8\u8BA4: 0\uFF09"
7070
- ).option(
7071
- "-p, --platform <platform>",
7072
- "\u76EE\u6807\u5E73\u53F0\uFF08\u9ED8\u8BA4 youtube\uFF09\u3002\u8FD0\u884C --list-platforms \u67E5\u770B\u5168\u90E8\u652F\u6301\u5E73\u53F0",
7073
- "youtube"
7074
- ).option("-o, --output <path>", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84\uFF08\u591A\u5E27\u65F6\u4F5C\u4E3A\u6587\u4EF6\u540D\u524D\u7F00\uFF1B\u9ED8\u8BA4\u4FDD\u5B58\u5728\u89C6\u9891\u540C\u76EE\u5F55\uFF09").option("--upload", "\u622A\u53D6\u540E\u81EA\u52A8\u4E0A\u4F20\u5C01\u9762\u5230\u7D20\u6750\u5E93\uFF0C\u5E76\u8F93\u51FA cover JSON \u7247\u6BB5", false).option("--list-platforms", "\u5217\u51FA\u6240\u6709\u652F\u6301\u7684\u5E73\u53F0\u5C01\u9762\u89C4\u683C", false).option("--token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").action(
7075
- async (opts) => {
7076
- if (opts.listPlatforms) {
7077
- const { PLATFORM_COVER_SPECS } = await import("./extract-cover-RZ5OIHTV.js");
7078
- const keys = Object.keys(PLATFORM_COVER_SPECS);
7079
- console.log("\n\u5404\u5E73\u53F0\u89C6\u9891\u5C01\u9762\u89C4\u683C\uFF1A\n");
7080
- const maxKeyLen = Math.max(...keys.map((k) => k.length));
7081
- const maxNameLen = Math.max(...keys.map((k) => PLATFORM_COVER_SPECS[k].displayName.length));
7082
- console.log(
7083
- ` ${"\u5E73\u53F0 ID".padEnd(maxKeyLen)} ${"\u5E73\u53F0\u540D\u79F0".padEnd(maxNameLen)} ${"\u5C3A\u5BF8".padEnd(12)} ${"\u6BD4\u4F8B".padEnd(6)} \u8BF4\u660E`
7084
- );
7085
- console.log(" " + "-".repeat(maxKeyLen + maxNameLen + 55));
7086
- for (const key of keys) {
7087
- const spec = PLATFORM_COVER_SPECS[key];
7088
- const size = `${spec.width}\xD7${spec.height}`;
6441
+ });
6442
+ accountGroupCmd.command("add-accounts").description("\u5411\u5206\u7EC4\u8FFD\u52A0\u8D26\u53F7\uFF08\u81EA\u52A8\u5408\u5E76\uFF0C\u4E0D\u5F71\u54CD\u5DF2\u6709\u8D26\u53F7\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").requiredOption("--id <groupId>", "\u5206\u7EC4 ID\uFF08\u6765\u81EA account-group list \u7684 id \u5B57\u6BB5\uFF09").requiredOption("--accounts <ids>", "\u8981\u6DFB\u52A0\u7684 mediaCustomerId\uFF0C\u9017\u53F7\u5206\u9694").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u7ED3\u679C", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6443
+ async (opts) => {
6444
+ await runAccountGroupAddAccounts({
6445
+ token: opts.token,
6446
+ id: opts.id,
6447
+ accounts: opts.accounts,
6448
+ json: opts.json,
6449
+ verbose: opts.verbose
6450
+ });
6451
+ }
6452
+ );
6453
+ accountGroupCmd.command("remove-accounts").description("\u4ECE\u5206\u7EC4\u79FB\u9664\u6307\u5B9A\u8D26\u53F7\uFF08\u4E0D\u5F71\u54CD\u5176\u4ED6\u5DF2\u6709\u8D26\u53F7\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").requiredOption("--id <groupId>", "\u5206\u7EC4 ID\uFF08\u6765\u81EA account-group list \u7684 id \u5B57\u6BB5\uFF09").requiredOption("--accounts <ids>", "\u8981\u79FB\u9664\u7684 mediaCustomerId\uFF0C\u9017\u53F7\u5206\u9694").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA\u7ED3\u679C", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6454
+ async (opts) => {
6455
+ await runAccountGroupRemoveAccounts({
6456
+ token: opts.token,
6457
+ id: opts.id,
6458
+ accounts: opts.accounts,
6459
+ json: opts.json,
6460
+ verbose: opts.verbose
6461
+ });
6462
+ }
6463
+ );
6464
+ const personaCmd = program2.command("persona").description("CSO \u4EBA\u8BBE\uFF1A\u67E5\u8BE2\u5E73\u53F0\u4EBA\u8BBE\u4E0E styleGuide\uFF08Markdown\uFF09");
6465
+ personaCmd.command("list").description("\u62C9\u53D6\u4EBA\u8BBE\u5217\u8868\uFF08POST /cso/v1/platformdata/GetPersonas\uFF0C\u4E0E Web \u7AEF\u4E00\u81F4\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--id <id>", "\u53EA\u663E\u793A\u6307\u5B9A\u4EBA\u8BBE id").option("--name <text>", "\u6309\u4EBA\u8BBE\u540D\u79F0\u5B50\u4E32\u8FC7\u6EE4").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON\uFF08\u542B styleGuide\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6466
+ async (opts) => {
6467
+ await runPersonaList({
6468
+ token: opts.token,
6469
+ id: opts.id,
6470
+ name: opts.name,
6471
+ json: opts.json,
6472
+ unicode: opts.unicode,
6473
+ verbose: opts.verbose
6474
+ });
6475
+ }
6476
+ );
6477
+ const ragCmd = program2.command("rag").description(
6478
+ "RAG \u77E5\u8BC6\u5E93\u68C0\u7D22\uFF08\u4EC5\u5199\u7A3F/\u4E09\u5E93\uFF1B\u9ED8\u8BA4 belongToId=account/me \u7684 companyId\uFF0C\u9ED8\u8BA4 tags=\u4E09\u5E93\uFF09"
6479
+ );
6480
+ ragCmd.command("list").description(
6481
+ "\u5217\u51FA\u5F53\u524D\u4F01\u4E1A\u4E0B\u6240\u6709\u77E5\u8BC6\u5E93\u6587\u4EF6\u5939\uFF08GET cutapi/v1/material/querylist\uFF09\uFF0C\u4F9B AI \u9009\u62E9\u68C0\u7D22\u8303\u56F4"
6482
+ ).option("--belong-to-id <id>", "\u4F01\u4E1A ID\uFF1B\u4E0D\u4F20\u5219\u4ECE GET /query/account/me \u53D6 companyId").option("--rag-only", "\u4EC5\u663E\u793A\u5DF2\u5EFA RAG \u5411\u91CF\u7D22\u5F15\uFF08ragStatus=true\uFF09\u7684\u77E5\u8BC6\u5E93", false).option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6483
+ async (opts) => {
6484
+ await runRagList({
6485
+ belongToId: opts.belongToId,
6486
+ ragOnly: opts.ragOnly,
6487
+ token: opts.token,
6488
+ json: opts.json,
6489
+ verbose: opts.verbose
6490
+ });
6491
+ }
6492
+ );
6493
+ ragCmd.command("query").description("\u6309\u5173\u952E\u8BCD\u68C0\u7D22\u5DF2\u7EB3\u5165\u5411\u91CF\u7684\u77E5\u8BC6\u7247\u6BB5\uFF08GET cutapi/v1/material/queryknowledges\uFF09").requiredOption("-q, --query <text>", "\u68C0\u7D22\u5173\u952E\u8BCD\u6216\u95EE\u53E5").option("--belong-to-id <id>", "\u4F01\u4E1A ID\uFF1B\u4E0D\u4F20\u5219\u4ECE GET /query/account/me \u53D6 companyId").option("--source-id <ids>", "\u7D20\u6750\u6587\u4EF6 ID\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u53EF\u9009\uFF0Cqueryknowledges \u7684 sourceid\uFF09").option("--folder-id <ids>", "\u6587\u4EF6\u5939 ID\uFF0C\u9017\u53F7\u5206\u9694\uFF08\u53EF\u9009\uFF0Ccomid\uFF09").option("--top-k <n>", "\u8FD4\u56DE\u6761\u6570\uFF0C3\u201330\uFF08\u9ED8\u8BA4 7\uFF09", "7").option("--belong-to <n>", "\u5F52\u5C5E\u7C7B\u578B\uFF08\u9ED8\u8BA4 0\uFF0C\u4F01\u4E1A\uFF09", "0").option("--tags <tags>", "\u6807\u7B7E\u8FC7\u6EE4\uFF0C\u9017\u53F7\u5206\u9694\uFF1B\u4E0D\u4F20\u5219\u4E0D\u8FC7\u6EE4\u6807\u7B7E\uFF08\u5168\u91CF\u68C0\u7D22\uFF09").option("--category <categories>", "\u5206\u7C7B\u8FC7\u6EE4\uFF0C\u9017\u53F7\u5206\u9694").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII +-|\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6494
+ async (opts) => {
6495
+ await runRagQuery({
6496
+ query: opts.query,
6497
+ belongToId: opts.belongToId,
6498
+ sourceId: opts.sourceId,
6499
+ folderId: opts.folderId,
6500
+ topK: opts.topK ? parseInt(opts.topK, 10) : void 0,
6501
+ belongTo: opts.belongTo !== void 0 ? parseInt(opts.belongTo, 10) : void 0,
6502
+ tags: opts.tags,
6503
+ category: opts.category,
6504
+ token: opts.token,
6505
+ json: opts.json,
6506
+ unicode: opts.unicode,
6507
+ verbose: opts.verbose
6508
+ });
6509
+ }
6510
+ );
6511
+ const REGISTRARS = [
6512
+ register
6513
+ ];
6514
+ for (const reg of REGISTRARS) reg(program2);
6515
+ program2.command("upload").description("\u4E0A\u4F20\u672C\u5730\u89C6\u9891\u6216\u56FE\u7247\u5230 Siluzan \u7D20\u6750\u5E93\uFF0C\u8F93\u51FA\u53EF\u76F4\u63A5\u586B\u5165 publish-config.json \u7684\u5B57\u6BB5").requiredOption("-f, --file <path>", "\u672C\u5730\u6587\u4EF6\u8DEF\u5F84").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--kind <video|image>", "\u624B\u52A8\u6307\u5B9A\u6587\u4EF6\u7C7B\u578B\uFF08\u9ED8\u8BA4\u6309\u6269\u5C55\u540D\u81EA\u52A8\u5224\u65AD\uFF09").option("--cover <path>", "\u5C01\u9762\u56FE\u7247\u8DEF\u5F84\uFF08\u4E0A\u4F20\u89C6\u9891\u65F6\u5FC5\u987B\u63D0\u4F9B\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F\u53CA\u5B8C\u6574 URL\uFF08\u9ED8\u8BA4\u9690\u85CF\u542B\u7B7E\u540D URL\uFF09", false).action(
6516
+ async (opts) => {
6517
+ await runUpload({
6518
+ file: opts.file,
6519
+ token: opts.token,
6520
+ kind: opts.kind,
6521
+ cover: opts.cover,
6522
+ verbose: opts.verbose
6523
+ });
6524
+ }
6525
+ );
6526
+ program2.command("extract-cover").description(
6527
+ "\u4ECE\u89C6\u9891\u6587\u4EF6\u622A\u53D6\u5C01\u9762\u5E27\uFF0C\u6309\u5E73\u53F0\u89C4\u683C\uFF08YouTube/TikTok/Twitter \u7B49\uFF09\u88C1\u526A\u7F29\u653E\uFF0C\u53EF\u9009\u81EA\u52A8\u4E0A\u4F20"
6528
+ ).requiredOption("-f, --file <path>", "\u89C6\u9891\u6587\u4EF6\u8DEF\u5F84\uFF08MP4/MOV/MKV \u7B49\uFF09").option(
6529
+ "-t, --time <seconds...>",
6530
+ "\u622A\u5E27\u65F6\u95F4\u70B9\uFF08\u79D2\uFF0C\u53EF\u591A\u4E2A\uFF09\uFF0C\u5982 -t 0 3 10 \u622A\u53D6\u7B2C 0\u30013\u300110 \u79D2\u5E27\uFF08\u9ED8\u8BA4: 0\uFF09"
6531
+ ).option(
6532
+ "-p, --platform <platform>",
6533
+ "\u76EE\u6807\u5E73\u53F0\uFF08\u9ED8\u8BA4 youtube\uFF09\u3002\u8FD0\u884C --list-platforms \u67E5\u770B\u5168\u90E8\u652F\u6301\u5E73\u53F0",
6534
+ "youtube"
6535
+ ).option("-o, --output <path>", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84\uFF08\u591A\u5E27\u65F6\u4F5C\u4E3A\u6587\u4EF6\u540D\u524D\u7F00\uFF1B\u9ED8\u8BA4\u4FDD\u5B58\u5728\u89C6\u9891\u540C\u76EE\u5F55\uFF09").option("--upload", "\u622A\u53D6\u540E\u81EA\u52A8\u4E0A\u4F20\u5C01\u9762\u5230\u7D20\u6750\u5E93\uFF0C\u5E76\u8F93\u51FA cover JSON \u7247\u6BB5", false).option("--list-platforms", "\u5217\u51FA\u6240\u6709\u652F\u6301\u7684\u5E73\u53F0\u5C01\u9762\u89C4\u683C", false).option("--token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").action(
6536
+ async (opts) => {
6537
+ if (opts.listPlatforms) {
6538
+ const { PLATFORM_COVER_SPECS } = await import("./extract-cover-RZ5OIHTV.js");
6539
+ const keys = Object.keys(PLATFORM_COVER_SPECS);
6540
+ console.log("\n\u5404\u5E73\u53F0\u89C6\u9891\u5C01\u9762\u89C4\u683C\uFF1A\n");
6541
+ const maxKeyLen = Math.max(...keys.map((k) => k.length));
6542
+ const maxNameLen = Math.max(...keys.map((k) => PLATFORM_COVER_SPECS[k].displayName.length));
7089
6543
  console.log(
7090
- ` ${key.padEnd(maxKeyLen)} ${spec.displayName.padEnd(maxNameLen)} ${size.padEnd(12)} ${spec.ratio.padEnd(6)} ${spec.note}`
6544
+ ` ${"\u5E73\u53F0 ID".padEnd(maxKeyLen)} ${"\u5E73\u53F0\u540D\u79F0".padEnd(maxNameLen)} ${"\u5C3A\u5BF8".padEnd(12)} ${"\u6BD4\u4F8B".padEnd(6)} \u8BF4\u660E`
7091
6545
  );
7092
- }
7093
- console.log();
7094
- return;
6546
+ console.log(" " + "-".repeat(maxKeyLen + maxNameLen + 55));
6547
+ for (const key of keys) {
6548
+ const spec = PLATFORM_COVER_SPECS[key];
6549
+ const size = `${spec.width}\xD7${spec.height}`;
6550
+ console.log(
6551
+ ` ${key.padEnd(maxKeyLen)} ${spec.displayName.padEnd(maxNameLen)} ${size.padEnd(12)} ${spec.ratio.padEnd(6)} ${spec.note}`
6552
+ );
6553
+ }
6554
+ console.log();
6555
+ return;
6556
+ }
6557
+ await runExtractCover({
6558
+ file: opts.file,
6559
+ time: opts.time,
6560
+ platform: opts.platform,
6561
+ output: opts.output,
6562
+ upload: opts.upload,
6563
+ token: opts.token
6564
+ });
7095
6565
  }
7096
- await runExtractCover({
7097
- file: opts.file,
7098
- time: opts.time,
7099
- platform: opts.platform,
7100
- output: opts.output,
7101
- upload: opts.upload,
7102
- token: opts.token
6566
+ );
6567
+ program2.command("publish").description("\u6309 JSON \u914D\u7F6E\u6587\u4EF6\u63D0\u4EA4\u53D1\u5E03\u4EFB\u52A1\u5230 CSO").requiredOption("-c, --config <path>", "\u53D1\u5E03\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08JSON\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--dry-run", "\u4EC5\u9884\u89C8\u8BF7\u6C42\u4F53\uFF0C\u4E0D\u5B9E\u9645\u63D0\u4EA4", false).option("--verbose", "\u663E\u793A\u5B8C\u6574\u8BF7\u6C42\u4F53\u53CA\u8BE6\u7EC6\u9519\u8BEF\uFF08\u542B\u654F\u611F\u5B57\u6BB5\uFF0C\u9ED8\u8BA4\u8131\u654F\uFF09", false).action(async (opts) => {
6568
+ await runPublish({
6569
+ config: opts.config,
6570
+ token: opts.token,
6571
+ dryRun: opts.dryRun,
6572
+ verbose: opts.verbose
7103
6573
  });
7104
- }
7105
- );
7106
- program.command("publish").description("\u6309 JSON \u914D\u7F6E\u6587\u4EF6\u63D0\u4EA4\u53D1\u5E03\u4EFB\u52A1\u5230 CSO").requiredOption("-c, --config <path>", "\u53D1\u5E03\u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84\uFF08JSON\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--dry-run", "\u4EC5\u9884\u89C8\u8BF7\u6C42\u4F53\uFF0C\u4E0D\u5B9E\u9645\u63D0\u4EA4", false).option("--verbose", "\u663E\u793A\u5B8C\u6574\u8BF7\u6C42\u4F53\u53CA\u8BE6\u7EC6\u9519\u8BEF\uFF08\u542B\u654F\u611F\u5B57\u6BB5\uFF0C\u9ED8\u8BA4\u8131\u654F\uFF09", false).action(async (opts) => {
7107
- await runPublish({
7108
- config: opts.config,
7109
- token: opts.token,
7110
- dryRun: opts.dryRun,
7111
- verbose: opts.verbose
7112
6574
  });
7113
- });
7114
- var reportCmd = program.command("report").description("\u8FD0\u8425\u62A5\u8868\uFF08table\uFF09\u76F8\u5173\u547D\u4EE4\uFF1A\u62C9\u53D6\u62A5\u8868\u6570\u636E\u3001\u67E5\u770B\u5BFC\u51FA\u8BB0\u5F55\u3001\u4E0B\u8F7D PDF");
7115
- reportCmd.command("fetch").description("\u6309\u5A92\u4F53/\u65E5\u671F\u62C9\u53D6\u8FD0\u8425\u62A5\u8868\u6A21\u5757\u6570\u636E\uFF08\u8986\u76D6 table \u9875\u4E3B\u8981\u67E5\u8BE2\u63A5\u53E3\uFF09").requiredOption(
7116
- "--media <mediaType>",
7117
- "\u5A92\u4F53\u7C7B\u578B\uFF0C\u5982 Douyin / YouTube / TikTokBusinessAccount / Twitter"
7118
- ).option(
7119
- "--maids <ids...>",
7120
- "\u5A92\u4F53\u8D26\u53F7list-accounts\u83B7\u53D6\u7684[mediaCustomerId] ID\uFF0C\u652F\u6301\u7A7A\u683C\u5206\u9694\u6216\u9017\u53F7\u5206\u9694\uFF1B\u4E0D\u4F20\u8868\u793A\u8BE5\u5A92\u4F53\u5168\u90E8\u8D26\u53F7"
7121
- ).option(
7122
- "--days <n>",
7123
- "\u8FD1 N \u5929\uFF08\u4ECE\u6628\u5929\u5F80\u56DE\u7B97\uFF09\uFF1A7=\u8FD1 7 \u5929\uFF0C30=\u8FD1 30 \u5929\uFF08\u9ED8\u8BA4\uFF09\uFF0C90/180 \u7B49\uFF0C\u4F18\u5148\u7EA7\u4F4E\u4E8E --start/--end"
7124
- ).option("--start <date>", "\u5F00\u59CB\u65F6\u95F4\uFF08\u672C\u5730\u65F6\u533A\uFF0CYYYY-MM-DD \u6216 ISO \u65E5\u671F\u65F6\u95F4\uFF09").option("--end <date>", "\u7ED3\u675F\u65F6\u95F4\uFF08\u672C\u5730\u65F6\u533A\uFF0CYYYY-MM-DD \u6216 ISO \u65E5\u671F\u65F6\u95F4\uFF09").option("--method <Day|Week|Moth>", "\u805A\u5408\u7EF4\u5EA6\uFF08\u4E0E Web table \u4FDD\u6301\u4E00\u81F4\uFF09", "Day").option(
7125
- "--include <modules...>",
7126
- "\u9700\u8981\u62C9\u53D6\u7684\u6A21\u5757\uFF0C\u652F\u6301\u9017\u53F7\u5206\u9694\uFF1Aoperation,total-fans,fans-analysis,hot-topic,works,hot-comment-word,comment-top10,video-duration,video-distribution,comment-trend,fans-trend,new-fans-trend,homepage-visit"
7127
- ).option("--order <play|digg|fullplay>", "works \u6A21\u5757\u6392\u5E8F\u5B57\u6BB5", "play").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON\uFF08\u9002\u5408\u811A\u672C\u5904\u7406\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7128
- async (opts) => {
7129
- await runReportFetch({
7130
- ...opts,
7131
- days: opts.days ? parseInt(opts.days, 10) : void 0
7132
- });
7133
- }
7134
- );
7135
- reportCmd.command("records").description("\u67E5\u8BE2\u8FD0\u8425\u62A5\u8868\u5BFC\u51FA\u8BB0\u5F55\uFF08\u5BF9\u5E94 table \u5BFC\u51FA\u8BB0\u5F55\u5F39\u7A97\uFF09").option("--page <number>", "\u9875\u7801\uFF08\u9ED8\u8BA4 1\uFF09").option("--page-size <number>", "\u6BCF\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 20\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON\uFF08\u9002\u5408\u811A\u672C\u5904\u7406\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7136
- async (opts) => {
7137
- await runReportRecords(opts);
7138
- }
7139
- );
7140
- reportCmd.command("download").description("\u6309\u5BFC\u51FA\u8BB0\u5F55 ID \u4E0B\u8F7D\u8FD0\u8425\u62A5\u8868 PDF\uFF08\u5BF9\u5E94 table \u7684\u91CD\u65B0\u4E0B\u8F7D\uFF09").requiredOption("--id <recordId>", "\u5BFC\u51FA\u8BB0\u5F55 ID").option("-o, --output <path>", "\u8F93\u51FA PDF \u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\u81EA\u52A8\u547D\u540D\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
7141
- await runReportDownload(opts);
7142
- });
7143
- var planningCmd = program.command("planning").description("AI \u5185\u5BB9\u89C4\u5212\uFF08planning\uFF09\uFF1A\u4F01\u4E1A\u5217\u8868\u3001\u5185\u5BB9\u7C7B\u578B\u3001\u751F\u6210\u3001\u4EFB\u52A1\u7BA1\u7406\u3001\u8BE6\u60C5\u4E0E\u5BFC\u51FA");
7144
- planningCmd.command("enterprises").description("\u67E5\u8BE2\u4F01\u4E1A\u76EE\u5F55\uFF08cutapi querylist\uFF0C\u4F9B\u89C4\u5212\u751F\u6210\u65F6\u9009\u62E9\u4F01\u4E1A\uFF09").option("--belong-to-id <id>", "\u4F01\u4E1A\u5F52\u5C5E ID\uFF08\u4E0D\u4F20\u65F6\u53D1\u9001\u7A7A\u503C\uFF09").option("--page-size <number>", "\u76EE\u5F55\u67E5\u8BE2\u6761\u6570\uFF08\u9ED8\u8BA4 100\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7145
- async (opts) => {
7146
- await runPlanningEnterprises(opts);
7147
- }
7148
- );
7149
- planningCmd.command("content-types").description("\u67E5\u8BE2\u53EF\u7528\u5185\u5BB9\u7C7B\u578B\uFF08\u5931\u8D25\u65F6\u56DE\u9000\u9ED8\u8BA4 post/video\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7150
- async (opts) => {
7151
- await runPlanningContentTypes(opts);
7152
- }
7153
- );
7154
- planningCmd.command("generate").description("\u521B\u5EFA\u89C4\u5212\u751F\u6210\u4EFB\u52A1\uFF08\u5BF9\u5E94 planning \u751F\u6210\u5F39\u7A97\uFF09").requiredOption("--enterprise-id <id>", "\u4F01\u4E1A ID").option("--enterprise-name <name>", "\u4F01\u4E1A\u540D\u79F0\uFF08\u4E0D\u4F20\u9ED8\u8BA4\u4F7F\u7528 enterprise-id\uFF09").requiredOption("--year-month <YYYY-MM>", "\u89C4\u5212\u6708\u4EFD").requiredOption("--content-types <types...>", "\u5185\u5BB9\u7C7B\u578B\uFF0C\u652F\u6301\u9017\u53F7\u6216\u7A7A\u683C\uFF1Apost,video").option("--partnership-total-months <6|12|24>", "\u5408\u4F5C\u603B\u6708\u6570\uFF08\u9ED8\u8BA4 12\uFF09", "12").option("--partnership-start-year-month <YYYY-MM>", "\u5408\u4F5C\u5F00\u59CB\u6708\u4EFD\uFF08\u4E0E\u89C4\u5212\u6708\u4E0D\u540C\u624D\u4F1A\u4F20\u7ED9\u63A5\u53E3\uFF09").option("--freq-unit <week|month>", "\u9891\u6B21\u5355\u4F4D").option("--freq-count <number>", "\u9891\u6B21\u6570\u91CF\uFF08\u4E0E --freq-unit \u540C\u65F6\u63D0\u4F9B\uFF09").option("--marketing-goal <text>", "\u672C\u6708\u89C4\u5212\u91CD\u70B9\uFF1A\u8425\u9500\u76EE\u6807").option("--key-products <text>", "\u672C\u6708\u89C4\u5212\u91CD\u70B9\uFF1A\u6838\u5FC3\u4EA7\u54C1").option("--target-markets <text>", "\u672C\u6708\u89C4\u5212\u91CD\u70B9\uFF1A\u76EE\u6807\u5E02\u573A").option("--key-events <text>", "\u672C\u6708\u89C4\u5212\u91CD\u70B9\uFF1A\u5173\u952E\u8282\u70B9").option("--content-tone <text>", "\u672C\u6708\u89C4\u5212\u91CD\u70B9\uFF1A\u5185\u5BB9\u8BED\u8C03").option("--watch", "\u63D0\u4EA4\u540E\u76D1\u542C\u4EFB\u52A1\u76F4\u5230\u5B8C\u6210/\u5931\u8D25", false).option("--watch-timeout <seconds>", "\u76D1\u542C\u8D85\u65F6\u79D2\u6570\uFF08\u9ED8\u8BA4 300 \u79D2\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7155
- async (opts) => {
7156
- await runPlanningGenerate(opts);
7157
- }
7158
- );
7159
- planningCmd.command("list").description("\u67E5\u8BE2\u89C4\u5212\u4EFB\u52A1\u5217\u8868\uFF08\u652F\u6301\u4F01\u4E1A/\u6708\u5EA6\u7B5B\u9009\u4E0E\u5206\u9875\uFF09").option("--enterprise-id <id>", "\u4F01\u4E1A ID").option("--year-month <YYYY-MM>", "\u89C4\u5212\u6708\u4EFD").option("--page-index <number>", "\u9875\u7801\uFF08\u9ED8\u8BA4 1\uFF09").option("--page-size <number>", "\u6BCF\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 10\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7160
- async (opts) => {
7161
- await runPlanningList(opts);
7162
- }
7163
- );
7164
- planningCmd.command("watch").description("\u76D1\u542C\u89C4\u5212\u4EFB\u52A1\u8FDB\u5EA6\uFF08SSE\uFF09").argument("<taskId>", "\u4EFB\u52A1 ID").option("--timeout <seconds>", "\u76D1\u542C\u8D85\u65F6\u79D2\u6570\uFF08\u9ED8\u8BA4 300 \u79D2\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7165
- async (taskId, opts) => {
7166
- await runPlanningWatchTask(taskId, opts);
7167
- }
7168
- );
7169
- var planningTaskCmd = planningCmd.command("task").description("\u89C4\u5212\u4EFB\u52A1\u64CD\u4F5C\uFF1A\u53D6\u6D88\u3001\u91CD\u8BD5\u3001\u5220\u9664");
7170
- planningTaskCmd.command("cancel").description("\u53D6\u6D88\u4EFB\u52A1").argument("<taskId>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (taskId, opts) => {
7171
- await runPlanningTaskCancel(taskId, opts);
7172
- });
7173
- planningTaskCmd.command("retry").description("\u91CD\u8BD5\u5931\u8D25/\u53D6\u6D88\u4EFB\u52A1").argument("<taskId>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (taskId, opts) => {
7174
- await runPlanningTaskRetry(taskId, opts);
7175
- });
7176
- planningTaskCmd.command("delete").description("\u5220\u9664\u4EFB\u52A1").argument("<taskId>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (taskId, opts) => {
7177
- await runPlanningTaskDelete(taskId, opts);
7178
- });
7179
- planningCmd.command("get").description("\u83B7\u53D6\u89C4\u5212\u8BE6\u60C5").argument("<planId>", "\u89C4\u5212 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (planId, opts) => {
7180
- await runPlanningGet(planId, opts);
7181
- });
7182
- planningCmd.command("regenerate").description("\u5BF9\u5DF2\u6709\u89C4\u5212\u53D1\u8D77\u518D\u751F\u6210").argument("<planId>", "\u89C4\u5212 ID").option("--watch", "\u63D0\u4EA4\u540E\u76D1\u542C\u4EFB\u52A1\u76F4\u5230\u5B8C\u6210/\u5931\u8D25", false).option("--watch-timeout <seconds>", "\u76D1\u542C\u8D85\u65F6\u79D2\u6570\uFF08\u9ED8\u8BA4 300 \u79D2\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7183
- async (planId, opts) => {
7184
- await runPlanningRegenerate(planId, opts);
7185
- }
7186
- );
7187
- var planningExportCmd = planningCmd.command("export").description("\u89C4\u5212\u5BFC\u51FA");
7188
- planningExportCmd.command("txt").description("\u5BFC\u51FA\u89C4\u5212\u4E3A TXT\uFF08Markdown \u8868\u683C\u683C\u5F0F\uFF09").option("--plan-id <id>", "\u89C4\u5212 ID\uFF08\u4E0E --input \u4E8C\u9009\u4E00\uFF09").option("--input <file>", "\u672C\u5730\u89C4\u5212 JSON \u6587\u4EF6\u8DEF\u5F84\uFF08\u4E0E --plan-id \u4E8C\u9009\u4E00\uFF09").option("-o, --output <file>", "\u5BFC\u51FA\u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u81EA\u52A8\u547D\u540D\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7189
- async (opts) => {
7190
- await runPlanningExportTxt(opts);
7191
- }
7192
- );
7193
- var taskCmd = program.command("task").description("\u4EFB\u52A1\u7BA1\u7406\uFF08taskManage\uFF09\uFF1A\u5217\u8868\u7B5B\u9009\u3001\u8BE6\u60C5\u3001\u4EFB\u52A1\u64CD\u4F5C\u3001\u53D1\u5E03\u9879\u64CD\u4F5C\u3001\u8BC4\u8BBA\u64CD\u4F5C");
7194
- taskCmd.command("list").description("\u67E5\u8BE2\u4EFB\u52A1\u5217\u8868\uFF08\u652F\u6301\u72B6\u6001/\u65F6\u95F4/\u7C7B\u578B/\u5173\u952E\u8BCD/\u5F02\u5E38\u4EFB\u52A1\u7B5B\u9009\uFF09").option("--page <number>", "\u9875\u7801\uFF08\u9ED8\u8BA4 1\uFF09").option("--size <number>", "\u6BCF\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 10\uFF09").option("--status <-1|0|1|2>", "\u72B6\u6001\uFF1A-1 \u5168\u90E8\uFF0C0 \u6267\u884C\u4E2D\uFF0C1 \u5DF2\u5B8C\u6210\uFF0C2 \u5DF2\u4E2D\u6B62").option("--asc", "\u6309\u521B\u5EFA\u65F6\u95F4\u5347\u5E8F\uFF08\u9ED8\u8BA4\u964D\u5E8F\uFF09", false).option("--search-type <task-name|creator>", "\u5173\u952E\u8BCD\u5B57\u6BB5\uFF08\u9ED8\u8BA4 task-name\uFF09", "task-name").option("--keyword <text>", "\u5173\u952E\u8BCD\uFF08\u914D\u5408 --search-type \u4F7F\u7528\uFF09").option("--creator <name>", "\u6309\u521B\u5EFA\u4EBA\u7B5B\u9009\uFF08\u4F18\u5148\u7EA7\u9AD8\u4E8E --keyword + --search-type creator\uFF09").option("--mine", "\u4EC5\u770B\u6211\u521B\u5EFA\u7684\uFF08\u9700\u540C\u65F6\u63D0\u4F9B --mine-name\uFF09", false).option("--mine-name <name>", "\u6211\u7684\u7528\u6237\u540D\uFF08\u7528\u4E8E --mine\uFF09").option("--failed-only", "\u4EC5\u67E5\u770B\u5F02\u5E38\u4EFB\u52A1\uFF08nolyFailed=true\uFF09", false).option("--content-type <all|video|image-text>", "\u5185\u5BB9\u7C7B\u578B\u7B5B\u9009", "all").option("--date-preset <all|week|month|year>", "\u5FEB\u6377\u65F6\u95F4\u8303\u56F4", "all").option("--start-date <YYYY-MM-DD>", "\u81EA\u5B9A\u4E49\u5F00\u59CB\u65E5\u671F\uFF08\u4E0E --end-date \u540C\u65F6\u4F7F\u7528\uFF09").option("--end-date <YYYY-MM-DD>", "\u81EA\u5B9A\u4E49\u7ED3\u675F\u65E5\u671F\uFF08\u4E0E --start-date \u540C\u65F6\u4F7F\u7528\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON\uFF08\u9002\u5408\u811A\u672C\u5904\u7406\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7195
- async (opts) => {
7196
- await runTaskList(opts);
7197
- }
7198
- );
7199
- taskCmd.command("detail").description("\u67E5\u770B\u4EFB\u52A1\u8BE6\u60C5\u53D1\u5E03\u9879\u5217\u8868\uFF08\u5BF9\u5E94\u8BE6\u60C5\u62BD\u5C49\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").option("--media <nameOrId>", "\u5A92\u4F53\u7C7B\u578B\uFF08\u5982 Douyin / YouTube\uFF0C\u6216\u6570\u5B57 ID\uFF09").option("--page <number>", "\u9875\u7801\uFF08\u9ED8\u8BA4 1\uFF09").option("--size <number>", "\u6BCF\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 10\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON\uFF08\u9002\u5408\u811A\u672C\u5904\u7406\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7200
- async (opts) => {
7201
- await runTaskDetail(opts);
7202
- }
7203
- );
7204
- taskCmd.command("start").description("\u542F\u52A8\u4EFB\u52A1\uFF08\u5BF9\u5E94 taskManage \u7684 startTask\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
7205
- await runTaskStart(opts);
7206
- });
7207
- taskCmd.command("stop").description("\u4E2D\u6B62\u4EFB\u52A1\uFF08\u5BF9\u5E94 taskManage \u7684 stopTask\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
7208
- await runTaskStop(opts);
7209
- });
7210
- taskCmd.command("delete").description("\u5220\u9664\u4EFB\u52A1\uFF08\u5BF9\u5E94 taskManage \u7684 deleteTask\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
7211
- await runTaskDelete(opts);
7212
- });
7213
- taskCmd.command("rename").description("\u91CD\u547D\u540D\u4EFB\u52A1\uFF08\u5BF9\u5E94 taskManage \u7684 reName\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").requiredOption("--name <taskName>", "\u65B0\u4EFB\u52A1\u540D").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
7214
- await runTaskRename(opts);
7215
- });
7216
- taskCmd.command("check-edit").description("\u68C0\u67E5\u4EFB\u52A1\u662F\u5426\u5141\u8BB8\u4FEE\u6539\uFF08\u5BF9\u5E94 checkAllowChange\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7217
- async (opts) => {
7218
- await runTaskCheckEdit(opts);
7219
- }
7220
- );
7221
- var taskItemCmd = taskCmd.command("item").description("\u4EFB\u52A1\u53D1\u5E03\u9879\u64CD\u4F5C\uFF1A\u5220\u9664\u3001\u91CD\u65B0\u53D1\u5E03\u3001\u7ACB\u5373\u53D1\u5E03");
7222
- taskItemCmd.command("delete").description("\u5220\u9664\u5355\u4E2A\u53D1\u5E03\u9879\uFF08deletePublishItem\uFF09").requiredOption("--item-id <id>", "\u53D1\u5E03\u9879 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
7223
- await runTaskItemDelete(opts);
7224
- });
7225
- taskItemCmd.command("republish").description("\u91CD\u65B0\u53D1\u5E03\u5355\u4E2A\u53D1\u5E03\u9879\uFF08rePublish\uFF09").requiredOption("--item-id <id>", "\u53D1\u5E03\u9879 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
7226
- await runTaskItemRepublish(opts);
7227
- });
7228
- taskItemCmd.command("run-now").description("\u7ACB\u5373\u53D1\u5E03\u5355\u4E2A\u53D1\u5E03\u9879\uFF08runPublish\uFF09").requiredOption("--item-id <id>", "\u53D1\u5E03\u9879 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
7229
- await runTaskItemRunNow(opts);
7230
- });
7231
- var taskCommentCmd = taskCmd.command("comment").description("\u4EFB\u52A1\u8BE6\u60C5\u4E2D\u7684\u8BC4\u8BBA\u67E5\u8BE2\u4E0E\u56DE\u590D");
7232
- taskCommentCmd.command("list").description("\u6309\u89C6\u9891\u67E5\u8BE2\u8BC4\u8BBA\u5217\u8868").requiredOption("--media-type <nameOrId>", "\u5A92\u4F53\u7C7B\u578B\uFF08\u5982 Douyin / YouTube \u6216\u6570\u5B57 ID\uFF09").requiredOption("--video-id <id>", "\u89C6\u9891 ID").requiredOption("--media-customer-id <id>", "\u5A92\u4F53\u8D26\u53F7 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
7233
- async (opts) => {
7234
- await runTaskCommentList(opts);
7235
- }
7236
- );
6575
+ const reportCmd = program2.command("report").description("\u8FD0\u8425\u62A5\u8868\uFF08table\uFF09\u76F8\u5173\u547D\u4EE4\uFF1A\u62C9\u53D6\u62A5\u8868\u6570\u636E\u3001\u67E5\u770B\u5BFC\u51FA\u8BB0\u5F55\u3001\u4E0B\u8F7D PDF");
6576
+ reportCmd.command("fetch").description("\u6309\u5A92\u4F53/\u65E5\u671F\u62C9\u53D6\u8FD0\u8425\u62A5\u8868\u6A21\u5757\u6570\u636E\uFF08\u8986\u76D6 table \u9875\u4E3B\u8981\u67E5\u8BE2\u63A5\u53E3\uFF09").requiredOption(
6577
+ "--media <mediaType>",
6578
+ "\u5A92\u4F53\u7C7B\u578B\uFF0C\u5982 Douyin / YouTube / TikTokBusinessAccount / Twitter"
6579
+ ).option(
6580
+ "--maids <ids...>",
6581
+ "\u5A92\u4F53\u8D26\u53F7list-accounts\u83B7\u53D6\u7684[mediaCustomerId] ID\uFF0C\u652F\u6301\u7A7A\u683C\u5206\u9694\u6216\u9017\u53F7\u5206\u9694\uFF1B\u4E0D\u4F20\u8868\u793A\u8BE5\u5A92\u4F53\u5168\u90E8\u8D26\u53F7"
6582
+ ).option(
6583
+ "--days <n>",
6584
+ "\u8FD1 N \u5929\uFF08\u4ECE\u6628\u5929\u5F80\u56DE\u7B97\uFF09\uFF1A7=\u8FD1 7 \u5929\uFF0C30=\u8FD1 30 \u5929\uFF08\u9ED8\u8BA4\uFF09\uFF0C90/180 \u7B49\uFF0C\u4F18\u5148\u7EA7\u4F4E\u4E8E --start/--end"
6585
+ ).option("--start <date>", "\u5F00\u59CB\u65F6\u95F4\uFF08\u672C\u5730\u65F6\u533A\uFF0CYYYY-MM-DD \u6216 ISO \u65E5\u671F\u65F6\u95F4\uFF09").option("--end <date>", "\u7ED3\u675F\u65F6\u95F4\uFF08\u672C\u5730\u65F6\u533A\uFF0CYYYY-MM-DD \u6216 ISO \u65E5\u671F\u65F6\u95F4\uFF09").option("--method <Day|Week|Moth>", "\u805A\u5408\u7EF4\u5EA6\uFF08\u4E0E Web table \u4FDD\u6301\u4E00\u81F4\uFF09", "Day").option(
6586
+ "--include <modules...>",
6587
+ "\u9700\u8981\u62C9\u53D6\u7684\u6A21\u5757\uFF0C\u652F\u6301\u9017\u53F7\u5206\u9694\uFF1Aoperation,total-fans,fans-analysis,hot-topic,works,hot-comment-word,comment-top10,video-duration,video-distribution,comment-trend,fans-trend,new-fans-trend,homepage-visit"
6588
+ ).option("--order <play|digg|fullplay>", "works \u6A21\u5757\u6392\u5E8F\u5B57\u6BB5", "play").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON\uFF08\u9002\u5408\u811A\u672C\u5904\u7406\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6589
+ async (opts) => {
6590
+ await runReportFetch({
6591
+ ...opts,
6592
+ days: opts.days ? parseInt(opts.days, 10) : void 0
6593
+ });
6594
+ }
6595
+ );
6596
+ reportCmd.command("records").description("\u67E5\u8BE2\u8FD0\u8425\u62A5\u8868\u5BFC\u51FA\u8BB0\u5F55\uFF08\u5BF9\u5E94 table \u5BFC\u51FA\u8BB0\u5F55\u5F39\u7A97\uFF09").option("--page <number>", "\u9875\u7801\uFF08\u9ED8\u8BA4 1\uFF09").option("--page-size <number>", "\u6BCF\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 20\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON\uFF08\u9002\u5408\u811A\u672C\u5904\u7406\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6597
+ async (opts) => {
6598
+ await runReportRecords(opts);
6599
+ }
6600
+ );
6601
+ reportCmd.command("download").description("\u6309\u5BFC\u51FA\u8BB0\u5F55 ID \u4E0B\u8F7D\u8FD0\u8425\u62A5\u8868 PDF\uFF08\u5BF9\u5E94 table \u7684\u91CD\u65B0\u4E0B\u8F7D\uFF09").requiredOption("--id <recordId>", "\u5BFC\u51FA\u8BB0\u5F55 ID").option("-o, --output <path>", "\u8F93\u51FA PDF \u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\u81EA\u52A8\u547D\u540D\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6602
+ await runReportDownload(opts);
6603
+ });
6604
+ const planningCmd = program2.command("planning").description("AI \u5185\u5BB9\u89C4\u5212\uFF08planning\uFF09\uFF1A\u4F01\u4E1A\u5217\u8868\u3001\u5185\u5BB9\u7C7B\u578B\u3001\u751F\u6210\u3001\u4EFB\u52A1\u7BA1\u7406\u3001\u8BE6\u60C5\u4E0E\u5BFC\u51FA");
6605
+ planningCmd.command("enterprises").description("\u67E5\u8BE2\u4F01\u4E1A\u76EE\u5F55\uFF08cutapi querylist\uFF0C\u4F9B\u89C4\u5212\u751F\u6210\u65F6\u9009\u62E9\u4F01\u4E1A\uFF09").option("--belong-to-id <id>", "\u4F01\u4E1A\u5F52\u5C5E ID\uFF08\u4E0D\u4F20\u65F6\u53D1\u9001\u7A7A\u503C\uFF09").option("--page-size <number>", "\u76EE\u5F55\u67E5\u8BE2\u6761\u6570\uFF08\u9ED8\u8BA4 100\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6606
+ async (opts) => {
6607
+ await runPlanningEnterprises(opts);
6608
+ }
6609
+ );
6610
+ planningCmd.command("content-types").description("\u67E5\u8BE2\u53EF\u7528\u5185\u5BB9\u7C7B\u578B\uFF08\u5931\u8D25\u65F6\u56DE\u9000\u9ED8\u8BA4 post/video\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6611
+ async (opts) => {
6612
+ await runPlanningContentTypes(opts);
6613
+ }
6614
+ );
6615
+ planningCmd.command("generate").description("\u521B\u5EFA\u89C4\u5212\u751F\u6210\u4EFB\u52A1\uFF08\u5BF9\u5E94 planning \u751F\u6210\u5F39\u7A97\uFF09").requiredOption("--enterprise-id <id>", "\u4F01\u4E1A ID").option("--enterprise-name <name>", "\u4F01\u4E1A\u540D\u79F0\uFF08\u4E0D\u4F20\u9ED8\u8BA4\u4F7F\u7528 enterprise-id\uFF09").requiredOption("--year-month <YYYY-MM>", "\u89C4\u5212\u6708\u4EFD").requiredOption("--content-types <types...>", "\u5185\u5BB9\u7C7B\u578B\uFF0C\u652F\u6301\u9017\u53F7\u6216\u7A7A\u683C\uFF1Apost,video").option("--partnership-total-months <6|12|24>", "\u5408\u4F5C\u603B\u6708\u6570\uFF08\u9ED8\u8BA4 12\uFF09", "12").option("--partnership-start-year-month <YYYY-MM>", "\u5408\u4F5C\u5F00\u59CB\u6708\u4EFD\uFF08\u4E0E\u89C4\u5212\u6708\u4E0D\u540C\u624D\u4F1A\u4F20\u7ED9\u63A5\u53E3\uFF09").option("--freq-unit <week|month>", "\u9891\u6B21\u5355\u4F4D").option("--freq-count <number>", "\u9891\u6B21\u6570\u91CF\uFF08\u4E0E --freq-unit \u540C\u65F6\u63D0\u4F9B\uFF09").option("--marketing-goal <text>", "\u672C\u6708\u89C4\u5212\u91CD\u70B9\uFF1A\u8425\u9500\u76EE\u6807").option("--key-products <text>", "\u672C\u6708\u89C4\u5212\u91CD\u70B9\uFF1A\u6838\u5FC3\u4EA7\u54C1").option("--target-markets <text>", "\u672C\u6708\u89C4\u5212\u91CD\u70B9\uFF1A\u76EE\u6807\u5E02\u573A").option("--key-events <text>", "\u672C\u6708\u89C4\u5212\u91CD\u70B9\uFF1A\u5173\u952E\u8282\u70B9").option("--content-tone <text>", "\u672C\u6708\u89C4\u5212\u91CD\u70B9\uFF1A\u5185\u5BB9\u8BED\u8C03").option("--watch", "\u63D0\u4EA4\u540E\u76D1\u542C\u4EFB\u52A1\u76F4\u5230\u5B8C\u6210/\u5931\u8D25", false).option("--watch-timeout <seconds>", "\u76D1\u542C\u8D85\u65F6\u79D2\u6570\uFF08\u9ED8\u8BA4 300 \u79D2\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6616
+ async (opts) => {
6617
+ await runPlanningGenerate(opts);
6618
+ }
6619
+ );
6620
+ planningCmd.command("list").description("\u67E5\u8BE2\u89C4\u5212\u4EFB\u52A1\u5217\u8868\uFF08\u652F\u6301\u4F01\u4E1A/\u6708\u5EA6\u7B5B\u9009\u4E0E\u5206\u9875\uFF09").option("--enterprise-id <id>", "\u4F01\u4E1A ID").option("--year-month <YYYY-MM>", "\u89C4\u5212\u6708\u4EFD").option("--page-index <number>", "\u9875\u7801\uFF08\u9ED8\u8BA4 1\uFF09").option("--page-size <number>", "\u6BCF\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 10\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6621
+ async (opts) => {
6622
+ await runPlanningList(opts);
6623
+ }
6624
+ );
6625
+ planningCmd.command("watch").description("\u76D1\u542C\u89C4\u5212\u4EFB\u52A1\u8FDB\u5EA6\uFF08SSE\uFF09").argument("<taskId>", "\u4EFB\u52A1 ID").option("--timeout <seconds>", "\u76D1\u542C\u8D85\u65F6\u79D2\u6570\uFF08\u9ED8\u8BA4 300 \u79D2\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6626
+ async (taskId, opts) => {
6627
+ await runPlanningWatchTask(taskId, opts);
6628
+ }
6629
+ );
6630
+ const planningTaskCmd = planningCmd.command("task").description("\u89C4\u5212\u4EFB\u52A1\u64CD\u4F5C\uFF1A\u53D6\u6D88\u3001\u91CD\u8BD5\u3001\u5220\u9664");
6631
+ planningTaskCmd.command("cancel").description("\u53D6\u6D88\u4EFB\u52A1").argument("<taskId>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (taskId, opts) => {
6632
+ await runPlanningTaskCancel(taskId, opts);
6633
+ });
6634
+ planningTaskCmd.command("retry").description("\u91CD\u8BD5\u5931\u8D25/\u53D6\u6D88\u4EFB\u52A1").argument("<taskId>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (taskId, opts) => {
6635
+ await runPlanningTaskRetry(taskId, opts);
6636
+ });
6637
+ planningTaskCmd.command("delete").description("\u5220\u9664\u4EFB\u52A1").argument("<taskId>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (taskId, opts) => {
6638
+ await runPlanningTaskDelete(taskId, opts);
6639
+ });
6640
+ planningCmd.command("get").description("\u83B7\u53D6\u89C4\u5212\u8BE6\u60C5").argument("<planId>", "\u89C4\u5212 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (planId, opts) => {
6641
+ await runPlanningGet(planId, opts);
6642
+ });
6643
+ planningCmd.command("regenerate").description("\u5BF9\u5DF2\u6709\u89C4\u5212\u53D1\u8D77\u518D\u751F\u6210").argument("<planId>", "\u89C4\u5212 ID").option("--watch", "\u63D0\u4EA4\u540E\u76D1\u542C\u4EFB\u52A1\u76F4\u5230\u5B8C\u6210/\u5931\u8D25", false).option("--watch-timeout <seconds>", "\u76D1\u542C\u8D85\u65F6\u79D2\u6570\uFF08\u9ED8\u8BA4 300 \u79D2\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6644
+ async (planId, opts) => {
6645
+ await runPlanningRegenerate(planId, opts);
6646
+ }
6647
+ );
6648
+ const planningExportCmd = planningCmd.command("export").description("\u89C4\u5212\u5BFC\u51FA");
6649
+ planningExportCmd.command("txt").description("\u5BFC\u51FA\u89C4\u5212\u4E3A TXT\uFF08Markdown \u8868\u683C\u683C\u5F0F\uFF09").option("--plan-id <id>", "\u89C4\u5212 ID\uFF08\u4E0E --input \u4E8C\u9009\u4E00\uFF09").option("--input <file>", "\u672C\u5730\u89C4\u5212 JSON \u6587\u4EF6\u8DEF\u5F84\uFF08\u4E0E --plan-id \u4E8C\u9009\u4E00\uFF09").option("-o, --output <file>", "\u5BFC\u51FA\u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u81EA\u52A8\u547D\u540D\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6650
+ async (opts) => {
6651
+ await runPlanningExportTxt(opts);
6652
+ }
6653
+ );
6654
+ const taskCmd = program2.command("task").description("\u4EFB\u52A1\u7BA1\u7406\uFF08taskManage\uFF09\uFF1A\u5217\u8868\u7B5B\u9009\u3001\u8BE6\u60C5\u3001\u4EFB\u52A1\u64CD\u4F5C\u3001\u53D1\u5E03\u9879\u64CD\u4F5C\u3001\u8BC4\u8BBA\u64CD\u4F5C");
6655
+ taskCmd.command("list").description("\u67E5\u8BE2\u4EFB\u52A1\u5217\u8868\uFF08\u652F\u6301\u72B6\u6001/\u65F6\u95F4/\u7C7B\u578B/\u5173\u952E\u8BCD/\u5F02\u5E38\u4EFB\u52A1\u7B5B\u9009\uFF09").option("--page <number>", "\u9875\u7801\uFF08\u9ED8\u8BA4 1\uFF09").option("--size <number>", "\u6BCF\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 10\uFF09").option("--status <-1|0|1|2>", "\u72B6\u6001\uFF1A-1 \u5168\u90E8\uFF0C0 \u6267\u884C\u4E2D\uFF0C1 \u5DF2\u5B8C\u6210\uFF0C2 \u5DF2\u4E2D\u6B62").option("--asc", "\u6309\u521B\u5EFA\u65F6\u95F4\u5347\u5E8F\uFF08\u9ED8\u8BA4\u964D\u5E8F\uFF09", false).option("--search-type <task-name|creator>", "\u5173\u952E\u8BCD\u5B57\u6BB5\uFF08\u9ED8\u8BA4 task-name\uFF09", "task-name").option("--keyword <text>", "\u5173\u952E\u8BCD\uFF08\u914D\u5408 --search-type \u4F7F\u7528\uFF09").option("--creator <name>", "\u6309\u521B\u5EFA\u4EBA\u7B5B\u9009\uFF08\u4F18\u5148\u7EA7\u9AD8\u4E8E --keyword + --search-type creator\uFF09").option("--mine", "\u4EC5\u770B\u6211\u521B\u5EFA\u7684\uFF08\u9700\u540C\u65F6\u63D0\u4F9B --mine-name\uFF09", false).option("--mine-name <name>", "\u6211\u7684\u7528\u6237\u540D\uFF08\u7528\u4E8E --mine\uFF09").option("--failed-only", "\u4EC5\u67E5\u770B\u5F02\u5E38\u4EFB\u52A1\uFF08nolyFailed=true\uFF09", false).option("--content-type <all|video|image-text>", "\u5185\u5BB9\u7C7B\u578B\u7B5B\u9009", "all").option("--date-preset <all|week|month|year>", "\u5FEB\u6377\u65F6\u95F4\u8303\u56F4", "all").option("--start-date <YYYY-MM-DD>", "\u81EA\u5B9A\u4E49\u5F00\u59CB\u65E5\u671F\uFF08\u4E0E --end-date \u540C\u65F6\u4F7F\u7528\uFF09").option("--end-date <YYYY-MM-DD>", "\u81EA\u5B9A\u4E49\u7ED3\u675F\u65E5\u671F\uFF08\u4E0E --start-date \u540C\u65F6\u4F7F\u7528\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON\uFF08\u9002\u5408\u811A\u672C\u5904\u7406\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6656
+ async (opts) => {
6657
+ await runTaskList(opts);
6658
+ }
6659
+ );
6660
+ taskCmd.command("detail").description("\u67E5\u770B\u4EFB\u52A1\u8BE6\u60C5\u53D1\u5E03\u9879\u5217\u8868\uFF08\u5BF9\u5E94\u8BE6\u60C5\u62BD\u5C49\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").option("--media <nameOrId>", "\u5A92\u4F53\u7C7B\u578B\uFF08\u5982 Douyin / YouTube\uFF0C\u6216\u6570\u5B57 ID\uFF09").option("--page <number>", "\u9875\u7801\uFF08\u9ED8\u8BA4 1\uFF09").option("--size <number>", "\u6BCF\u9875\u6761\u6570\uFF08\u9ED8\u8BA4 10\uFF09").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF1B\u4F18\u5148\u4E8E ~/.siluzan/config.json\uFF09").option("--json", "\u8F93\u51FA\u5B8C\u6574 JSON\uFF08\u9002\u5408\u811A\u672C\u5904\u7406\uFF09", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6661
+ async (opts) => {
6662
+ await runTaskDetail(opts);
6663
+ }
6664
+ );
6665
+ taskCmd.command("start").description("\u542F\u52A8\u4EFB\u52A1\uFF08\u5BF9\u5E94 taskManage \u7684 startTask\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6666
+ await runTaskStart(opts);
6667
+ });
6668
+ taskCmd.command("stop").description("\u4E2D\u6B62\u4EFB\u52A1\uFF08\u5BF9\u5E94 taskManage \u7684 stopTask\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6669
+ await runTaskStop(opts);
6670
+ });
6671
+ taskCmd.command("delete").description("\u5220\u9664\u4EFB\u52A1\uFF08\u5BF9\u5E94 taskManage \u7684 deleteTask\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6672
+ await runTaskDelete(opts);
6673
+ });
6674
+ taskCmd.command("rename").description("\u91CD\u547D\u540D\u4EFB\u52A1\uFF08\u5BF9\u5E94 taskManage \u7684 reName\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").requiredOption("--name <taskName>", "\u65B0\u4EFB\u52A1\u540D").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6675
+ await runTaskRename(opts);
6676
+ });
6677
+ taskCmd.command("check-edit").description("\u68C0\u67E5\u4EFB\u52A1\u662F\u5426\u5141\u8BB8\u4FEE\u6539\uFF08\u5BF9\u5E94 checkAllowChange\uFF09").requiredOption("--publish-id <id>", "\u4EFB\u52A1 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6678
+ async (opts) => {
6679
+ await runTaskCheckEdit(opts);
6680
+ }
6681
+ );
6682
+ const taskItemCmd = taskCmd.command("item").description("\u4EFB\u52A1\u53D1\u5E03\u9879\u64CD\u4F5C\uFF1A\u5220\u9664\u3001\u91CD\u65B0\u53D1\u5E03\u3001\u7ACB\u5373\u53D1\u5E03");
6683
+ taskItemCmd.command("delete").description("\u5220\u9664\u5355\u4E2A\u53D1\u5E03\u9879\uFF08deletePublishItem\uFF09").requiredOption("--item-id <id>", "\u53D1\u5E03\u9879 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6684
+ await runTaskItemDelete(opts);
6685
+ });
6686
+ taskItemCmd.command("republish").description("\u91CD\u65B0\u53D1\u5E03\u5355\u4E2A\u53D1\u5E03\u9879\uFF08rePublish\uFF09").requiredOption("--item-id <id>", "\u53D1\u5E03\u9879 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6687
+ await runTaskItemRepublish(opts);
6688
+ });
6689
+ taskItemCmd.command("run-now").description("\u7ACB\u5373\u53D1\u5E03\u5355\u4E2A\u53D1\u5E03\u9879\uFF08runPublish\uFF09").requiredOption("--item-id <id>", "\u53D1\u5E03\u9879 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(async (opts) => {
6690
+ await runTaskItemRunNow(opts);
6691
+ });
6692
+ const taskCommentCmd = taskCmd.command("comment").description("\u4EFB\u52A1\u8BE6\u60C5\u4E2D\u7684\u8BC4\u8BBA\u67E5\u8BE2\u4E0E\u56DE\u590D");
6693
+ taskCommentCmd.command("list").description("\u6309\u89C6\u9891\u67E5\u8BE2\u8BC4\u8BBA\u5217\u8868").requiredOption("--media-type <nameOrId>", "\u5A92\u4F53\u7C7B\u578B\uFF08\u5982 Douyin / YouTube \u6216\u6570\u5B57 ID\uFF09").requiredOption("--video-id <id>", "\u89C6\u9891 ID").requiredOption("--media-customer-id <id>", "\u5A92\u4F53\u8D26\u53F7 ID").option("-t, --token <token>", "Token\uFF08\u53EF\u9009\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--unicode", "\u4F7F\u7528 Unicode \u7EBF\u6846\u8868\u683C\uFF08\u9ED8\u8BA4 ASCII\uFF09", false).option("--verbose", "\u663E\u793A\u8BE6\u7EC6\u9519\u8BEF\u4FE1\u606F", false).action(
6694
+ async (opts) => {
6695
+ await runTaskCommentList(opts);
6696
+ }
6697
+ );
6698
+ }
6699
+
6700
+ // src/index.ts
6701
+ installProcessHandlers();
6702
+ var program = new Command();
6703
+ program.name("siluzan-cso").description("Siluzan \u5E73\u53F0 Skill \u5DE5\u5177\uFF1A\u521D\u59CB\u5316\u3001\u8D26\u53F7\u67E5\u8BE2\u3001\u4E0A\u4F20\u3001\u56FE\u6587/\u89C6\u9891\u53D1\u5E03").version(getCurrentVersion2());
6704
+ registerCsoCommands(program);
7237
6705
  program.parse();
7238
6706
  var activeCmd = process.argv[2];
7239
- if (activeCmd !== "update" && activeCmd !== "login") {
6707
+ if (activeCmd !== "update" && activeCmd !== "login" && activeCmd !== "send-login-code") {
7240
6708
  notifyIfOutdated().catch(() => {
7241
6709
  });
7242
6710
  }