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 +1 -1
- package/dist/index.js +91 -305
- package/dist/skill/_meta.json +2 -2
- package/package.json +1 -1
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.
|
|
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 = {}) {
|
package/dist/skill/_meta.json
CHANGED
package/package.json
CHANGED