siluzan-cso-cli 1.1.8-beta.4 → 1.1.8-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,7 +20,7 @@ siluzan-cso init -d /path/to/skills # 写入自定义目录
20
20
  siluzan-cso init --force # 强制覆盖已存在文件
21
21
  ```
22
22
 
23
- > **注意**:当前为测试版(1.1.8-beta.4),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-cso-cli`。
23
+ > **注意**:当前为测试版(1.1.8-beta.6),供内部测试使用。正式发布后安装命令将改为 `npm install -g siluzan-cso-cli`。
24
24
 
25
25
  | 助手 | 建议 `--ai` |
26
26
  |------|-------------|
package/dist/index.js CHANGED
@@ -2125,11 +2125,11 @@ import * as path3 from "path";
2125
2125
  import * as os2 from "os";
2126
2126
  import * as https from "https";
2127
2127
  import * as http from "http";
2128
- import * as os22 from "os";
2129
2128
  import { randomUUID as _randomUUID } from "crypto";
2130
2129
  import * as fs22 from "fs";
2131
2130
  import * as path22 from "path";
2132
2131
  import { fileURLToPath as fileURLToPath2 } from "url";
2132
+ import * as os22 from "os";
2133
2133
  var SILUZAN_DIR = path3.join(os2.homedir(), ".siluzan");
2134
2134
  var CONFIG_FILE = path3.join(SILUZAN_DIR, "config.json");
2135
2135
  function readStr(raw, key) {
@@ -2242,6 +2242,96 @@ function rawRequest(url, options) {
2242
2242
  req.end();
2243
2243
  });
2244
2244
  }
2245
+ function redactSensitive(input) {
2246
+ let output = input;
2247
+ output = output.replace(/(Bearer\s+)[^\s",]+/gi, "$1***");
2248
+ output = output.replace(
2249
+ /("?(?:apiKey|authToken|accessToken|refreshToken|token|authorization)"?\s*[:=]\s*"?)([^"\s,}]+)/gi,
2250
+ "$1***"
2251
+ );
2252
+ return output;
2253
+ }
2254
+ async function apiFetch(url, config, options = {}, verbose = false) {
2255
+ const method = options.method ?? "GET";
2256
+ const authHeaders = config.apiKey ? { "x-api-key": config.apiKey } : { Authorization: `Bearer ${config.authToken}` };
2257
+ const reqHeaders = {
2258
+ "Content-Type": "application/json",
2259
+ "Accept-Language": "zh-CN",
2260
+ ...authHeaders,
2261
+ // dataPermission 仅 TSO 使用;CSO 未设置时为空字符串,服务端忽略该头
2262
+ Datapermission: config.dataPermission ?? "",
2263
+ ...options.headers ?? {}
2264
+ };
2265
+ const body = typeof options.body === "string" ? options.body : void 0;
2266
+ const res = await rawRequest(url, {
2267
+ method,
2268
+ headers: reqHeaders,
2269
+ body
2270
+ });
2271
+ const text = res.text;
2272
+ if (res.status < 200 || res.status >= 300) {
2273
+ const detail = verbose ? `\uFF1A${redactSensitive(text).slice(0, 300)}` : "";
2274
+ throw new Error(`HTTP ${res.status}${detail}`);
2275
+ }
2276
+ if (!text.trim()) return null;
2277
+ try {
2278
+ return JSON.parse(text);
2279
+ } catch {
2280
+ if (verbose) {
2281
+ console.error(` \u26A0\uFE0F \u54CD\u5E94\u975E JSON\uFF0C\u539F\u59CB\u5185\u5BB9\uFF1A${redactSensitive(text).slice(0, 200)}`);
2282
+ }
2283
+ return text;
2284
+ }
2285
+ }
2286
+ function decodeJwtClaims(token) {
2287
+ try {
2288
+ const parts = token.split(".");
2289
+ if (parts.length < 2) return null;
2290
+ const payload = Buffer.from(parts[1], "base64url").toString("utf8");
2291
+ const parsed = JSON.parse(payload);
2292
+ return parsed.sub ? parsed : null;
2293
+ } catch {
2294
+ return null;
2295
+ }
2296
+ }
2297
+ function isUUID(value) {
2298
+ if (typeof value !== "string") return false;
2299
+ 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);
2300
+ }
2301
+ var randomUUID = _randomUUID;
2302
+ function getCurrentVersion(importMetaUrl) {
2303
+ try {
2304
+ const __dirname2 = path22.dirname(fileURLToPath2(importMetaUrl));
2305
+ const pkgPath = path22.join(__dirname2, "..", "package.json");
2306
+ const pkg = JSON.parse(fs22.readFileSync(pkgPath, "utf8"));
2307
+ return pkg.version ?? "0.0.0";
2308
+ } catch {
2309
+ return "0.0.0";
2310
+ }
2311
+ }
2312
+ function npmDistTagForBuildEnv(buildEnv) {
2313
+ return buildEnv === "test" ? "beta" : "latest";
2314
+ }
2315
+ function npmMinRequiredTagForBuildEnv(buildEnv) {
2316
+ return buildEnv === "test" ? "min-required-beta" : "min-required";
2317
+ }
2318
+ function isNewer(a, b) {
2319
+ return import_semver.default.gt(b, a) === true;
2320
+ }
2321
+ async function fetchNpmVersion(pkgName, tag, timeoutMs = 4e3) {
2322
+ try {
2323
+ const url = `https://registry.npmjs.org/${pkgName}/${tag}`;
2324
+ const controller = new AbortController();
2325
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
2326
+ const res = await fetch(url, { signal: controller.signal });
2327
+ clearTimeout(timer);
2328
+ if (!res.ok) return null;
2329
+ const data = await res.json();
2330
+ return data.version ?? null;
2331
+ } catch {
2332
+ return null;
2333
+ }
2334
+ }
2245
2335
  var DEFAULT_SENTRY_DSN = "https://bafcf42aab6fe7b485310619ae041b5e@o4510436169285632.ingest.us.sentry.io/4511103054708736";
