maoda-commander-tt 0.0.12 → 0.0.16
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/main.js +1227 -16
- package/dist/main.js.map +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -1823,7 +1823,7 @@ var PippitCommand = class extends BaseSubcommandHost {
|
|
|
1823
1823
|
import { spawnSync } from "child_process";
|
|
1824
1824
|
var GitBaseCommand = class extends BaseCommand {
|
|
1825
1825
|
_configureArguments(cmd) {
|
|
1826
|
-
cmd.argument("[msg]", "\u63D0\u4EA4\u6D88\u606F", "update");
|
|
1826
|
+
cmd.argument("[msg]", "\u63D0\u4EA4\u6D88\u606F", "feat: update");
|
|
1827
1827
|
}
|
|
1828
1828
|
_configureOptions(cmd) {
|
|
1829
1829
|
cmd.option("-n, --no-verify", "\u8DF3\u8FC7 git hook \u6821\u9A8C");
|
|
@@ -1854,7 +1854,10 @@ var GitBaseCommand = class extends BaseCommand {
|
|
|
1854
1854
|
encoding: "utf8"
|
|
1855
1855
|
});
|
|
1856
1856
|
if (result.error) {
|
|
1857
|
-
return makeError(
|
|
1857
|
+
return makeError(
|
|
1858
|
+
1,
|
|
1859
|
+
`\u6267\u884C git ${args.join(" ")} \u5931\u8D25: ${result.error.message}`
|
|
1860
|
+
);
|
|
1858
1861
|
}
|
|
1859
1862
|
if (result.status !== 0) {
|
|
1860
1863
|
const signalText = result.signal ? `, signal: ${result.signal}` : "";
|
|
@@ -1936,10 +1939,7 @@ var GitBaseCommand = class extends BaseCommand {
|
|
|
1936
1939
|
}
|
|
1937
1940
|
if (result.status !== 0) {
|
|
1938
1941
|
const signalText = result.signal ? `, signal: ${result.signal}` : "";
|
|
1939
|
-
return this._makeError(
|
|
1940
|
-
result.status ?? 1,
|
|
1941
|
-
`\u6253\u5F00\u6D4F\u89C8\u5668\u5931\u8D25${signalText}`
|
|
1942
|
-
);
|
|
1942
|
+
return this._makeError(result.status ?? 1, `\u6253\u5F00\u6D4F\u89C8\u5668\u5931\u8D25${signalText}`);
|
|
1943
1943
|
}
|
|
1944
1944
|
return this._makeOk();
|
|
1945
1945
|
}
|
|
@@ -2078,9 +2078,9 @@ var ShortcutBaseCommand = class extends BaseCommand {
|
|
|
2078
2078
|
stdio: "inherit",
|
|
2079
2079
|
shell: true
|
|
2080
2080
|
});
|
|
2081
|
-
return new Promise((
|
|
2081
|
+
return new Promise((resolve8) => {
|
|
2082
2082
|
child.on("error", (error) => {
|
|
2083
|
-
|
|
2083
|
+
resolve8(
|
|
2084
2084
|
this._makeError(
|
|
2085
2085
|
1,
|
|
2086
2086
|
`\u6267\u884C ${cmdLine} \u5931\u8D25: ${error.message}`
|
|
@@ -2089,11 +2089,11 @@ var ShortcutBaseCommand = class extends BaseCommand {
|
|
|
2089
2089
|
});
|
|
2090
2090
|
child.on("close", (code, signal) => {
|
|
2091
2091
|
if (code === 0) {
|
|
2092
|
-
|
|
2092
|
+
resolve8(this._makeOk());
|
|
2093
2093
|
return;
|
|
2094
2094
|
}
|
|
2095
2095
|
const signalText = signal ? `, signal: ${signal}` : "";
|
|
2096
|
-
|
|
2096
|
+
resolve8(
|
|
2097
2097
|
this._makeError(
|
|
2098
2098
|
code ?? 1,
|
|
2099
2099
|
`\u6267\u884C ${cmdLine} \u5931\u8D25${signalText}`
|
|
@@ -2170,9 +2170,9 @@ var AiBaseCommand = class extends BaseCommand {
|
|
|
2170
2170
|
cwd: process.cwd(),
|
|
2171
2171
|
stdio: "inherit"
|
|
2172
2172
|
});
|
|
2173
|
-
return new Promise((
|
|
2173
|
+
return new Promise((resolve8) => {
|
|
2174
2174
|
child.on("error", (error) => {
|
|
2175
|
-
|
|
2175
|
+
resolve8(
|
|
2176
2176
|
this._makeError(
|
|
2177
2177
|
1,
|
|
2178
2178
|
`\u6267\u884C ${command} ${args.join(" ")} \u5931\u8D25: ${error.message}`
|
|
@@ -2181,11 +2181,11 @@ var AiBaseCommand = class extends BaseCommand {
|
|
|
2181
2181
|
});
|
|
2182
2182
|
child.on("close", (code, signal) => {
|
|
2183
2183
|
if (code === 0) {
|
|
2184
|
-
|
|
2184
|
+
resolve8(this._makeOk());
|
|
2185
2185
|
return;
|
|
2186
2186
|
}
|
|
2187
2187
|
const signalText = signal ? `, signal: ${signal}` : "";
|
|
2188
|
-
|
|
2188
|
+
resolve8(
|
|
2189
2189
|
this._makeError(
|
|
2190
2190
|
code ?? 1,
|
|
2191
2191
|
`\u6267\u884C ${command} ${args.join(" ")} \u5931\u8D25${signalText}`
|
|
@@ -2196,6 +2196,10 @@ var AiBaseCommand = class extends BaseCommand {
|
|
|
2196
2196
|
}
|
|
2197
2197
|
};
|
|
2198
2198
|
|
|
2199
|
+
// src/constants/ak.ts
|
|
2200
|
+
var ARK_AK = "6990de07-83be-487d-930d-f5dd3b6d5993";
|
|
2201
|
+
var OPENROUTER_AK = "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";
|
|
2202
|
+
|
|
2199
2203
|
// src/commands/ai/ai-websearch-command.ts
|
|
2200
2204
|
var AiWebSearchCommand = class extends AiBaseCommand {
|
|
2201
2205
|
_meta() {
|
|
@@ -2213,7 +2217,7 @@ var AiWebSearchCommand = class extends AiBaseCommand {
|
|
|
2213
2217
|
return this._makeError(1, "\u8BF7\u8F93\u5165\u641C\u7D22\u5185\u5BB9");
|
|
2214
2218
|
}
|
|
2215
2219
|
const url = "https://ark.cn-beijing.volces.com/api/v3/responses";
|
|
2216
|
-
const token =
|
|
2220
|
+
const token = ARK_AK;
|
|
2217
2221
|
const response = await fetch(url, {
|
|
2218
2222
|
method: "POST",
|
|
2219
2223
|
headers: {
|
|
@@ -2423,7 +2427,7 @@ var AiRunCommand = class extends AiBaseCommand {
|
|
|
2423
2427
|
}
|
|
2424
2428
|
_createSystemReminder(referenceDir) {
|
|
2425
2429
|
return `<system-reminder>
|
|
2426
|
-
\u53C2\u8003\u6587\u4EF6\u8DEF\u5F84 ${referenceDir} \u6587\u4EF6\u5939\u7684\u5185\u5BB9\uFF0C\u6267\u884C\u7528\u6237\u7684\u8981\u6C42\uFF0C\u82E5\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\uFF0C\u4E0D\u8981\u5BF9\u8BE5\u6587\u4EF6\u5939\u7684\u5185\u5BB9\u8FDB\u884C\u4FEE\u6539\uFF0C\u800C\u662F\u67E5\u9605\u91CC\u9762\u7684\u5185\u5BB9\u4F5C\u4E3A\u4E0A\u4E0B\u6587\u8865\u5145\u6BD4\u5982\u4F5C\u4E3A\u4FE1\u606F\u53C2\u8003\uFF0C\u6216\u8005\u6267\u884C\u6307\u5F15\uFF1B
|
|
2430
|
+
\u53C2\u8003\u6587\u4EF6\u8DEF\u5F84 ${referenceDir} \u4E0B\uFF0C\u6587\u4EF6\u5939\u91CC\u7684\u5185\u5BB9\uFF0C\u6267\u884C\u7528\u6237\u7684\u8981\u6C42\uFF0C\u82E5\u975E\u7528\u6237\u660E\u786E\u8981\u6C42\uFF0C\u4E0D\u8981\u5BF9\u8BE5\u6587\u4EF6\u5939\u7684\u5185\u5BB9\u8FDB\u884C\u4FEE\u6539\uFF0C\u800C\u662F\u67E5\u9605\u91CC\u9762\u7684\u5185\u5BB9\u4F5C\u4E3A\u4E0A\u4E0B\u6587\u8865\u5145\u6BD4\u5982\u4F5C\u4E3A\u4FE1\u606F\u53C2\u8003\uFF0C\u6216\u8005\u6267\u884C\u6307\u5F15\uFF1B
|
|
2427
2431
|
\u5982\u679C user_prompt \u91CC\uFF0C\u7ED9\u51FA\u4E00\u4E9B\u6587\u4EF6\u8DEF\u5F84\uFF0C\u9ED8\u8BA4\u662F\u5F53\u524D\u6267\u884C\u547D\u4EE4\u8DEF\u5F84 (cwd) \u4E0B\u7684\u6587\u4EF6\uFF0C\u63D0\u4F9B\u7684\u662F\u672C\u6B21\u8981\u6C42\u7684\u8BE6\u7EC6\u6307\u4EE4\u6216\u8005\u91CD\u8981\u7684\u53C2\u8003\u4FE1\u606F
|
|
2428
2432
|
\u82E5\u7528\u6237\u672A\u63D0\u53CA\u4EFB\u4F55\u6587\u4EF6\u548C\u76EE\u5F55\uFF0C\u4F60\u65E0\u9700\u8BFB\u53D6\u547D\u4EE4\u6267\u884C\u76EE\u5F55\u4E0B\u7684\u4EFB\u4F55\u5185\u5BB9\uFF0C\u53EA\u9700\u5728\u53C2\u8003\u6587\u4EF6\u8DEF\u5F84\u4E0B\u641C\u7D22\u76F8\u5173\u7684\u4FE1\u606F\u5373\u53EF
|
|
2429
2433
|
\u6700\u540E\u7ED9\u51FA\u7684\u7528\u6237\u56DE\u590D\uFF0C\u65E0\u9700\u5F15\u7528\u53C2\u8003\u6587\u4EF6\u76EE\u5F55\u4E0B\u7684\u5177\u4F53\u6587\u4EF6\uFF0C\u56E0\u4E3A\u7528\u6237\u4E0D\u4F1A\u53BB\u770B\u5BF9\u5E94\u7684\u6587\u4EF6\uFF0C\u800C\u4E14\u8FD9\u4E5F\u662F\u5185\u90E8\u79C1\u6709\u4FE1\u606F
|
|
@@ -2433,6 +2437,1210 @@ user_prompt:
|
|
|
2433
2437
|
}
|
|
2434
2438
|
};
|
|
2435
2439
|
|
|
2440
|
+
// src/commands/ai/ai-image-command.ts
|
|
2441
|
+
import * as fs6 from "fs/promises";
|
|
2442
|
+
import * as path7 from "path";
|
|
2443
|
+
import { Option as Option8 } from "commander";
|
|
2444
|
+
|
|
2445
|
+
// src/commands/ai/ai-image-reference.ts
|
|
2446
|
+
import * as fs5 from "fs/promises";
|
|
2447
|
+
import * as os2 from "os";
|
|
2448
|
+
import * as path6 from "path";
|
|
2449
|
+
import { execFile } from "child_process";
|
|
2450
|
+
import { promisify } from "util";
|
|
2451
|
+
var execFileAsync = promisify(execFile);
|
|
2452
|
+
var MAX_REFERENCE_IMAGE_BYTES = 2 * 1024 * 1024;
|
|
2453
|
+
var MAX_REFERENCE_IMAGE_COUNT = 14;
|
|
2454
|
+
var API_SUPPORTED_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
2455
|
+
"image/jpeg",
|
|
2456
|
+
"image/png",
|
|
2457
|
+
"image/webp",
|
|
2458
|
+
"image/bmp",
|
|
2459
|
+
"image/tiff",
|
|
2460
|
+
"image/gif"
|
|
2461
|
+
]);
|
|
2462
|
+
async function prepareReferenceImages(filePaths) {
|
|
2463
|
+
if (filePaths.length > MAX_REFERENCE_IMAGE_COUNT) {
|
|
2464
|
+
return makeError(
|
|
2465
|
+
1,
|
|
2466
|
+
`\u53C2\u8003\u56FE\u6700\u591A\u652F\u6301 ${MAX_REFERENCE_IMAGE_COUNT} \u5F20\uFF0C\u5F53\u524D\u4F20\u5165 ${filePaths.length} \u5F20\u3002`
|
|
2467
|
+
);
|
|
2468
|
+
}
|
|
2469
|
+
const preparedImages = [];
|
|
2470
|
+
for (const filePath of filePaths) {
|
|
2471
|
+
const prepared = await prepareReferenceImage(filePath);
|
|
2472
|
+
if (!prepared.ok) {
|
|
2473
|
+
return prepared;
|
|
2474
|
+
}
|
|
2475
|
+
preparedImages.push(prepared.value);
|
|
2476
|
+
}
|
|
2477
|
+
return makeOkWith(preparedImages);
|
|
2478
|
+
}
|
|
2479
|
+
async function prepareReferenceImage(filePath) {
|
|
2480
|
+
const resolvedPath = path6.resolve(process.cwd(), filePath);
|
|
2481
|
+
let stats;
|
|
2482
|
+
try {
|
|
2483
|
+
stats = await fs5.stat(resolvedPath);
|
|
2484
|
+
} catch (error) {
|
|
2485
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2486
|
+
return makeError(1, `\u8BFB\u53D6\u53C2\u8003\u56FE\u5931\u8D25: ${resolvedPath}: ${message}`);
|
|
2487
|
+
}
|
|
2488
|
+
if (!stats.isFile()) {
|
|
2489
|
+
return makeError(1, `\u53C2\u8003\u56FE\u4E0D\u662F\u6587\u4EF6: ${resolvedPath}`);
|
|
2490
|
+
}
|
|
2491
|
+
let fileBytes;
|
|
2492
|
+
try {
|
|
2493
|
+
fileBytes = await fs5.readFile(resolvedPath);
|
|
2494
|
+
} catch (error) {
|
|
2495
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2496
|
+
return makeError(1, `\u8BFB\u53D6\u53C2\u8003\u56FE\u5185\u5BB9\u5931\u8D25: ${resolvedPath}: ${message}`);
|
|
2497
|
+
}
|
|
2498
|
+
const detectedType = detectMimeType(fileBytes, resolvedPath);
|
|
2499
|
+
if (!detectedType) {
|
|
2500
|
+
return makeError(1, `\u53C2\u8003\u56FE\u4E0D\u662F\u652F\u6301\u7684\u56FE\u7247\u683C\u5F0F: ${resolvedPath}`);
|
|
2501
|
+
}
|
|
2502
|
+
const needsTranscode = !API_SUPPORTED_MIME_TYPES.has(detectedType.mimeType) || fileBytes.byteLength > MAX_REFERENCE_IMAGE_BYTES;
|
|
2503
|
+
if (!needsTranscode) {
|
|
2504
|
+
return makeOkWith({
|
|
2505
|
+
inputPath: filePath,
|
|
2506
|
+
resolvedPath,
|
|
2507
|
+
sourceMimeType: detectedType.mimeType,
|
|
2508
|
+
requestMimeType: detectedType.mimeType,
|
|
2509
|
+
originalBytes: fileBytes.byteLength,
|
|
2510
|
+
finalBytes: fileBytes.byteLength,
|
|
2511
|
+
compressed: false,
|
|
2512
|
+
dataUrl: toDataUrl(detectedType.mimeType, fileBytes)
|
|
2513
|
+
});
|
|
2514
|
+
}
|
|
2515
|
+
const compressed = await compressImageForReference(resolvedPath);
|
|
2516
|
+
if (!compressed.ok) {
|
|
2517
|
+
return compressed;
|
|
2518
|
+
}
|
|
2519
|
+
return makeOkWith({
|
|
2520
|
+
inputPath: filePath,
|
|
2521
|
+
resolvedPath,
|
|
2522
|
+
sourceMimeType: detectedType.mimeType,
|
|
2523
|
+
requestMimeType: compressed.value.mimeType,
|
|
2524
|
+
originalBytes: fileBytes.byteLength,
|
|
2525
|
+
finalBytes: compressed.value.bytes.byteLength,
|
|
2526
|
+
compressed: true,
|
|
2527
|
+
dataUrl: toDataUrl(compressed.value.mimeType, compressed.value.bytes)
|
|
2528
|
+
});
|
|
2529
|
+
}
|
|
2530
|
+
function detectMimeType(fileBytes, filePath) {
|
|
2531
|
+
if (fileBytes.length >= 3 && fileBytes[0] === 255 && fileBytes[1] === 216 && fileBytes[2] === 255) {
|
|
2532
|
+
return { mimeType: "image/jpeg", extension: "jpeg" };
|
|
2533
|
+
}
|
|
2534
|
+
if (fileBytes.length >= 8 && fileBytes[0] === 137 && fileBytes[1] === 80 && fileBytes[2] === 78 && fileBytes[3] === 71 && fileBytes[4] === 13 && fileBytes[5] === 10 && fileBytes[6] === 26 && fileBytes[7] === 10) {
|
|
2535
|
+
return { mimeType: "image/png", extension: "png" };
|
|
2536
|
+
}
|
|
2537
|
+
if (fileBytes.length >= 6) {
|
|
2538
|
+
const gifHeader = fileBytes.subarray(0, 6).toString("ascii");
|
|
2539
|
+
if (gifHeader === "GIF87a" || gifHeader === "GIF89a") {
|
|
2540
|
+
return { mimeType: "image/gif", extension: "gif" };
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
if (fileBytes.length >= 12 && fileBytes.subarray(0, 4).toString("ascii") === "RIFF" && fileBytes.subarray(8, 12).toString("ascii") === "WEBP") {
|
|
2544
|
+
return { mimeType: "image/webp", extension: "webp" };
|
|
2545
|
+
}
|
|
2546
|
+
if (fileBytes.length >= 2 && fileBytes.subarray(0, 2).toString("ascii") === "BM") {
|
|
2547
|
+
return { mimeType: "image/bmp", extension: "bmp" };
|
|
2548
|
+
}
|
|
2549
|
+
if (fileBytes.length >= 4 && (fileBytes[0] === 73 && fileBytes[1] === 73 && fileBytes[2] === 42 && fileBytes[3] === 0 || fileBytes[0] === 77 && fileBytes[1] === 77 && fileBytes[2] === 0 && fileBytes[3] === 42)) {
|
|
2550
|
+
return { mimeType: "image/tiff", extension: "tiff" };
|
|
2551
|
+
}
|
|
2552
|
+
if (fileBytes.length >= 12 && fileBytes.subarray(4, 8).toString("ascii") === "ftyp") {
|
|
2553
|
+
const brand = fileBytes.subarray(8, 12).toString("ascii").trim();
|
|
2554
|
+
if (brand.startsWith("avif") || brand === "avis") {
|
|
2555
|
+
return { mimeType: "image/avif", extension: "avif" };
|
|
2556
|
+
}
|
|
2557
|
+
if (brand.startsWith("hei") || brand.startsWith("hev") || brand === "mif1" || brand === "msf1") {
|
|
2558
|
+
return { mimeType: "image/heic", extension: "heic" };
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
const ext = path6.extname(filePath).toLowerCase();
|
|
2562
|
+
switch (ext) {
|
|
2563
|
+
case ".jpg":
|
|
2564
|
+
case ".jpeg":
|
|
2565
|
+
return { mimeType: "image/jpeg", extension: "jpeg" };
|
|
2566
|
+
case ".png":
|
|
2567
|
+
return { mimeType: "image/png", extension: "png" };
|
|
2568
|
+
case ".gif":
|
|
2569
|
+
return { mimeType: "image/gif", extension: "gif" };
|
|
2570
|
+
case ".webp":
|
|
2571
|
+
return { mimeType: "image/webp", extension: "webp" };
|
|
2572
|
+
case ".bmp":
|
|
2573
|
+
return { mimeType: "image/bmp", extension: "bmp" };
|
|
2574
|
+
case ".tif":
|
|
2575
|
+
case ".tiff":
|
|
2576
|
+
return { mimeType: "image/tiff", extension: "tiff" };
|
|
2577
|
+
case ".heic":
|
|
2578
|
+
case ".heif":
|
|
2579
|
+
return { mimeType: "image/heic", extension: "heic" };
|
|
2580
|
+
case ".avif":
|
|
2581
|
+
return { mimeType: "image/avif", extension: "avif" };
|
|
2582
|
+
default:
|
|
2583
|
+
return void 0;
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
async function compressImageForReference(sourcePath) {
|
|
2587
|
+
if (process.platform !== "darwin") {
|
|
2588
|
+
return makeError(
|
|
2589
|
+
1,
|
|
2590
|
+
`\u53C2\u8003\u56FE\u9700\u8981\u538B\u7F29\u6216\u8F6C\u7801\uFF0C\u4F46\u5F53\u524D\u5E73\u53F0 ${process.platform} \u672A\u5B9E\u73B0\u81EA\u52A8\u5904\u7406\u3002`
|
|
2591
|
+
);
|
|
2592
|
+
}
|
|
2593
|
+
const tempDir = await fs5.mkdtemp(path6.join(os2.tmpdir(), "tt-ai-image-"));
|
|
2594
|
+
try {
|
|
2595
|
+
const dimensions = await readImageDimensions(sourcePath);
|
|
2596
|
+
const maxDimension = Math.max(dimensions.width, dimensions.height);
|
|
2597
|
+
const resizeLimits = uniqueNumbers([
|
|
2598
|
+
maxDimension,
|
|
2599
|
+
Math.floor(maxDimension * 0.85),
|
|
2600
|
+
Math.floor(maxDimension * 0.7),
|
|
2601
|
+
Math.floor(maxDimension * 0.55),
|
|
2602
|
+
Math.floor(maxDimension * 0.4)
|
|
2603
|
+
]).filter((value) => value >= 64);
|
|
2604
|
+
const qualityLevels = [85, 75, 65, 55, 45, 35];
|
|
2605
|
+
let attemptIndex = 0;
|
|
2606
|
+
for (const resizeLimit of resizeLimits) {
|
|
2607
|
+
for (const quality of qualityLevels) {
|
|
2608
|
+
const targetPath = path6.join(tempDir, `compressed-${attemptIndex}.jpeg`);
|
|
2609
|
+
attemptIndex += 1;
|
|
2610
|
+
await runSips([
|
|
2611
|
+
"--setProperty",
|
|
2612
|
+
"format",
|
|
2613
|
+
"jpeg",
|
|
2614
|
+
"--setProperty",
|
|
2615
|
+
"formatOptions",
|
|
2616
|
+
String(quality),
|
|
2617
|
+
sourcePath,
|
|
2618
|
+
"--out",
|
|
2619
|
+
targetPath
|
|
2620
|
+
]);
|
|
2621
|
+
if (resizeLimit < maxDimension) {
|
|
2622
|
+
await runSips(["-Z", String(resizeLimit), targetPath]);
|
|
2623
|
+
}
|
|
2624
|
+
const compressedBytes = await fs5.readFile(targetPath);
|
|
2625
|
+
if (compressedBytes.byteLength <= MAX_REFERENCE_IMAGE_BYTES) {
|
|
2626
|
+
return makeOkWith({
|
|
2627
|
+
mimeType: "image/jpeg",
|
|
2628
|
+
bytes: compressedBytes
|
|
2629
|
+
});
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
return makeError(1, `\u53C2\u8003\u56FE\u538B\u7F29\u5931\u8D25\uFF0C\u65E0\u6CD5\u538B\u7F29\u5230 2MB \u4EE5\u5185: ${sourcePath}`);
|
|
2634
|
+
} catch (error) {
|
|
2635
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2636
|
+
return makeError(1, `\u5904\u7406\u53C2\u8003\u56FE\u5931\u8D25: ${sourcePath}: ${message}`);
|
|
2637
|
+
} finally {
|
|
2638
|
+
await fs5.rm(tempDir, { recursive: true, force: true });
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
async function readImageDimensions(sourcePath) {
|
|
2642
|
+
const { stdout } = await runSips([
|
|
2643
|
+
"-g",
|
|
2644
|
+
"pixelWidth",
|
|
2645
|
+
"-g",
|
|
2646
|
+
"pixelHeight",
|
|
2647
|
+
sourcePath
|
|
2648
|
+
]);
|
|
2649
|
+
const width = readSipsMetric(stdout, "pixelWidth");
|
|
2650
|
+
const height = readSipsMetric(stdout, "pixelHeight");
|
|
2651
|
+
if (!width || !height) {
|
|
2652
|
+
throw new Error("\u65E0\u6CD5\u8BFB\u53D6\u56FE\u7247\u5C3A\u5BF8");
|
|
2653
|
+
}
|
|
2654
|
+
return { width, height };
|
|
2655
|
+
}
|
|
2656
|
+
async function runSips(args) {
|
|
2657
|
+
return execFileAsync("/usr/bin/sips", [...args]);
|
|
2658
|
+
}
|
|
2659
|
+
function readSipsMetric(output, key) {
|
|
2660
|
+
const matcher = new RegExp(`${key}:\\s*(\\d+)`);
|
|
2661
|
+
const matched = output.match(matcher);
|
|
2662
|
+
if (!matched) {
|
|
2663
|
+
return void 0;
|
|
2664
|
+
}
|
|
2665
|
+
const value = Number.parseInt(matched[1], 10);
|
|
2666
|
+
return Number.isFinite(value) ? value : void 0;
|
|
2667
|
+
}
|
|
2668
|
+
function uniqueNumbers(values) {
|
|
2669
|
+
return [...new Set(values)];
|
|
2670
|
+
}
|
|
2671
|
+
function toDataUrl(mimeType, fileBytes) {
|
|
2672
|
+
const suffix = mimeType.replace("image/", "");
|
|
2673
|
+
return `data:image/${suffix};base64,${fileBytes.toString("base64")}`;
|
|
2674
|
+
}
|
|
2675
|
+
|
|
2676
|
+
// src/commands/ai/ai-image-command.ts
|
|
2677
|
+
var IMAGE_GENERATION_URL = "https://ark.cn-beijing.volces.com/api/v3/images/generations";
|
|
2678
|
+
var IMAGE_MODEL = "doubao-seedream-5-0-260128";
|
|
2679
|
+
var AiImageCommand = class extends AiBaseCommand {
|
|
2680
|
+
_meta() {
|
|
2681
|
+
return {
|
|
2682
|
+
name: "image",
|
|
2683
|
+
description: "\u8C03\u7528\u8C46\u5305 Seedream \u6A21\u578B\u751F\u6210\u56FE\u7247\u5E76\u4E0B\u8F7D\u5230\u672C\u5730"
|
|
2684
|
+
};
|
|
2685
|
+
}
|
|
2686
|
+
_configureOptions(cmd) {
|
|
2687
|
+
cmd.addOption(
|
|
2688
|
+
new Option8(
|
|
2689
|
+
"-r, --reference <path>",
|
|
2690
|
+
"\u53C2\u8003\u56FE\u8DEF\u5F84\uFF0C\u53EF\u91CD\u590D\u4F20\u5165\uFF0C\u4E5F\u652F\u6301\u7528\u82F1\u6587\u9017\u53F7\u5206\u9694\u591A\u4E2A\u8DEF\u5F84"
|
|
2691
|
+
).argParser(parseReferencePaths).default([])
|
|
2692
|
+
);
|
|
2693
|
+
cmd.addOption(
|
|
2694
|
+
new Option8(
|
|
2695
|
+
"-s, --size <size>",
|
|
2696
|
+
"\u8F93\u51FA\u5C3A\u5BF8\uFF0C\u4F8B\u5982 1024x1024\u30012048x2048\u30012K"
|
|
2697
|
+
).default("2K")
|
|
2698
|
+
);
|
|
2699
|
+
cmd.addOption(
|
|
2700
|
+
new Option8("--output-format <format>", "\u751F\u6210\u56FE\u7247\u7F16\u7801\u683C\u5F0F").choices(["jpeg", "png", "webp"]).default("jpeg")
|
|
2701
|
+
);
|
|
2702
|
+
cmd.addOption(
|
|
2703
|
+
new Option8(
|
|
2704
|
+
"-o, --output <path>",
|
|
2705
|
+
"\u8F93\u51FA\u8DEF\u5F84\uFF0C\u53EF\u4F20\u6587\u4EF6\u8DEF\u5F84\u6216\u76EE\u5F55\u8DEF\u5F84\uFF1B\u672A\u4F20\u65F6\u9ED8\u8BA4\u5199\u5165\u5F53\u524D\u76EE\u5F55\u5E76\u81EA\u52A8\u547D\u540D"
|
|
2706
|
+
)
|
|
2707
|
+
);
|
|
2708
|
+
}
|
|
2709
|
+
_configureArguments(cmd) {
|
|
2710
|
+
cmd.argument("[content...]", "\u751F\u56FE\u63D0\u793A\u8BCD");
|
|
2711
|
+
}
|
|
2712
|
+
async _execute(ctx) {
|
|
2713
|
+
const prompt = this._readPrompt(ctx);
|
|
2714
|
+
if (!prompt) {
|
|
2715
|
+
this._outputJsonError(1, "\u8BF7\u8F93\u5165\u751F\u56FE\u63D0\u793A\u8BCD");
|
|
2716
|
+
return this._makeOk();
|
|
2717
|
+
}
|
|
2718
|
+
const referenceResult = await prepareReferenceImages(ctx.options.reference);
|
|
2719
|
+
if (!referenceResult.ok) {
|
|
2720
|
+
this._outputJsonError(referenceResult.code, referenceResult.msg);
|
|
2721
|
+
return this._makeOk();
|
|
2722
|
+
}
|
|
2723
|
+
const requestBody = {
|
|
2724
|
+
model: IMAGE_MODEL,
|
|
2725
|
+
prompt,
|
|
2726
|
+
size: ctx.options.size ?? "2K",
|
|
2727
|
+
response_format: "url",
|
|
2728
|
+
output_format: ctx.options.outputFormat,
|
|
2729
|
+
watermark: false,
|
|
2730
|
+
...referenceResult.value.length > 0 ? {
|
|
2731
|
+
image: referenceResult.value.map((item) => item.dataUrl)
|
|
2732
|
+
} : {}
|
|
2733
|
+
};
|
|
2734
|
+
const responseResult = await this._requestImage(requestBody);
|
|
2735
|
+
if (!responseResult.ok) {
|
|
2736
|
+
this._outputJsonError(responseResult.code, responseResult.msg);
|
|
2737
|
+
return this._makeOk();
|
|
2738
|
+
}
|
|
2739
|
+
const payload = responseResult.value;
|
|
2740
|
+
const remoteUrl = payload.data?.[0]?.url?.trim();
|
|
2741
|
+
if (!remoteUrl) {
|
|
2742
|
+
this._outputJsonError(1, "\u63A5\u53E3\u8C03\u7528\u6210\u529F\uFF0C\u4F46 data.[0].url \u4E3A\u7A7A");
|
|
2743
|
+
return this._makeOk();
|
|
2744
|
+
}
|
|
2745
|
+
const outputTargetResult = await resolveOutputTarget(
|
|
2746
|
+
ctx.options.output,
|
|
2747
|
+
ctx.options.outputFormat
|
|
2748
|
+
);
|
|
2749
|
+
if (!outputTargetResult.ok) {
|
|
2750
|
+
this._outputJsonError(outputTargetResult.code, outputTargetResult.msg);
|
|
2751
|
+
return this._makeOk();
|
|
2752
|
+
}
|
|
2753
|
+
const saveResult = await downloadImageToFile(
|
|
2754
|
+
remoteUrl,
|
|
2755
|
+
outputTargetResult.value
|
|
2756
|
+
);
|
|
2757
|
+
if (!saveResult.ok) {
|
|
2758
|
+
this._outputJsonError(saveResult.code, saveResult.msg);
|
|
2759
|
+
return this._makeOk();
|
|
2760
|
+
}
|
|
2761
|
+
this._outputJsonOk({
|
|
2762
|
+
image_path: saveResult.value
|
|
2763
|
+
});
|
|
2764
|
+
return this._makeOk();
|
|
2765
|
+
}
|
|
2766
|
+
async _requestImage(requestBody) {
|
|
2767
|
+
const token = process.env.ARK_AK?.trim() || ARK_AK;
|
|
2768
|
+
if (!token) {
|
|
2769
|
+
return makeError(1, "\u7F3A\u5C11 ARK_AK\uFF0C\u8BF7\u5148\u914D\u7F6E\u53EF\u7528\u7684 API Key");
|
|
2770
|
+
}
|
|
2771
|
+
const controller = new AbortController();
|
|
2772
|
+
const timer = setTimeout(() => controller.abort(), 12e4);
|
|
2773
|
+
try {
|
|
2774
|
+
const response = await fetch(IMAGE_GENERATION_URL, {
|
|
2775
|
+
method: "POST",
|
|
2776
|
+
headers: {
|
|
2777
|
+
Authorization: `Bearer ${token}`,
|
|
2778
|
+
"Content-Type": "application/json"
|
|
2779
|
+
},
|
|
2780
|
+
body: JSON.stringify(requestBody),
|
|
2781
|
+
signal: controller.signal
|
|
2782
|
+
});
|
|
2783
|
+
const bodyText = await response.text();
|
|
2784
|
+
const payload = parseJsonSafely(bodyText);
|
|
2785
|
+
if (!response.ok) {
|
|
2786
|
+
const suffix = extractErrorMessage(payload) ?? bodyText.trim();
|
|
2787
|
+
return makeError(
|
|
2788
|
+
response.status,
|
|
2789
|
+
suffix ? `\u751F\u56FE\u63A5\u53E3\u8BF7\u6C42\u5931\u8D25: HTTP ${response.status}: ${suffix}` : `\u751F\u56FE\u63A5\u53E3\u8BF7\u6C42\u5931\u8D25: HTTP ${response.status}`
|
|
2790
|
+
);
|
|
2791
|
+
}
|
|
2792
|
+
if (!payload) {
|
|
2793
|
+
return makeError(1, "\u751F\u56FE\u63A5\u53E3\u8FD4\u56DE\u975E JSON \u54CD\u5E94");
|
|
2794
|
+
}
|
|
2795
|
+
if (hasFailedCode(payload.code)) {
|
|
2796
|
+
return makeError(
|
|
2797
|
+
1,
|
|
2798
|
+
extractErrorMessage(payload) ?? "\u751F\u56FE\u63A5\u53E3\u8FD4\u56DE\u9519\u8BEF"
|
|
2799
|
+
);
|
|
2800
|
+
}
|
|
2801
|
+
return makeOkWith(payload);
|
|
2802
|
+
} catch (error) {
|
|
2803
|
+
const message = error instanceof Error && error.name === "AbortError" ? "\u8BF7\u6C42\u8D85\u65F6" : error instanceof Error ? error.message : String(error);
|
|
2804
|
+
return makeError(1, `\u8C03\u7528\u751F\u56FE\u63A5\u53E3\u5931\u8D25: ${message}`);
|
|
2805
|
+
} finally {
|
|
2806
|
+
clearTimeout(timer);
|
|
2807
|
+
}
|
|
2808
|
+
}
|
|
2809
|
+
};
|
|
2810
|
+
async function resolveOutputTarget(outputPath, outputFormat) {
|
|
2811
|
+
if (!outputPath) {
|
|
2812
|
+
const directoryPath = process.cwd();
|
|
2813
|
+
const filePath = path7.join(directoryPath, buildAutoFileName(outputFormat));
|
|
2814
|
+
return makeOkWith({
|
|
2815
|
+
directoryPath,
|
|
2816
|
+
filePath,
|
|
2817
|
+
autoNamed: true
|
|
2818
|
+
});
|
|
2819
|
+
}
|
|
2820
|
+
const resolvedPath = path7.resolve(process.cwd(), outputPath);
|
|
2821
|
+
try {
|
|
2822
|
+
const stats = await fs6.stat(resolvedPath);
|
|
2823
|
+
if (stats.isDirectory()) {
|
|
2824
|
+
return makeOkWith({
|
|
2825
|
+
directoryPath: resolvedPath,
|
|
2826
|
+
filePath: path7.join(resolvedPath, buildAutoFileName(outputFormat)),
|
|
2827
|
+
autoNamed: true
|
|
2828
|
+
});
|
|
2829
|
+
}
|
|
2830
|
+
return makeOkWith({
|
|
2831
|
+
directoryPath: path7.dirname(resolvedPath),
|
|
2832
|
+
filePath: resolvedPath,
|
|
2833
|
+
autoNamed: false
|
|
2834
|
+
});
|
|
2835
|
+
} catch (error) {
|
|
2836
|
+
const nodeError = error;
|
|
2837
|
+
if (nodeError.code !== "ENOENT") {
|
|
2838
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2839
|
+
return makeError(1, `\u8BFB\u53D6\u8F93\u51FA\u8DEF\u5F84\u5931\u8D25: ${resolvedPath}: ${message}`);
|
|
2840
|
+
}
|
|
2841
|
+
if (path7.extname(resolvedPath)) {
|
|
2842
|
+
return makeOkWith({
|
|
2843
|
+
directoryPath: path7.dirname(resolvedPath),
|
|
2844
|
+
filePath: resolvedPath,
|
|
2845
|
+
autoNamed: false
|
|
2846
|
+
});
|
|
2847
|
+
}
|
|
2848
|
+
return makeOkWith({
|
|
2849
|
+
directoryPath: resolvedPath,
|
|
2850
|
+
filePath: path7.join(resolvedPath, buildAutoFileName(outputFormat)),
|
|
2851
|
+
autoNamed: true
|
|
2852
|
+
});
|
|
2853
|
+
}
|
|
2854
|
+
}
|
|
2855
|
+
async function downloadImageToFile(remoteUrl, target) {
|
|
2856
|
+
try {
|
|
2857
|
+
await fs6.mkdir(target.directoryPath, { recursive: true });
|
|
2858
|
+
} catch (error) {
|
|
2859
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2860
|
+
return makeError(
|
|
2861
|
+
1,
|
|
2862
|
+
`\u521B\u5EFA\u8F93\u51FA\u76EE\u5F55\u5931\u8D25: ${target.directoryPath}: ${message}`
|
|
2863
|
+
);
|
|
2864
|
+
}
|
|
2865
|
+
let response;
|
|
2866
|
+
try {
|
|
2867
|
+
response = await fetch(remoteUrl);
|
|
2868
|
+
} catch (error) {
|
|
2869
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2870
|
+
return makeError(1, `\u4E0B\u8F7D\u56FE\u7247\u5931\u8D25: ${message}`);
|
|
2871
|
+
}
|
|
2872
|
+
if (!response.ok) {
|
|
2873
|
+
return makeError(response.status, `\u4E0B\u8F7D\u56FE\u7247\u5931\u8D25: HTTP ${response.status}`);
|
|
2874
|
+
}
|
|
2875
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
2876
|
+
const targetPath = target.autoNamed ? replaceFileExtension(
|
|
2877
|
+
target.filePath,
|
|
2878
|
+
inferImageExtension(remoteUrl, response)
|
|
2879
|
+
) : target.filePath;
|
|
2880
|
+
try {
|
|
2881
|
+
await fs6.writeFile(targetPath, bytes);
|
|
2882
|
+
} catch (error) {
|
|
2883
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2884
|
+
return makeError(1, `\u5199\u5165\u56FE\u7247\u5931\u8D25: ${targetPath}: ${message}`);
|
|
2885
|
+
}
|
|
2886
|
+
return makeOkWith(path7.resolve(targetPath));
|
|
2887
|
+
}
|
|
2888
|
+
function parseReferencePaths(value, previous) {
|
|
2889
|
+
return previous.concat(
|
|
2890
|
+
value.split(",").map((item) => item.trim()).filter((item) => item.length > 0)
|
|
2891
|
+
);
|
|
2892
|
+
}
|
|
2893
|
+
function parseJsonSafely(text) {
|
|
2894
|
+
if (!text.trim()) {
|
|
2895
|
+
return void 0;
|
|
2896
|
+
}
|
|
2897
|
+
try {
|
|
2898
|
+
return JSON.parse(text);
|
|
2899
|
+
} catch {
|
|
2900
|
+
return void 0;
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
function hasFailedCode(code) {
|
|
2904
|
+
if (code === void 0 || code === null) {
|
|
2905
|
+
return false;
|
|
2906
|
+
}
|
|
2907
|
+
if (typeof code === "number") {
|
|
2908
|
+
return code !== 0;
|
|
2909
|
+
}
|
|
2910
|
+
const normalized = code.trim();
|
|
2911
|
+
return normalized !== "0" && normalized !== "";
|
|
2912
|
+
}
|
|
2913
|
+
function extractErrorMessage(payload) {
|
|
2914
|
+
if (!payload) {
|
|
2915
|
+
return void 0;
|
|
2916
|
+
}
|
|
2917
|
+
const message = payload.msg?.trim() || payload.message?.trim();
|
|
2918
|
+
return message || void 0;
|
|
2919
|
+
}
|
|
2920
|
+
function buildAutoFileName(outputFormat) {
|
|
2921
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2922
|
+
return `ai-image-${timestamp}.${outputFormat}`;
|
|
2923
|
+
}
|
|
2924
|
+
function replaceFileExtension(filePath, extension) {
|
|
2925
|
+
const ext = path7.extname(filePath);
|
|
2926
|
+
if (!ext) {
|
|
2927
|
+
return `${filePath}.${extension}`;
|
|
2928
|
+
}
|
|
2929
|
+
return `${filePath.slice(0, -ext.length)}.${extension}`;
|
|
2930
|
+
}
|
|
2931
|
+
function inferImageExtension(remoteUrl, response) {
|
|
2932
|
+
const contentType = response.headers.get("content-type")?.toLowerCase() ?? "";
|
|
2933
|
+
if (contentType.includes("png")) {
|
|
2934
|
+
return "png";
|
|
2935
|
+
}
|
|
2936
|
+
if (contentType.includes("webp")) {
|
|
2937
|
+
return "webp";
|
|
2938
|
+
}
|
|
2939
|
+
if (contentType.includes("jpeg") || contentType.includes("jpg")) {
|
|
2940
|
+
return "jpeg";
|
|
2941
|
+
}
|
|
2942
|
+
try {
|
|
2943
|
+
const url = new URL(remoteUrl);
|
|
2944
|
+
const ext = path7.extname(url.pathname).toLowerCase();
|
|
2945
|
+
if (ext === ".png") {
|
|
2946
|
+
return "png";
|
|
2947
|
+
}
|
|
2948
|
+
if (ext === ".webp") {
|
|
2949
|
+
return "webp";
|
|
2950
|
+
}
|
|
2951
|
+
if (ext === ".jpg" || ext === ".jpeg") {
|
|
2952
|
+
return "jpeg";
|
|
2953
|
+
}
|
|
2954
|
+
} catch {
|
|
2955
|
+
}
|
|
2956
|
+
return "jpeg";
|
|
2957
|
+
}
|
|
2958
|
+
|
|
2959
|
+
// src/commands/ai/ai-video-command.ts
|
|
2960
|
+
import * as path8 from "path";
|
|
2961
|
+
import { Option as Option9 } from "commander";
|
|
2962
|
+
|
|
2963
|
+
// src/bedrock/uuid/uuid.ts
|
|
2964
|
+
var generateUuid = (() => {
|
|
2965
|
+
if (typeof crypto === "object" && typeof crypto.randomUUID === "function") {
|
|
2966
|
+
return crypto.randomUUID.bind(crypto);
|
|
2967
|
+
}
|
|
2968
|
+
let getRandomValues;
|
|
2969
|
+
if (typeof crypto === "object" && typeof crypto.getRandomValues === "function") {
|
|
2970
|
+
getRandomValues = crypto.getRandomValues.bind(crypto);
|
|
2971
|
+
} else {
|
|
2972
|
+
getRandomValues = function(bucket) {
|
|
2973
|
+
for (let i = 0; i < bucket.length; i++) {
|
|
2974
|
+
bucket[i] = Math.floor(Math.random() * 256);
|
|
2975
|
+
}
|
|
2976
|
+
return bucket;
|
|
2977
|
+
};
|
|
2978
|
+
}
|
|
2979
|
+
const data = new Uint8Array(16);
|
|
2980
|
+
const hex = [];
|
|
2981
|
+
for (let i = 0; i < 256; i++) {
|
|
2982
|
+
hex.push(i.toString(16).padStart(2, "0"));
|
|
2983
|
+
}
|
|
2984
|
+
return () => {
|
|
2985
|
+
getRandomValues(data);
|
|
2986
|
+
data[6] = data[6] & 15 | 64;
|
|
2987
|
+
data[8] = data[8] & 63 | 128;
|
|
2988
|
+
let i = 0;
|
|
2989
|
+
let result = "";
|
|
2990
|
+
result += hex[data[i++]];
|
|
2991
|
+
result += hex[data[i++]];
|
|
2992
|
+
result += hex[data[i++]];
|
|
2993
|
+
result += hex[data[i++]];
|
|
2994
|
+
result += "-";
|
|
2995
|
+
result += hex[data[i++]];
|
|
2996
|
+
result += hex[data[i++]];
|
|
2997
|
+
result += "-";
|
|
2998
|
+
result += hex[data[i++]];
|
|
2999
|
+
result += hex[data[i++]];
|
|
3000
|
+
result += "-";
|
|
3001
|
+
result += hex[data[i++]];
|
|
3002
|
+
result += hex[data[i++]];
|
|
3003
|
+
result += "-";
|
|
3004
|
+
result += hex[data[i++]];
|
|
3005
|
+
result += hex[data[i++]];
|
|
3006
|
+
result += hex[data[i++]];
|
|
3007
|
+
result += hex[data[i++]];
|
|
3008
|
+
result += hex[data[i++]];
|
|
3009
|
+
result += hex[data[i++]];
|
|
3010
|
+
return result;
|
|
3011
|
+
};
|
|
3012
|
+
})();
|
|
3013
|
+
|
|
3014
|
+
// src/commands/pippit/modules/submit-direct/submit-direct-cn.ts
|
|
3015
|
+
var SUBMIT_DIRECT_URL = "https://xyq.jianying.com/api/biz/v1/agent/submit_run";
|
|
3016
|
+
function normalizeToken4(token) {
|
|
3017
|
+
const trimmed = token.trim();
|
|
3018
|
+
const prefix = "sessionid_pippitcn_web=";
|
|
3019
|
+
if (trimmed.startsWith(prefix)) {
|
|
3020
|
+
return trimmed.slice(prefix.length).trim();
|
|
3021
|
+
}
|
|
3022
|
+
return trimmed;
|
|
3023
|
+
}
|
|
3024
|
+
function createCookieHeader3(token) {
|
|
3025
|
+
return `sessionid_pippitcn_web=${normalizeToken4(token)}`;
|
|
3026
|
+
}
|
|
3027
|
+
function parseErrorCode2(ret) {
|
|
3028
|
+
const parsed = typeof ret === "number" ? ret : typeof ret === "string" ? Number.parseInt(ret, 10) : Number.NaN;
|
|
3029
|
+
return Number.isFinite(parsed) ? parsed : 1;
|
|
3030
|
+
}
|
|
3031
|
+
function createUserInfo() {
|
|
3032
|
+
return readWebContext("cn" /* CN */).then((webContextResult) => {
|
|
3033
|
+
if (!webContextResult.ok) {
|
|
3034
|
+
return webContextResult;
|
|
3035
|
+
}
|
|
3036
|
+
const webContext = webContextResult.value;
|
|
3037
|
+
if (!webContext.uid || !webContext.workspaceId || !webContext.spaceId) {
|
|
3038
|
+
return missingWebContextError();
|
|
3039
|
+
}
|
|
3040
|
+
return makeOkWith({
|
|
3041
|
+
uid: webContext.uid,
|
|
3042
|
+
workspace_id: webContext.workspaceId,
|
|
3043
|
+
space_id: webContext.spaceId
|
|
3044
|
+
});
|
|
3045
|
+
});
|
|
3046
|
+
}
|
|
3047
|
+
async function submitDirectCn(options) {
|
|
3048
|
+
const userInfoResult = await createUserInfo();
|
|
3049
|
+
if (!userInfoResult.ok) {
|
|
3050
|
+
return userInfoResult;
|
|
3051
|
+
}
|
|
3052
|
+
const { durationSec, imageAssetIds, prompt } = options;
|
|
3053
|
+
const tokenResult = await readWebToken("cn" /* CN */);
|
|
3054
|
+
if (!tokenResult.ok) {
|
|
3055
|
+
return tokenResult;
|
|
3056
|
+
}
|
|
3057
|
+
const token = tokenResult.value?.trim();
|
|
3058
|
+
if (!token) {
|
|
3059
|
+
return missingWebTokenError();
|
|
3060
|
+
}
|
|
3061
|
+
const threadId = generateUuid();
|
|
3062
|
+
const runId = generateUuid();
|
|
3063
|
+
let duration = 5;
|
|
3064
|
+
if (durationSec && durationSec <= 8 && durationSec >= 2) {
|
|
3065
|
+
duration = Math.round(durationSec);
|
|
3066
|
+
}
|
|
3067
|
+
const message = {
|
|
3068
|
+
message_id: "",
|
|
3069
|
+
role: "user",
|
|
3070
|
+
thread_id: threadId,
|
|
3071
|
+
run_id: runId,
|
|
3072
|
+
created_at: Date.now(),
|
|
3073
|
+
content: [
|
|
3074
|
+
{
|
|
3075
|
+
type: "data",
|
|
3076
|
+
sub_type: "biz/x_data_direct_tool_call_req",
|
|
3077
|
+
data: JSON.stringify({
|
|
3078
|
+
param: JSON.stringify({
|
|
3079
|
+
prompt,
|
|
3080
|
+
images: [
|
|
3081
|
+
imageAssetIds?.map((assetId) => ({
|
|
3082
|
+
asset_id: assetId
|
|
3083
|
+
}))
|
|
3084
|
+
],
|
|
3085
|
+
duration_sec: duration,
|
|
3086
|
+
language: "zh",
|
|
3087
|
+
resolution: "720p",
|
|
3088
|
+
imitation_videos: [],
|
|
3089
|
+
videos: [],
|
|
3090
|
+
audios: [],
|
|
3091
|
+
model: "seedance2.0_vision"
|
|
3092
|
+
}),
|
|
3093
|
+
tool_name: "biz/x_tool_name_video_part"
|
|
3094
|
+
}),
|
|
3095
|
+
hidden: false,
|
|
3096
|
+
is_thought: false
|
|
3097
|
+
}
|
|
3098
|
+
]
|
|
3099
|
+
};
|
|
3100
|
+
const userInfo = {
|
|
3101
|
+
app_id: "795647",
|
|
3102
|
+
consumer_uid: userInfoResult.value.uid,
|
|
3103
|
+
workspace_id: userInfoResult.value.workspace_id,
|
|
3104
|
+
space_id: userInfoResult.value.space_id
|
|
3105
|
+
};
|
|
3106
|
+
const responseResult = await requestJson(
|
|
3107
|
+
SUBMIT_DIRECT_URL,
|
|
3108
|
+
{
|
|
3109
|
+
method: "POST",
|
|
3110
|
+
headers: {
|
|
3111
|
+
accept: "application/json, text/plain, */*",
|
|
3112
|
+
"content-type": "application/json",
|
|
3113
|
+
cookie: createCookieHeader3(token),
|
|
3114
|
+
Referer: "https://xyq.jianying.com/"
|
|
3115
|
+
},
|
|
3116
|
+
body: JSON.stringify({
|
|
3117
|
+
user_info: userInfo,
|
|
3118
|
+
message,
|
|
3119
|
+
agent_name: "pippit_video_part_agent",
|
|
3120
|
+
entrance_from: "web",
|
|
3121
|
+
run_extra: "{}"
|
|
3122
|
+
})
|
|
3123
|
+
},
|
|
3124
|
+
{
|
|
3125
|
+
networkRequestFailed: (message2) => networkRequestFailedError3(message2),
|
|
3126
|
+
responseParseFailed: (message2) => responseParseFailedError2(message2)
|
|
3127
|
+
}
|
|
3128
|
+
);
|
|
3129
|
+
if (!responseResult.ok) {
|
|
3130
|
+
return responseResult;
|
|
3131
|
+
}
|
|
3132
|
+
const response = responseResult.value;
|
|
3133
|
+
console.log("=====response", response);
|
|
3134
|
+
if (String(response.ret) !== "0") {
|
|
3135
|
+
return makeError(
|
|
3136
|
+
parseErrorCode2(response.ret),
|
|
3137
|
+
response.errmsg?.trim() || "\u76F4\u63A5\u63D0\u4EA4\u5931\u8D25\u3002"
|
|
3138
|
+
);
|
|
3139
|
+
}
|
|
3140
|
+
return makeOkWith(response.data);
|
|
3141
|
+
}
|
|
3142
|
+
|
|
3143
|
+
// src/commands/ai/ai-video-command.ts
|
|
3144
|
+
var AiVideoCommand = class extends AiBaseCommand {
|
|
3145
|
+
_meta() {
|
|
3146
|
+
return {
|
|
3147
|
+
name: "video",
|
|
3148
|
+
description: "\u4E0A\u4F20\u53C2\u8003\u7D20\u6750\u5E76\u8C03\u7528\u89C6\u9891\u751F\u6210\u63A5\u53E3"
|
|
3149
|
+
};
|
|
3150
|
+
}
|
|
3151
|
+
_configureOptions(cmd) {
|
|
3152
|
+
cmd.addOption(
|
|
3153
|
+
new Option9(
|
|
3154
|
+
"-r, --reference <path>",
|
|
3155
|
+
"\u53C2\u8003\u56FE\u7247\u6216\u89C6\u9891\u8DEF\u5F84\uFF0C\u53EF\u91CD\u590D\u4F20\u5165\uFF0C\u4E5F\u652F\u6301\u7528\u82F1\u6587\u9017\u53F7\u5206\u9694\u591A\u4E2A\u8DEF\u5F84"
|
|
3156
|
+
).argParser(parseReferencePaths2).default([])
|
|
3157
|
+
);
|
|
3158
|
+
}
|
|
3159
|
+
_configureArguments(cmd) {
|
|
3160
|
+
cmd.argument("[content...]", "\u89C6\u9891\u751F\u6210\u63D0\u793A\u8BCD");
|
|
3161
|
+
}
|
|
3162
|
+
async _execute(ctx) {
|
|
3163
|
+
const prompt = this._readPrompt(ctx);
|
|
3164
|
+
if (!prompt) {
|
|
3165
|
+
this._outputJsonError(1, "\u8BF7\u8F93\u5165\u89C6\u9891\u751F\u6210\u63D0\u793A\u8BCD");
|
|
3166
|
+
return this._makeOk();
|
|
3167
|
+
}
|
|
3168
|
+
const uploadResult = await this._uploadReferences(ctx.options.reference);
|
|
3169
|
+
if (!uploadResult.ok) {
|
|
3170
|
+
this._outputJsonError(uploadResult.code, uploadResult.msg);
|
|
3171
|
+
return this._makeOk();
|
|
3172
|
+
}
|
|
3173
|
+
const generationResult = await this._requestVideoGeneration(
|
|
3174
|
+
prompt,
|
|
3175
|
+
uploadResult.value
|
|
3176
|
+
);
|
|
3177
|
+
if (!generationResult.ok) {
|
|
3178
|
+
this._outputJsonError(generationResult.code, generationResult.msg);
|
|
3179
|
+
return this._makeOk();
|
|
3180
|
+
}
|
|
3181
|
+
this._outputJsonOk({
|
|
3182
|
+
prompt,
|
|
3183
|
+
assets: uploadResult.value,
|
|
3184
|
+
generation: generationResult.value
|
|
3185
|
+
});
|
|
3186
|
+
return this._makeOk();
|
|
3187
|
+
}
|
|
3188
|
+
async _uploadReferences(references) {
|
|
3189
|
+
if (references.length === 0) {
|
|
3190
|
+
return makeOkWith([]);
|
|
3191
|
+
}
|
|
3192
|
+
const uploadResults = await Promise.all(
|
|
3193
|
+
references.map(async (referencePath) => {
|
|
3194
|
+
const result = await uploadAsset({
|
|
3195
|
+
filePath: referencePath,
|
|
3196
|
+
region: "cn" /* CN */
|
|
3197
|
+
});
|
|
3198
|
+
if (!result.ok) {
|
|
3199
|
+
return result;
|
|
3200
|
+
}
|
|
3201
|
+
return makeOkWith({
|
|
3202
|
+
asset_id: result.value.assetId,
|
|
3203
|
+
asset_type: result.value.fileInfo.assetType,
|
|
3204
|
+
file_path: path8.resolve(process.cwd(), referencePath),
|
|
3205
|
+
region: result.value.region
|
|
3206
|
+
});
|
|
3207
|
+
})
|
|
3208
|
+
);
|
|
3209
|
+
for (const result of uploadResults) {
|
|
3210
|
+
if (!result.ok) {
|
|
3211
|
+
return result;
|
|
3212
|
+
}
|
|
3213
|
+
}
|
|
3214
|
+
return makeOkWith(uploadResults.map((result) => result.value));
|
|
3215
|
+
}
|
|
3216
|
+
async _requestVideoGeneration(prompt, assets) {
|
|
3217
|
+
return submitDirectCn({
|
|
3218
|
+
prompt,
|
|
3219
|
+
imageAssetIds: assets.map((asset) => asset.asset_id),
|
|
3220
|
+
durationSec: 5
|
|
3221
|
+
});
|
|
3222
|
+
}
|
|
3223
|
+
};
|
|
3224
|
+
function parseReferencePaths2(value, previous) {
|
|
3225
|
+
return previous.concat(
|
|
3226
|
+
value.split(",").map((item) => item.trim()).filter((item) => item.length > 0)
|
|
3227
|
+
);
|
|
3228
|
+
}
|
|
3229
|
+
|
|
3230
|
+
// src/commands/ai/ai-vid-command.ts
|
|
3231
|
+
import * as fs7 from "fs/promises";
|
|
3232
|
+
import * as path9 from "path";
|
|
3233
|
+
import { Option as Option10 } from "commander";
|
|
3234
|
+
var VIDEO_GENERATION_URL = "https://openrouter.ai/api/v1/videos";
|
|
3235
|
+
var VIDEO_MODEL = "bytedance/seedance-2.0";
|
|
3236
|
+
var POLLING_LOG_FILE_NAME = "ai-vid-polling.log";
|
|
3237
|
+
var POLL_INTERVAL_MS = 3e3;
|
|
3238
|
+
var POLL_STATUS_LOG_INTERVAL_MS = 1e4;
|
|
3239
|
+
var POLL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
3240
|
+
var SUBMIT_TIMEOUT_MS = 3e4;
|
|
3241
|
+
var AiVidCommand = class extends AiBaseCommand {
|
|
3242
|
+
_meta() {
|
|
3243
|
+
return {
|
|
3244
|
+
name: "vid",
|
|
3245
|
+
description: "\u901A\u8FC7 OpenRouter \u8C03\u7528 bytedance/seedance-2.0 \u751F\u6210\u89C6\u9891"
|
|
3246
|
+
};
|
|
3247
|
+
}
|
|
3248
|
+
_configureOptions(cmd) {
|
|
3249
|
+
cmd.addOption(
|
|
3250
|
+
new Option10(
|
|
3251
|
+
"-r, --reference <path>",
|
|
3252
|
+
"\u53C2\u8003\u56FE\u7247\u672C\u5730\u8DEF\u5F84\uFF0C\u53EF\u91CD\u590D\u4F20\u5165\uFF0C\u4E5F\u652F\u6301\u7528\u82F1\u6587\u9017\u53F7\u5206\u9694\u591A\u4E2A\u8DEF\u5F84\uFF1B\u6700\u7EC8\u8F6C\u4E3A base64 data URL"
|
|
3253
|
+
).argParser(parseReferencePaths3).default([])
|
|
3254
|
+
);
|
|
3255
|
+
cmd.addOption(
|
|
3256
|
+
new Option10("--resolution <resolution>", "\u89C6\u9891\u5206\u8FA8\u7387").choices(["480p", "720p"]).default("480p")
|
|
3257
|
+
);
|
|
3258
|
+
cmd.addOption(
|
|
3259
|
+
new Option10(
|
|
3260
|
+
"--aspect-ratio <ratio>",
|
|
3261
|
+
"\u89C6\u9891\u957F\u5BBD\u6BD4\uFF0C\u4F8B\u5982 16:9\u30019:16\u30011:1\uFF0C\u7F3A\u7701\u4E0D\u6307\u5B9A"
|
|
3262
|
+
)
|
|
3263
|
+
);
|
|
3264
|
+
cmd.addOption(
|
|
3265
|
+
new Option10("--duration <seconds>", "\u89C6\u9891\u65F6\u957F\uFF08\u79D2\uFF09\uFF0C\u7F3A\u7701\u4E0D\u6307\u5B9A").argParser(
|
|
3266
|
+
parseDuration
|
|
3267
|
+
)
|
|
3268
|
+
);
|
|
3269
|
+
cmd.addOption(
|
|
3270
|
+
new Option10(
|
|
3271
|
+
"--polling-only",
|
|
3272
|
+
"\u4EC5\u63D0\u4EA4\u5E76\u8FD4\u56DE polling_url\uFF0C\u4E0D\u5728\u672C\u5730\u8F6E\u8BE2\u7ED3\u679C"
|
|
3273
|
+
).default(false)
|
|
3274
|
+
);
|
|
3275
|
+
cmd.addOption(
|
|
3276
|
+
new Option10(
|
|
3277
|
+
"-o, --output <path>",
|
|
3278
|
+
"\u89C6\u9891\u4E0B\u8F7D\u8F93\u51FA\u8DEF\u5F84\uFF0C\u53EF\u4F20\u6587\u4EF6\u8DEF\u5F84\u6216\u76EE\u5F55\u8DEF\u5F84\uFF1B\u672A\u4F20\u65F6\u9ED8\u8BA4\u5199\u5165\u5F53\u524D\u76EE\u5F55\u5E76\u81EA\u52A8\u547D\u540D"
|
|
3279
|
+
)
|
|
3280
|
+
);
|
|
3281
|
+
}
|
|
3282
|
+
_configureArguments(cmd) {
|
|
3283
|
+
cmd.argument("[content...]", "\u89C6\u9891\u751F\u6210\u63D0\u793A\u8BCD");
|
|
3284
|
+
}
|
|
3285
|
+
async _execute(ctx) {
|
|
3286
|
+
const prompt = this._readPrompt(ctx);
|
|
3287
|
+
if (!prompt) {
|
|
3288
|
+
this._outputJsonError(1, "\u8BF7\u8F93\u5165\u89C6\u9891\u751F\u6210\u63D0\u793A\u8BCD");
|
|
3289
|
+
return this._makeOk();
|
|
3290
|
+
}
|
|
3291
|
+
const referenceResult = await prepareReferenceImages(ctx.options.reference);
|
|
3292
|
+
if (!referenceResult.ok) {
|
|
3293
|
+
this._outputJsonError(referenceResult.code, referenceResult.msg);
|
|
3294
|
+
return this._makeOk();
|
|
3295
|
+
}
|
|
3296
|
+
const requestBody = {
|
|
3297
|
+
model: VIDEO_MODEL,
|
|
3298
|
+
prompt,
|
|
3299
|
+
resolution: ctx.options.resolution
|
|
3300
|
+
};
|
|
3301
|
+
if (ctx.options.aspectRatio) {
|
|
3302
|
+
requestBody.aspect_ratio = ctx.options.aspectRatio;
|
|
3303
|
+
}
|
|
3304
|
+
if (typeof ctx.options.duration === "number") {
|
|
3305
|
+
requestBody.duration = ctx.options.duration;
|
|
3306
|
+
}
|
|
3307
|
+
if (referenceResult.value.length > 0) {
|
|
3308
|
+
requestBody.input_references = referenceResult.value.map((item) => ({
|
|
3309
|
+
type: "image_url",
|
|
3310
|
+
image_url: { url: item.dataUrl }
|
|
3311
|
+
}));
|
|
3312
|
+
}
|
|
3313
|
+
const submitResult = await this._submitGeneration(requestBody);
|
|
3314
|
+
if (!submitResult.ok) {
|
|
3315
|
+
this._outputJsonError(submitResult.code, submitResult.msg);
|
|
3316
|
+
return this._makeOk();
|
|
3317
|
+
}
|
|
3318
|
+
const submitPayload = submitResult.value;
|
|
3319
|
+
const pollingUrl = submitPayload.polling_url?.trim();
|
|
3320
|
+
if (!pollingUrl) {
|
|
3321
|
+
this._outputJsonError(1, "\u63D0\u4EA4\u6210\u529F\u4F46\u8FD4\u56DE\u6570\u636E\u7F3A\u5C11 polling_url");
|
|
3322
|
+
return this._makeOk();
|
|
3323
|
+
}
|
|
3324
|
+
const logPathResult = await appendPollingUrl(pollingUrl, submitPayload.id);
|
|
3325
|
+
const pollingLogPath = logPathResult.ok ? logPathResult.value : void 0;
|
|
3326
|
+
if (!logPathResult.ok) {
|
|
3327
|
+
this._debug(`\u8BB0\u5F55 polling_url \u5931\u8D25: ${logPathResult.msg}`);
|
|
3328
|
+
}
|
|
3329
|
+
if (ctx.options.pollingOnly) {
|
|
3330
|
+
this._outputJsonOk({
|
|
3331
|
+
polling_url: pollingUrl,
|
|
3332
|
+
generation_id: submitPayload.id,
|
|
3333
|
+
polling_log_path: pollingLogPath
|
|
3334
|
+
});
|
|
3335
|
+
return this._makeOk();
|
|
3336
|
+
}
|
|
3337
|
+
const pollResult = await this._pollUntilComplete(pollingUrl);
|
|
3338
|
+
if (!pollResult.ok) {
|
|
3339
|
+
this._outputJsonError(pollResult.code, pollResult.msg);
|
|
3340
|
+
return this._makeOk();
|
|
3341
|
+
}
|
|
3342
|
+
const videoUrl = pollResult.value.unsigned_urls?.[0];
|
|
3343
|
+
if (!videoUrl) {
|
|
3344
|
+
this._outputJsonError(1, "\u89C6\u9891\u751F\u6210\u5B8C\u6210\uFF0C\u4F46\u672A\u62FF\u5230 unsigned_urls[0]");
|
|
3345
|
+
return this._makeOk();
|
|
3346
|
+
}
|
|
3347
|
+
const outputTargetResult = await resolveOutputTarget2(ctx.options.output);
|
|
3348
|
+
if (!outputTargetResult.ok) {
|
|
3349
|
+
this._outputJsonError(outputTargetResult.code, outputTargetResult.msg);
|
|
3350
|
+
return this._makeOk();
|
|
3351
|
+
}
|
|
3352
|
+
const downloadResult = await downloadVideoToFile(
|
|
3353
|
+
videoUrl,
|
|
3354
|
+
outputTargetResult.value
|
|
3355
|
+
);
|
|
3356
|
+
if (!downloadResult.ok) {
|
|
3357
|
+
this._outputJsonError(downloadResult.code, downloadResult.msg);
|
|
3358
|
+
return this._makeOk();
|
|
3359
|
+
}
|
|
3360
|
+
this._outputJsonOk({
|
|
3361
|
+
video_path: downloadResult.value,
|
|
3362
|
+
video_url: videoUrl,
|
|
3363
|
+
polling_url: pollingUrl,
|
|
3364
|
+
generation_id: submitPayload.id,
|
|
3365
|
+
polling_log_path: pollingLogPath
|
|
3366
|
+
});
|
|
3367
|
+
return this._makeOk();
|
|
3368
|
+
}
|
|
3369
|
+
async _submitGeneration(requestBody) {
|
|
3370
|
+
const token = process.env.OPENROUTER_AK?.trim() || OPENROUTER_AK;
|
|
3371
|
+
if (!token) {
|
|
3372
|
+
return makeError(1, "\u7F3A\u5C11 OPENROUTER_AK\uFF0C\u8BF7\u5148\u914D\u7F6E\u53EF\u7528\u7684 API Key");
|
|
3373
|
+
}
|
|
3374
|
+
const controller = new AbortController();
|
|
3375
|
+
const timer = setTimeout(() => controller.abort(), SUBMIT_TIMEOUT_MS);
|
|
3376
|
+
let response;
|
|
3377
|
+
try {
|
|
3378
|
+
response = await fetch(VIDEO_GENERATION_URL, {
|
|
3379
|
+
method: "POST",
|
|
3380
|
+
headers: {
|
|
3381
|
+
Authorization: `Bearer ${token}`,
|
|
3382
|
+
"Content-Type": "application/json"
|
|
3383
|
+
},
|
|
3384
|
+
body: JSON.stringify(requestBody),
|
|
3385
|
+
signal: controller.signal
|
|
3386
|
+
});
|
|
3387
|
+
} catch (error) {
|
|
3388
|
+
const message = error instanceof Error && error.name === "AbortError" ? "\u8BF7\u6C42\u8D85\u65F6" : error instanceof Error ? error.message : String(error);
|
|
3389
|
+
return makeError(1, `\u63D0\u4EA4\u89C6\u9891\u751F\u6210\u8BF7\u6C42\u5931\u8D25: ${message}`);
|
|
3390
|
+
} finally {
|
|
3391
|
+
clearTimeout(timer);
|
|
3392
|
+
}
|
|
3393
|
+
const bodyText = await response.text().catch(() => "");
|
|
3394
|
+
const payload = parseJsonSafely2(bodyText);
|
|
3395
|
+
if (!response.ok) {
|
|
3396
|
+
const detail = extractErrorText(payload) ?? bodyText.trim();
|
|
3397
|
+
const suffix = detail ? `: ${detail}` : "";
|
|
3398
|
+
return makeError(
|
|
3399
|
+
response.status,
|
|
3400
|
+
`\u89C6\u9891\u751F\u6210\u8BF7\u6C42\u5931\u8D25: HTTP ${response.status}${suffix}`
|
|
3401
|
+
);
|
|
3402
|
+
}
|
|
3403
|
+
if (!payload) {
|
|
3404
|
+
return makeError(1, "\u89C6\u9891\u751F\u6210\u63A5\u53E3\u8FD4\u56DE\u975E JSON \u54CD\u5E94");
|
|
3405
|
+
}
|
|
3406
|
+
if (payload.error) {
|
|
3407
|
+
return makeError(1, `\u89C6\u9891\u751F\u6210\u8BF7\u6C42\u88AB\u62D2\u7EDD: ${payload.error}`);
|
|
3408
|
+
}
|
|
3409
|
+
if (!payload.id || !payload.polling_url) {
|
|
3410
|
+
return makeError(
|
|
3411
|
+
1,
|
|
3412
|
+
`\u89C6\u9891\u751F\u6210\u63A5\u53E3\u8FD4\u56DE\u6570\u636E\u5F02\u5E38: ${bodyText.slice(0, 500)}`
|
|
3413
|
+
);
|
|
3414
|
+
}
|
|
3415
|
+
return makeOkWith(payload);
|
|
3416
|
+
}
|
|
3417
|
+
async _pollUntilComplete(pollingUrl) {
|
|
3418
|
+
const token = process.env.OPENROUTER_AK?.trim() || OPENROUTER_AK;
|
|
3419
|
+
const startedAt = Date.now();
|
|
3420
|
+
let lastStatusLogAt = 0;
|
|
3421
|
+
while (true) {
|
|
3422
|
+
const elapsed = Date.now() - startedAt;
|
|
3423
|
+
if (elapsed >= POLL_TIMEOUT_MS) {
|
|
3424
|
+
return makeError(
|
|
3425
|
+
1,
|
|
3426
|
+
`\u8F6E\u8BE2\u8D85\u65F6\uFF0C\u8D85\u8FC7 ${Math.round(POLL_TIMEOUT_MS / 1e3)}s \u4ECD\u672A\u5B8C\u6210\uFF0C\u53EF\u4F7F\u7528 --polling-only \u62FF\u5230 polling_url \u540E\u7A0D\u540E\u91CD\u8BD5`
|
|
3427
|
+
);
|
|
3428
|
+
}
|
|
3429
|
+
let response;
|
|
3430
|
+
try {
|
|
3431
|
+
response = await fetch(pollingUrl, {
|
|
3432
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
3433
|
+
});
|
|
3434
|
+
} catch (error) {
|
|
3435
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3436
|
+
this._debug(`\u8F6E\u8BE2\u8BF7\u6C42\u5931\u8D25\uFF0C\u5C06\u91CD\u8BD5: ${message}`);
|
|
3437
|
+
await delay(POLL_INTERVAL_MS);
|
|
3438
|
+
continue;
|
|
3439
|
+
}
|
|
3440
|
+
const bodyText = await response.text().catch(() => "");
|
|
3441
|
+
const payload = parseJsonSafely2(bodyText);
|
|
3442
|
+
if (!response.ok) {
|
|
3443
|
+
const detail = extractErrorText(payload) ?? bodyText.trim();
|
|
3444
|
+
return makeError(
|
|
3445
|
+
response.status,
|
|
3446
|
+
`\u8F6E\u8BE2\u8BF7\u6C42\u5931\u8D25: HTTP ${response.status}${detail ? `: ${detail}` : ""}`
|
|
3447
|
+
);
|
|
3448
|
+
}
|
|
3449
|
+
if (!payload) {
|
|
3450
|
+
this._debug("\u8F6E\u8BE2\u8FD4\u56DE\u975E JSON \u6570\u636E\uFF0C\u5C06\u91CD\u8BD5");
|
|
3451
|
+
await delay(POLL_INTERVAL_MS);
|
|
3452
|
+
continue;
|
|
3453
|
+
}
|
|
3454
|
+
const status = payload.status;
|
|
3455
|
+
if (status === "completed") {
|
|
3456
|
+
return makeOkWith(payload);
|
|
3457
|
+
}
|
|
3458
|
+
if (status === "failed" || status === "cancelled" || status === "expired") {
|
|
3459
|
+
const errorText = payload.error?.trim() || `\u89C6\u9891\u751F\u6210\u7ED3\u675F\u4E8E\u72B6\u6001 ${status}`;
|
|
3460
|
+
return makeError(1, errorText);
|
|
3461
|
+
}
|
|
3462
|
+
const now = Date.now();
|
|
3463
|
+
if (now - lastStatusLogAt >= POLL_STATUS_LOG_INTERVAL_MS) {
|
|
3464
|
+
this._debug(
|
|
3465
|
+
`\u89C6\u9891\u751F\u6210\u72B6\u6001: ${status ?? "unknown"} (\u5DF2\u7B49\u5F85 ${Math.round(elapsed / 1e3)}s)`
|
|
3466
|
+
);
|
|
3467
|
+
lastStatusLogAt = now;
|
|
3468
|
+
}
|
|
3469
|
+
await delay(POLL_INTERVAL_MS);
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
};
|
|
3473
|
+
function parseReferencePaths3(value, previous) {
|
|
3474
|
+
return previous.concat(
|
|
3475
|
+
value.split(",").map((item) => item.trim()).filter((item) => item.length > 0)
|
|
3476
|
+
);
|
|
3477
|
+
}
|
|
3478
|
+
function parseDuration(value) {
|
|
3479
|
+
const parsed = Number.parseInt(value, 10);
|
|
3480
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
3481
|
+
throw new Error(`duration \u9700\u8981\u662F\u6B63\u6574\u6570\uFF0C\u6536\u5230: ${value}`);
|
|
3482
|
+
}
|
|
3483
|
+
return parsed;
|
|
3484
|
+
}
|
|
3485
|
+
function parseJsonSafely2(text) {
|
|
3486
|
+
if (!text.trim()) {
|
|
3487
|
+
return void 0;
|
|
3488
|
+
}
|
|
3489
|
+
try {
|
|
3490
|
+
return JSON.parse(text);
|
|
3491
|
+
} catch {
|
|
3492
|
+
return void 0;
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
function extractErrorText(payload) {
|
|
3496
|
+
if (!payload || typeof payload !== "object") {
|
|
3497
|
+
return void 0;
|
|
3498
|
+
}
|
|
3499
|
+
const record = payload;
|
|
3500
|
+
if (typeof record.error === "string" && record.error.trim().length > 0) {
|
|
3501
|
+
return record.error.trim();
|
|
3502
|
+
}
|
|
3503
|
+
if (record.error && typeof record.error === "object") {
|
|
3504
|
+
const inner = record.error;
|
|
3505
|
+
if (typeof inner.message === "string" && inner.message.trim().length > 0) {
|
|
3506
|
+
return inner.message.trim();
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
if (typeof record.message === "string" && record.message.trim().length > 0) {
|
|
3510
|
+
return record.message.trim();
|
|
3511
|
+
}
|
|
3512
|
+
return void 0;
|
|
3513
|
+
}
|
|
3514
|
+
function delay(ms) {
|
|
3515
|
+
return new Promise((resolve8) => setTimeout(resolve8, ms));
|
|
3516
|
+
}
|
|
3517
|
+
async function appendPollingUrl(pollingUrl, generationId) {
|
|
3518
|
+
const locationResult = await resolveConfigLocation();
|
|
3519
|
+
if (!locationResult.ok) {
|
|
3520
|
+
return locationResult;
|
|
3521
|
+
}
|
|
3522
|
+
const logFilePath = path9.join(
|
|
3523
|
+
locationResult.value.configDir,
|
|
3524
|
+
POLLING_LOG_FILE_NAME
|
|
3525
|
+
);
|
|
3526
|
+
try {
|
|
3527
|
+
await fs7.mkdir(locationResult.value.configDir, { recursive: true });
|
|
3528
|
+
const line = `${(/* @__PURE__ */ new Date()).toISOString()} ${generationId} ${pollingUrl}
|
|
3529
|
+
`;
|
|
3530
|
+
await fs7.appendFile(logFilePath, line, "utf8");
|
|
3531
|
+
return makeOkWith(logFilePath);
|
|
3532
|
+
} catch (error) {
|
|
3533
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3534
|
+
return makeError(1, `\u5199\u5165 polling \u65E5\u5FD7\u5931\u8D25 ${logFilePath}: ${message}`);
|
|
3535
|
+
}
|
|
3536
|
+
}
|
|
3537
|
+
async function resolveOutputTarget2(outputPath) {
|
|
3538
|
+
if (!outputPath) {
|
|
3539
|
+
const directoryPath = process.cwd();
|
|
3540
|
+
return makeOkWith({
|
|
3541
|
+
directoryPath,
|
|
3542
|
+
filePath: path9.join(directoryPath, buildAutoFileName2()),
|
|
3543
|
+
autoNamed: true
|
|
3544
|
+
});
|
|
3545
|
+
}
|
|
3546
|
+
const resolvedPath = path9.resolve(process.cwd(), outputPath);
|
|
3547
|
+
try {
|
|
3548
|
+
const stats = await fs7.stat(resolvedPath);
|
|
3549
|
+
if (stats.isDirectory()) {
|
|
3550
|
+
return makeOkWith({
|
|
3551
|
+
directoryPath: resolvedPath,
|
|
3552
|
+
filePath: path9.join(resolvedPath, buildAutoFileName2()),
|
|
3553
|
+
autoNamed: true
|
|
3554
|
+
});
|
|
3555
|
+
}
|
|
3556
|
+
return makeOkWith({
|
|
3557
|
+
directoryPath: path9.dirname(resolvedPath),
|
|
3558
|
+
filePath: resolvedPath,
|
|
3559
|
+
autoNamed: false
|
|
3560
|
+
});
|
|
3561
|
+
} catch (error) {
|
|
3562
|
+
const nodeError = error;
|
|
3563
|
+
if (nodeError.code !== "ENOENT") {
|
|
3564
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3565
|
+
return makeError(1, `\u8BFB\u53D6\u8F93\u51FA\u8DEF\u5F84\u5931\u8D25: ${resolvedPath}: ${message}`);
|
|
3566
|
+
}
|
|
3567
|
+
if (path9.extname(resolvedPath)) {
|
|
3568
|
+
return makeOkWith({
|
|
3569
|
+
directoryPath: path9.dirname(resolvedPath),
|
|
3570
|
+
filePath: resolvedPath,
|
|
3571
|
+
autoNamed: false
|
|
3572
|
+
});
|
|
3573
|
+
}
|
|
3574
|
+
return makeOkWith({
|
|
3575
|
+
directoryPath: resolvedPath,
|
|
3576
|
+
filePath: path9.join(resolvedPath, buildAutoFileName2()),
|
|
3577
|
+
autoNamed: true
|
|
3578
|
+
});
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
async function downloadVideoToFile(remoteUrl, target) {
|
|
3582
|
+
try {
|
|
3583
|
+
await fs7.mkdir(target.directoryPath, { recursive: true });
|
|
3584
|
+
} catch (error) {
|
|
3585
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3586
|
+
return makeError(
|
|
3587
|
+
1,
|
|
3588
|
+
`\u521B\u5EFA\u8F93\u51FA\u76EE\u5F55\u5931\u8D25: ${target.directoryPath}: ${message}`
|
|
3589
|
+
);
|
|
3590
|
+
}
|
|
3591
|
+
let response;
|
|
3592
|
+
try {
|
|
3593
|
+
response = await fetch(remoteUrl);
|
|
3594
|
+
} catch (error) {
|
|
3595
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3596
|
+
return makeError(1, `\u4E0B\u8F7D\u89C6\u9891\u5931\u8D25: ${message}`);
|
|
3597
|
+
}
|
|
3598
|
+
if (!response.ok) {
|
|
3599
|
+
return makeError(response.status, `\u4E0B\u8F7D\u89C6\u9891\u5931\u8D25: HTTP ${response.status}`);
|
|
3600
|
+
}
|
|
3601
|
+
const bytes = Buffer.from(await response.arrayBuffer());
|
|
3602
|
+
const targetPath = target.autoNamed ? replaceFileExtension2(target.filePath, inferVideoExtension(remoteUrl, response)) : target.filePath;
|
|
3603
|
+
try {
|
|
3604
|
+
await fs7.writeFile(targetPath, bytes);
|
|
3605
|
+
} catch (error) {
|
|
3606
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3607
|
+
return makeError(1, `\u5199\u5165\u89C6\u9891\u5931\u8D25: ${targetPath}: ${message}`);
|
|
3608
|
+
}
|
|
3609
|
+
return makeOkWith(path9.resolve(targetPath));
|
|
3610
|
+
}
|
|
3611
|
+
function buildAutoFileName2() {
|
|
3612
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
3613
|
+
return `ai-vid-${timestamp}.mp4`;
|
|
3614
|
+
}
|
|
3615
|
+
function replaceFileExtension2(filePath, extension) {
|
|
3616
|
+
const ext = path9.extname(filePath);
|
|
3617
|
+
if (!ext) {
|
|
3618
|
+
return `${filePath}.${extension}`;
|
|
3619
|
+
}
|
|
3620
|
+
return `${filePath.slice(0, -ext.length)}.${extension}`;
|
|
3621
|
+
}
|
|
3622
|
+
function inferVideoExtension(remoteUrl, response) {
|
|
3623
|
+
const contentType = response.headers.get("content-type")?.toLowerCase() ?? "";
|
|
3624
|
+
if (contentType.includes("mp4")) {
|
|
3625
|
+
return "mp4";
|
|
3626
|
+
}
|
|
3627
|
+
if (contentType.includes("webm")) {
|
|
3628
|
+
return "webm";
|
|
3629
|
+
}
|
|
3630
|
+
if (contentType.includes("quicktime") || contentType.includes("mov")) {
|
|
3631
|
+
return "mov";
|
|
3632
|
+
}
|
|
3633
|
+
try {
|
|
3634
|
+
const url = new URL(remoteUrl);
|
|
3635
|
+
const ext = path9.extname(url.pathname).toLowerCase();
|
|
3636
|
+
if (ext === ".mp4" || ext === ".webm" || ext === ".mov") {
|
|
3637
|
+
return ext.slice(1);
|
|
3638
|
+
}
|
|
3639
|
+
} catch {
|
|
3640
|
+
}
|
|
3641
|
+
return "mp4";
|
|
3642
|
+
}
|
|
3643
|
+
|
|
2436
3644
|
// src/commands/ai/ai-command.ts
|
|
2437
3645
|
var AiCommand = class extends BaseSubcommandHost {
|
|
2438
3646
|
_meta() {
|
|
@@ -2446,6 +3654,9 @@ var AiCommand = class extends BaseSubcommandHost {
|
|
|
2446
3654
|
this._addSubcommand(new AiCursorCommand());
|
|
2447
3655
|
this._addSubcommand(new AiCodexCommand());
|
|
2448
3656
|
this._addSubcommand(new AiRunCommand());
|
|
3657
|
+
this._addSubcommand(new AiImageCommand());
|
|
3658
|
+
this._addSubcommand(new AiVideoCommand());
|
|
3659
|
+
this._addSubcommand(new AiVidCommand());
|
|
2449
3660
|
}
|
|
2450
3661
|
};
|
|
2451
3662
|
|