2246
2336
  function isSentryDisabled() {
2247
2337
  return process.env.SILUZAN_SENTRY_DISABLED === "1" || process.env.SILUZAN_SENTRY_DISABLED === "true";
@@ -2281,11 +2371,6 @@ function redactCliArgvForSentry(argv) {
2281
2371
  }
2282
2372
  return out.join(" ");
2283
2373
  }
2284
- function isApiTrackingEnabled() {
2285
- const v = process.env.SILUZAN_SENTRY_TRACKING?.trim().toLowerCase();
2286
- if (v === "0" || v === "false" || v === "off" || v === "no") return false;
2287
- return true;
2288
- }
2289
2374
  function setSiluzanCliMeta(name, version) {
2290
2375
  cliMeta = { name, version };
2291
2376
  if (sentryReady) {
@@ -2374,178 +2459,6 @@ function inferSiluzanRuntimeEnvironment(requestUrl) {
2374
2459
  return "production";
2375
2460
  }
2376
2461
  }
2377
- function breadcrumbUrl(requestUrl) {
2378
- try {
2379
- const u = new URL(requestUrl);
2380
- return `${u.origin}${u.pathname}`;
2381
- } catch {
2382
- return requestUrl.slice(0, 120);
2383
- }
2384
- }
2385
- function trackingPathParts(requestUrl) {
2386
- try {
2387
- const u = new URL(requestUrl);
2388
- return { host: u.hostname.toLowerCase(), pathname: u.pathname || "/" };
2389
- } catch {
2390
- return { host: "unknown", pathname: "/" };
2391
- }
2392
- }
2393
- var SENSITIVE_QUERY_KEYS = /* @__PURE__ */ new Set([
2394
- "token",
2395
- "password",
2396
- "api_key",
2397
- "apikey",
2398
- "key",
2399
- "secret",
2400
- "authorization",
2401
- "auth"
2402
- ]);
2403
- function redactUrlForTracking(url) {
2404
- try {
2405
- const u = new URL(url);
2406
- const q = new URLSearchParams(u.search);
2407
- const out = new URLSearchParams();
2408
- for (const [k, v] of q.entries()) {
2409
- out.set(k, SENSITIVE_QUERY_KEYS.has(k.toLowerCase()) ? "[REDACTED]" : v);
2410
- }
2411
- const qs = out.toString();
2412
- return `${u.origin}${u.pathname}${qs ? `?${qs}` : ""}`;
2413
- } catch {
2414
- return url.slice(0, 800);
2415
- }
2416
- }
2417
- function redactTrackingHeaders(h) {
2418
- const out = {};
2419
- for (const [k, v] of Object.entries(h)) {
2420
- const low = k.toLowerCase();
2421
- if (low === "authorization" || low === "x-api-key") {
2422
- out[k] = "[REDACTED]";
2423
- } else if (v.length > 2e3) {
2424
- out[k] = `${v.slice(0, 500)}\u2026[truncated ${v.length} chars]`;
2425
- } else {
2426
- out[k] = v;
2427
- }
2428
- }
2429
- return out;
2430
- }
2431
- var SENSITIVE_JSON_KEY = /* @__PURE__ */ new Set([
2432
- "password",
2433
- "token",
2434
- "apikey",
2435
- "api_key",
2436
- "authorization",
2437
- "authtoken",
2438
- "accesstoken",
2439
- "refreshtoken",
2440
- "secret",
2441
- "client_secret",
2442
- "privatekey",
2443
- "private_key"
2444
- ]);
2445
- function deepRedactJson(value, depth) {
2446
- if (depth > 14) return "[MAX_DEPTH]";
2447
- if (value === null || typeof value !== "object") return value;
2448
- if (Array.isArray(value)) {
2449
- return value.map((v) => deepRedactJson(v, depth + 1));
2450
- }
2451
- const o = value;
2452
- const out = {};
2453
- for (const [k, v] of Object.entries(o)) {
2454
- const low = k.toLowerCase().replace(/_/g, "");
2455
- if (SENSITIVE_JSON_KEY.has(low) || low.includes("password") || low.includes("secret")) {
2456
- out[k] = "[REDACTED]";
2457
- } else {
2458
- out[k] = deepRedactJson(v, depth + 1);
2459
- }
2460
- }
2461
- return out;
2462
- }
2463
- function redactPlainTextSnippet(input) {
2464
- let s = input;
2465
- s = s.replace(/(Bearer\s+)[^\s'",}]+/gi, "$1***");
2466
- s = s.replace(
2467
- /("?(?:apiKey|authToken|accessToken|refreshToken|token|password)"?\s*[:=]\s*"?)([^"\s,}]{4,})/gi,
2468
- "$1***"
2469
- );
2470
- return s;
2471
- }
2472
- function trackingBodyMaxChars() {
2473
- const n = Number(process.env.SILUZAN_SENTRY_BODY_MAX);
2474
- if (Number.isFinite(n) && n > 256) return Math.min(n, 5e5);
2475
- return 12e3;
2476
- }
2477
- function trackingOmitBodies() {
2478
- const v = process.env.SILUZAN_SENTRY_NO_API_BODY?.trim().toLowerCase();
2479
- return v === "1" || v === "true" || v === "yes";
2480
- }
2481
- function formatTrackingBody(raw) {
2482
- if (trackingOmitBodies()) return "[omitted: SILUZAN_SENTRY_NO_API_BODY]";
2483
- if (raw === void 0 || raw === "") return "";
2484
- const max = trackingBodyMaxChars();
2485
- let text;
2486
- try {
2487
- const parsed = JSON.parse(raw);
2488
- text = JSON.stringify(deepRedactJson(parsed, 0));
2489
- } catch {
2490
- text = redactPlainTextSnippet(raw);
2491
- }
2492
- if (text.length > max) {
2493
- return `${text.slice(0, max)}\u2026[truncated ${text.length} chars]`;
2494
- }
2495
- return text;
2496
- }
2497
- async function reportSiluzanApiCall(payload) {
2498
- if (isSentryDisabled() || !getDsn() || !isApiTrackingEnabled()) return;
2499
- try {
2500
- const okInit = await ensureSentryInitialized(payload.url);
2501
- if (!okInit) return;
2502
- const Sentry = await import("@sentry/node");
2503
- const { host, pathname } = trackingPathParts(payload.url);
2504
- const siluzanEnv = inferSiluzanRuntimeEnvironment(payload.url);
2505
- const authType = payload.config.apiKey ? "apiKey" : "token";
2506
- const statusOk = payload.status >= 200 && payload.status < 300;
2507
- Sentry.captureMessage(
2508
- `siluzan.cli.api ${payload.method} ${host}${pathname} \u2192 ${payload.status}`,
2509
- {
2510
- level: statusOk ? "info" : "warning",
2511
- tags: {
2512
- siluzan_tracking: "api",
2513
- cli: cliMeta.name,
2514
- cli_version: cliMeta.version,
2515
- http_method: payload.method,
2516
- http_host: host,
2517
- http_status: String(payload.status),
2518
- siluzan_env: siluzanEnv,
2519
- auth_type: authType
2520
- },
2521
- fingerprint: [
2522
- "siluzan-cli-api",
2523
- cliMeta.name,
2524
- payload.method,
2525
- host,
2526
- pathname,
2527
- statusOk ? "2xx" : payload.status >= 500 ? "5xx" : "4xx"
2528
- ],
2529
- contexts: {
2530
- siluzan_cli: {
2531
- command: cliInvocation || "(pre-action \u672A\u6CE8\u518C\u6216\u5148\u4E8E parse \u53D1\u8D77\u8BF7\u6C42)"
2532
- },
2533
- siluzan_request: {
2534
- url: redactUrlForTracking(payload.url),
2535
- method: payload.method,
2536
- headers: redactTrackingHeaders(payload.reqHeaders),
2537
- body: formatTrackingBody(payload.requestBody)
2538
- },
2539
- siluzan_response: {
2540
- status: payload.status,
2541
- body: formatTrackingBody(payload.responseText)
2542
- }
2543
- }
2544
- }
2545
- );
2546
- } catch {
2547
- }
2548
- }
2549
2462
  function cacheKeyForUser(mainOrigin, config) {
2550
2463
  const cred = config.apiKey ? `k:${config.apiKey}` : `t:${config.authToken}`;
2551
2464
  return `${mainOrigin}\0${cred}`;
@@ -2659,133 +2572,6 @@ function refreshSiluzanUser(apiBase, config) {
2659
2572
  }
2660
2573
  })();
2661
2574
  }
2662
- async function prepareSiluzanSentryForApiFetch(url, config, options) {
2663
- if (isSentryDisabled()) return;
2664
- if (!getDsn()) return;
2665
- try {
2666
- const ok = await ensureSentryInitialized(url);
2667
- if (!ok) return;
2668
- const Sentry = await import("@sentry/node");
2669
- const method = options.method ?? "GET";
2670
- const siluzanEnv = inferSiluzanRuntimeEnvironment(url);
2671
- const authType = config.apiKey ? "apiKey" : "token";
2672
- Sentry.addBreadcrumb({
2673
- category: "siluzan.api",
2674
- type: "http",
2675
- level: "info",
2676
- message: `${method} ${breadcrumbUrl(url)}`,
2677
- data: {
2678
- siluzan_env: siluzanEnv,
2679
- auth_type: authType
2680
- }
2681
- });
2682
- const mainOrigin = deriveMainApiOriginFromRequestUrl(url);
2683
- if (mainOrigin) {
2684
- scheduleUserContext(mainOrigin, config);
2685
- }
2686
- } catch {
2687
- }
2688
- }
2689
- function redactSensitive(input) {
2690
- let output = input;
2691
- output = output.replace(/(Bearer\s+)[^\s",]+/gi, "$1***");
2692
- output = output.replace(
2693
- /("?(?:apiKey|authToken|accessToken|refreshToken|token|authorization)"?\s*[:=]\s*"?)([^"\s,}]+)/gi,
2694
- "$1***"
2695
- );
2696
- return output;
2697
- }
2698
- async function apiFetch(url, config, options = {}, verbose = false) {
2699
- await prepareSiluzanSentryForApiFetch(url, config, options);
2700
- const method = options.method ?? "GET";
2701
- const authHeaders = config.apiKey ? { "x-api-key": config.apiKey } : { Authorization: `Bearer ${config.authToken}` };
2702
- const reqHeaders = {
2703
- "Content-Type": "application/json",
2704
- "Accept-Language": "zh-CN",
2705
- ...authHeaders,
2706
- // dataPermission 仅 TSO 使用;CSO 未设置时为空字符串,服务端忽略该头
2707
- Datapermission: config.dataPermission ?? "",
2708
- ...options.headers ?? {}
2709
- };
2710
- const body = typeof options.body === "string" ? options.body : void 0;
2711
- const res = await rawRequest(url, {
2712
- method,
2713
- headers: reqHeaders,
2714
- body
2715
- });
2716
- const text = res.text;
2717
- await reportSiluzanApiCall({
2718
- url,
2719
- config,
2720
- method,
2721
- reqHeaders,
2722
- requestBody: body,
2723
- status: res.status,
2724
- responseText: text
2725
- });
2726
- if (res.status < 200 || res.status >= 300) {
2727
- const detail = verbose ? `\uFF1A${redactSensitive(text).slice(0, 300)}` : "";
2728
- throw new Error(`HTTP ${res.status}${detail}`);
2729
- }
2730
- if (!text.trim()) return null;
2731
- try {
2732
- return JSON.parse(text);
2733
- } catch {
2734
- if (verbose) {
2735
- console.error(` \u26A0\uFE0F \u54CD\u5E94\u975E JSON\uFF0C\u539F\u59CB\u5185\u5BB9\uFF1A${redactSensitive(text).slice(0, 200)}`);
2736
- }
2737
- return text;
2738
- }
2739
- }
2740
- function decodeJwtClaims(token) {
2741
- try {
2742
- const parts = token.split(".");
2743
- if (parts.length < 2) return null;
2744
- const payload = Buffer.from(parts[1], "base64url").toString("utf8");
2745
- const parsed = JSON.parse(payload);
2746
- return parsed.sub ? parsed : null;
2747
- } catch {
2748
- return null;
2749
- }
2750
- }
2751
- function isUUID(value) {
2752
- if (typeof value !== "string") return false;
2753
- 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);
2754
- }
2755
- var randomUUID = _randomUUID;
2756
- function getCurrentVersion(importMetaUrl) {
2757
- try {
2758
- const __dirname2 = path22.dirname(fileURLToPath2(importMetaUrl));
2759
- const pkgPath = path22.join(__dirname2, "..", "package.json");
2760
- const pkg = JSON.parse(fs22.readFileSync(pkgPath, "utf8"));
2761
- return pkg.version ?? "0.0.0";
2762
- } catch {
2763
- return "0.0.0";
2764
- }
2765
- }
2766
- function npmDistTagForBuildEnv(buildEnv) {
2767
- return buildEnv === "test" ? "beta" : "latest";
2768
- }
2769
- function npmMinRequiredTagForBuildEnv(buildEnv) {
2770
- return buildEnv === "test" ? "min-required-beta" : "min-required";
2771
- }
2772
- function isNewer(a, b) {
2773
- return import_semver.default.gt(b, a) === true;
2774
- }
2775
- async function fetchNpmVersion(pkgName, tag, timeoutMs = 4e3) {
2776
- try {
2777
- const url = `https://registry.npmjs.org/${pkgName}/${tag}`;
2778
- const controller = new AbortController();
2779
- const timer = setTimeout(() => controller.abort(), timeoutMs);
2780
- const res = await fetch(url, { signal: controller.signal });
2781
- clearTimeout(timer);
2782
- if (!res.ok) return null;
2783
- const data = await res.json();
2784
- return data.version ?? null;
2785
- } catch {
2786
- return null;
2787
- }
2788
- }
2789
2575
 
2790
2576
  // src/commands/login.ts
2791
2577
  async function runLogin(opts = {}) {
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "slug": "siluzan-cso",
3
- "version": "1.1.8-beta.4",
4
- "publishedAt": 1775715213765
3
+ "version": "1.1.8-beta.6",
4
+ "publishedAt": 1775717101837
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siluzan-cso-cli",
3
- "version": "1.1.8-beta.4",
3
+ "version": "1.1.8-beta.6",
4
4
  "description": "Siluzan platform AI Skill CLI — multi-platform content publishing (video/image-text) for Cursor, Claude Code, and OpenClaw.",
5
5
  "type": "module",
6
6
  "bin": {