jimeng-cli 0.2.0 → 0.3.0
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/chunk-2IIK4X7C.js +10228 -0
- package/dist/chunk-2IIK4X7C.js.map +1 -0
- package/dist/cli/index.cjs +6420 -580
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +406 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/mcp/index.cjs +6056 -513
- package/dist/mcp/index.cjs.map +1 -1
- package/dist/mcp/index.js +111 -1
- package/dist/mcp/index.js.map +1 -1
- package/package.json +11 -16
- package/dist/chunk-JZY62VNI.js +0 -4762
- package/dist/chunk-JZY62VNI.js.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
generateImageComposition,
|
|
6
6
|
generateImages,
|
|
7
7
|
generateVideo,
|
|
8
|
+
getAssetList,
|
|
8
9
|
getCredit,
|
|
9
10
|
getLiveModels,
|
|
10
11
|
getTaskResponse,
|
|
@@ -12,9 +13,11 @@ import {
|
|
|
12
13
|
logger_default,
|
|
13
14
|
parseRegionCode,
|
|
14
15
|
receiveCredit,
|
|
16
|
+
refreshAllTokenModels,
|
|
15
17
|
session_pool_default,
|
|
18
|
+
upscaleImage,
|
|
16
19
|
waitForTaskResponse
|
|
17
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-2IIK4X7C.js";
|
|
18
21
|
|
|
19
22
|
// src/cli/app.ts
|
|
20
23
|
import process2 from "process";
|
|
@@ -495,6 +498,34 @@ function printTaskInfo(task, deps) {
|
|
|
495
498
|
}
|
|
496
499
|
}
|
|
497
500
|
function createQueryCommandHandlers(deps) {
|
|
501
|
+
const handleModelsRefresh = async (argv) => {
|
|
502
|
+
const args = minimist2(argv, {
|
|
503
|
+
boolean: ["help", "json"]
|
|
504
|
+
});
|
|
505
|
+
if (args.help) {
|
|
506
|
+
console.log(deps.usageModelsRefresh());
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
await deps.ensureTokenPoolReady();
|
|
510
|
+
const results = await refreshAllTokenModels();
|
|
511
|
+
const isJson = Boolean(args.json);
|
|
512
|
+
if (isJson) {
|
|
513
|
+
deps.printCommandJson("models.refresh", results);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
if (results.length === 0) {
|
|
517
|
+
console.log("No enabled+live tokens found in pool. Nothing to refresh.");
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
console.log(`Refreshed ${results.length} token(s).`);
|
|
521
|
+
console.log("");
|
|
522
|
+
console.log("token region imageModels videoModels capabilityTags error");
|
|
523
|
+
for (const r of results) {
|
|
524
|
+
const tags = r.capabilityTags.length > 0 ? r.capabilityTags.join(",") : "-";
|
|
525
|
+
const err = r.error ? r.error.slice(0, 60) : "-";
|
|
526
|
+
console.log(`${r.token} ${r.region} ${r.imageModels} ${r.videoModels} ${tags} ${err}`);
|
|
527
|
+
}
|
|
528
|
+
};
|
|
498
529
|
const handleModelsList = async (argv) => {
|
|
499
530
|
const args = minimist2(argv, {
|
|
500
531
|
string: ["region", "token"],
|
|
@@ -638,10 +669,62 @@ ${deps.usageTaskWait()}`);
|
|
|
638
669
|
if (isJson) deps.printCommandJson("task.wait", taskInfo);
|
|
639
670
|
else printTaskInfo(taskInfo, deps);
|
|
640
671
|
};
|
|
672
|
+
const handleTaskList = async (argv) => {
|
|
673
|
+
const args = minimist2(argv, {
|
|
674
|
+
string: ["token", "region", "type", "count"],
|
|
675
|
+
boolean: ["help", "json"]
|
|
676
|
+
});
|
|
677
|
+
if (args.help) {
|
|
678
|
+
console.log(deps.usageTaskList());
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
const token = deps.getSingleString(args, "token");
|
|
682
|
+
const region = deps.getRegionWithDefault(args);
|
|
683
|
+
const type = deps.getSingleString(args, "type");
|
|
684
|
+
const countRaw = deps.getSingleString(args, "count");
|
|
685
|
+
const count = countRaw ? Number(countRaw) : 20;
|
|
686
|
+
const isJson = Boolean(args.json);
|
|
687
|
+
if (type && type !== "image" && type !== "video" && type !== "all") {
|
|
688
|
+
deps.fail(`Invalid --type: ${type}. Use image, video, or all.`);
|
|
689
|
+
}
|
|
690
|
+
const pick = await deps.pickDirectTokenForTask(token, region);
|
|
691
|
+
const result = await getAssetList(
|
|
692
|
+
pick.token,
|
|
693
|
+
buildRegionInfo(pick.region),
|
|
694
|
+
{
|
|
695
|
+
count: Number.isFinite(count) && count > 0 ? count : 20,
|
|
696
|
+
type
|
|
697
|
+
}
|
|
698
|
+
);
|
|
699
|
+
if (isJson) {
|
|
700
|
+
deps.printCommandJson("task.list", {
|
|
701
|
+
has_more: result.hasMore,
|
|
702
|
+
next_offset: result.nextOffset,
|
|
703
|
+
total: result.items.length,
|
|
704
|
+
items: result.items
|
|
705
|
+
});
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
console.log(`Total: ${result.items.length} items${result.hasMore ? " (more available)" : ""}
|
|
709
|
+
`);
|
|
710
|
+
for (const item of result.items) {
|
|
711
|
+
const typeLabel = item.type === 1 ? "IMG" : "VID";
|
|
712
|
+
const statusLabel = item.status === 144 || item.status === 10 ? "DONE" : item.status === 30 ? "FAIL" : "PROC";
|
|
713
|
+
const time = item.createdTime > 0 ? new Date(item.createdTime * 1e3).toLocaleString() : "-";
|
|
714
|
+
const modelShort = item.modelName || item.modelReqKey || "-";
|
|
715
|
+
const promptShort = item.prompt.length > 50 ? item.prompt.slice(0, 50) + "..." : item.prompt;
|
|
716
|
+
console.log(`${item.id} ${typeLabel} ${statusLabel.padEnd(4)} ${time} ${modelShort.padEnd(20)} ${promptShort}`);
|
|
717
|
+
if (item.imageUrl) {
|
|
718
|
+
console.log(` ${item.imageUrl}`);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
};
|
|
641
722
|
return {
|
|
642
723
|
handleModelsList,
|
|
724
|
+
handleModelsRefresh,
|
|
643
725
|
handleTaskGet,
|
|
644
726
|
handleTaskWait,
|
|
727
|
+
handleTaskList,
|
|
645
728
|
printTaskInfo: (task) => {
|
|
646
729
|
const normalized = collectTaskInfo(task, deps);
|
|
647
730
|
if (!normalized) {
|
|
@@ -1187,13 +1270,257 @@ function createMediaCommandHandlers(deps) {
|
|
|
1187
1270
|
deps.printDownloadSummary("video", [filePath]);
|
|
1188
1271
|
}
|
|
1189
1272
|
};
|
|
1273
|
+
const handleImageUpscale = async (argv) => {
|
|
1274
|
+
const args = minimist3(argv, {
|
|
1275
|
+
string: [
|
|
1276
|
+
"token",
|
|
1277
|
+
"region",
|
|
1278
|
+
"image",
|
|
1279
|
+
"model",
|
|
1280
|
+
"resolution",
|
|
1281
|
+
"output-dir",
|
|
1282
|
+
"wait-timeout-seconds",
|
|
1283
|
+
"poll-interval-ms"
|
|
1284
|
+
],
|
|
1285
|
+
boolean: ["help", "wait", "json"],
|
|
1286
|
+
default: { wait: true }
|
|
1287
|
+
});
|
|
1288
|
+
if (args.help) {
|
|
1289
|
+
console.log(deps.usageImageUpscale());
|
|
1290
|
+
return;
|
|
1291
|
+
}
|
|
1292
|
+
const token = deps.getSingleString(args, "token");
|
|
1293
|
+
const region = deps.getRegionWithDefault(args);
|
|
1294
|
+
const imageSource = deps.getSingleString(args, "image");
|
|
1295
|
+
if (!imageSource) deps.failWithUsage("Missing required --image.", deps.usageImageUpscale());
|
|
1296
|
+
const outputDir = deps.getSingleString(args, "output-dir") || "./pic/cli-image-upscale";
|
|
1297
|
+
const model = deps.getSingleString(args, "model") || "jimeng-5.0";
|
|
1298
|
+
const resolution = deps.getSingleString(args, "resolution") || "4k";
|
|
1299
|
+
const wait = Boolean(args.wait);
|
|
1300
|
+
const isJson = Boolean(args.json);
|
|
1301
|
+
const pick = await deps.pickDirectTokenForGeneration(token, region, model, "image");
|
|
1302
|
+
let image;
|
|
1303
|
+
if (isHttpUrl(imageSource)) {
|
|
1304
|
+
image = imageSource;
|
|
1305
|
+
} else {
|
|
1306
|
+
const imagePath = path3.resolve(imageSource);
|
|
1307
|
+
if (!await pathExists2(imagePath)) deps.fail(`Image file not found: ${imagePath}`);
|
|
1308
|
+
image = await readFile2(imagePath);
|
|
1309
|
+
}
|
|
1310
|
+
const result = await upscaleImage(
|
|
1311
|
+
model,
|
|
1312
|
+
image,
|
|
1313
|
+
{
|
|
1314
|
+
resolution,
|
|
1315
|
+
wait,
|
|
1316
|
+
waitTimeoutSeconds: parsePositiveNumberOption2(args, "wait-timeout-seconds", deps),
|
|
1317
|
+
pollIntervalMs: parsePositiveNumberOption2(args, "poll-interval-ms", deps)
|
|
1318
|
+
},
|
|
1319
|
+
pick.token,
|
|
1320
|
+
buildRegionInfo(pick.region)
|
|
1321
|
+
);
|
|
1322
|
+
if (!Array.isArray(result)) {
|
|
1323
|
+
if (isJson) deps.printCommandJson("image.upscale", result, { wait });
|
|
1324
|
+
else deps.printTaskInfo(result);
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
const urls = result;
|
|
1328
|
+
if (urls.length === 0) deps.fail("No image URL found in response.");
|
|
1329
|
+
const savedFiles = await downloadImages(urls, outputDir, "jimeng-image-upscale", deps);
|
|
1330
|
+
if (isJson) {
|
|
1331
|
+
deps.printCommandJson(
|
|
1332
|
+
"image.upscale",
|
|
1333
|
+
{ data: urls.map((url) => ({ url })), files: savedFiles },
|
|
1334
|
+
{ wait, resolution }
|
|
1335
|
+
);
|
|
1336
|
+
} else {
|
|
1337
|
+
deps.printDownloadSummary("image", savedFiles);
|
|
1338
|
+
}
|
|
1339
|
+
};
|
|
1190
1340
|
return {
|
|
1191
1341
|
handleImageGenerate,
|
|
1192
1342
|
handleImageEdit,
|
|
1343
|
+
handleImageUpscale,
|
|
1193
1344
|
handleVideoGenerate
|
|
1194
1345
|
};
|
|
1195
1346
|
}
|
|
1196
1347
|
|
|
1348
|
+
// src/cli/login.ts
|
|
1349
|
+
import { execSync, spawn } from "child_process";
|
|
1350
|
+
import { existsSync } from "fs";
|
|
1351
|
+
import path4 from "path";
|
|
1352
|
+
import os from "os";
|
|
1353
|
+
import minimist4 from "minimist";
|
|
1354
|
+
var LOGIN_SCRIPT = path4.join(__dirname, "..", "..", "scripts", "jimeng_login_helper.py");
|
|
1355
|
+
function createLoginCommandHandler(deps) {
|
|
1356
|
+
return async (argv) => {
|
|
1357
|
+
const args = minimist4(argv, {
|
|
1358
|
+
string: ["region", "sessionid", "debug-port"],
|
|
1359
|
+
boolean: ["help", "headless", "json"]
|
|
1360
|
+
});
|
|
1361
|
+
if (args.help) {
|
|
1362
|
+
console.log(usageLogin());
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
const region = deps.getRegionWithDefault(args);
|
|
1366
|
+
const parsedRegion = deps.parseRegionOrFail(region);
|
|
1367
|
+
const isJson = Boolean(args.json);
|
|
1368
|
+
const sessionid = deps.getSingleString(args, "sessionid");
|
|
1369
|
+
const debugPort = deps.getSingleString(args, "debug-port") || "9333";
|
|
1370
|
+
const headless = Boolean(args.headless);
|
|
1371
|
+
if (sessionid) {
|
|
1372
|
+
await addSessionToPool(sessionid, parsedRegion || "cn", deps, isJson);
|
|
1373
|
+
return;
|
|
1374
|
+
}
|
|
1375
|
+
const pythonLoginResult = await tryPythonLogin(debugPort, headless);
|
|
1376
|
+
if (pythonLoginResult) {
|
|
1377
|
+
await addSessionToPool(pythonLoginResult, parsedRegion || "cn", deps, isJson);
|
|
1378
|
+
return;
|
|
1379
|
+
}
|
|
1380
|
+
console.log("");
|
|
1381
|
+
console.log("Auto login not available. Please provide your sessionid manually.");
|
|
1382
|
+
console.log("You can get it from:");
|
|
1383
|
+
console.log(" 1. Login at https://jimeng.jianying.com/ai-tool/home/");
|
|
1384
|
+
console.log(" 2. Open DevTools > Application > Cookies > sessionid");
|
|
1385
|
+
console.log("");
|
|
1386
|
+
console.log("Then run: jimeng login --sessionid <your_sessionid> --region cn");
|
|
1387
|
+
console.log("");
|
|
1388
|
+
console.log("Or install Python 3 to use the automatic browser login.");
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
async function tryPythonLogin(debugPort, headless) {
|
|
1392
|
+
const loginScript = findLoginScript();
|
|
1393
|
+
if (!loginScript) {
|
|
1394
|
+
return null;
|
|
1395
|
+
}
|
|
1396
|
+
console.log(`Launching browser login (debug port: ${debugPort})...`);
|
|
1397
|
+
console.log("Please complete login in the Chrome window.\n");
|
|
1398
|
+
try {
|
|
1399
|
+
const cmdArgs = [loginScript, "--debug-port", debugPort];
|
|
1400
|
+
if (headless) cmdArgs.push("--headless");
|
|
1401
|
+
const result = await runPythonScript(cmdArgs);
|
|
1402
|
+
const output = result.stdout.trim();
|
|
1403
|
+
const match = output.match(/sessionid:\s*(\S+)/);
|
|
1404
|
+
if (match) {
|
|
1405
|
+
return match[1];
|
|
1406
|
+
}
|
|
1407
|
+
console.log("Login script completed but sessionid not found in output.");
|
|
1408
|
+
return null;
|
|
1409
|
+
} catch (error) {
|
|
1410
|
+
console.log(`Auto login failed: ${error.message}`);
|
|
1411
|
+
return null;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
function findLoginScript() {
|
|
1415
|
+
if (existsSync(LOGIN_SCRIPT)) {
|
|
1416
|
+
return LOGIN_SCRIPT;
|
|
1417
|
+
}
|
|
1418
|
+
const candidates = [
|
|
1419
|
+
path4.join(process.cwd(), "jimeng_login.py"),
|
|
1420
|
+
path4.join(os.homedir(), ".jimeng_login.py")
|
|
1421
|
+
];
|
|
1422
|
+
try {
|
|
1423
|
+
const whichResult = execSync("which jimeng_login.py 2>/dev/null || echo ''", { encoding: "utf-8" }).trim();
|
|
1424
|
+
if (whichResult) return whichResult;
|
|
1425
|
+
} catch {
|
|
1426
|
+
}
|
|
1427
|
+
for (const candidate of candidates) {
|
|
1428
|
+
if (existsSync(candidate)) return candidate;
|
|
1429
|
+
}
|
|
1430
|
+
return null;
|
|
1431
|
+
}
|
|
1432
|
+
function runPythonScript(args) {
|
|
1433
|
+
return new Promise((resolve, reject) => {
|
|
1434
|
+
var _a, _b;
|
|
1435
|
+
const pythonCmd = process.platform === "win32" ? "python" : "python3";
|
|
1436
|
+
const proc = spawn(pythonCmd, args, {
|
|
1437
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
1438
|
+
env: { ...process.env }
|
|
1439
|
+
});
|
|
1440
|
+
let stdout = "";
|
|
1441
|
+
let stderr = "";
|
|
1442
|
+
(_a = proc.stdout) == null ? void 0 : _a.on("data", (data) => {
|
|
1443
|
+
stdout += data.toString();
|
|
1444
|
+
const lines = data.toString().split("\n").filter(Boolean);
|
|
1445
|
+
for (const line of lines) {
|
|
1446
|
+
console.log(line);
|
|
1447
|
+
}
|
|
1448
|
+
});
|
|
1449
|
+
(_b = proc.stderr) == null ? void 0 : _b.on("data", (data) => {
|
|
1450
|
+
stderr += data.toString();
|
|
1451
|
+
});
|
|
1452
|
+
proc.on("close", (code) => {
|
|
1453
|
+
if (code === 0) {
|
|
1454
|
+
resolve({ stdout, stderr });
|
|
1455
|
+
} else {
|
|
1456
|
+
reject(new Error(`Login script exited with code ${code}: ${stderr.slice(-200)}`));
|
|
1457
|
+
}
|
|
1458
|
+
});
|
|
1459
|
+
proc.on("error", (error) => {
|
|
1460
|
+
reject(new Error(`Failed to run login script: ${error.message}`));
|
|
1461
|
+
});
|
|
1462
|
+
});
|
|
1463
|
+
}
|
|
1464
|
+
async function addSessionToPool(sessionid, region, deps, isJson) {
|
|
1465
|
+
await deps.ensureTokenPoolReady();
|
|
1466
|
+
const { added, total } = await session_pool_default.addTokens([sessionid], { defaultRegion: region });
|
|
1467
|
+
if (added > 0) {
|
|
1468
|
+
const masked = sessionid.length > 10 ? `${sessionid.slice(0, 4)}...${sessionid.slice(-4)}` : "***";
|
|
1469
|
+
let creditInfo = "";
|
|
1470
|
+
try {
|
|
1471
|
+
const { totalCredit } = await getCredit(sessionid, buildRegionInfo(region));
|
|
1472
|
+
creditInfo = ` (credits: ${totalCredit})`;
|
|
1473
|
+
} catch {
|
|
1474
|
+
creditInfo = " (credit check failed)";
|
|
1475
|
+
}
|
|
1476
|
+
if (isJson) {
|
|
1477
|
+
deps.printCommandJson("login", {
|
|
1478
|
+
token: masked,
|
|
1479
|
+
region,
|
|
1480
|
+
added: true,
|
|
1481
|
+
total,
|
|
1482
|
+
creditCheck: creditInfo.trim()
|
|
1483
|
+
});
|
|
1484
|
+
} else {
|
|
1485
|
+
console.log(`
|
|
1486
|
+
Login successful!`);
|
|
1487
|
+
console.log(` Token: ${masked}`);
|
|
1488
|
+
console.log(` Region: ${region}${creditInfo}`);
|
|
1489
|
+
console.log(` Pool size: ${total} token(s)`);
|
|
1490
|
+
}
|
|
1491
|
+
} else {
|
|
1492
|
+
if (isJson) {
|
|
1493
|
+
deps.printCommandJson("login", {
|
|
1494
|
+
added: false,
|
|
1495
|
+
total,
|
|
1496
|
+
reason: "token already exists in pool"
|
|
1497
|
+
});
|
|
1498
|
+
} else {
|
|
1499
|
+
console.log(`Token already exists in pool. Pool size: ${total} token(s)`);
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
function usageLogin() {
|
|
1504
|
+
return [
|
|
1505
|
+
"Usage:",
|
|
1506
|
+
" jimeng login [options]",
|
|
1507
|
+
"",
|
|
1508
|
+
"Options:",
|
|
1509
|
+
" --region <region> Region for the token (default cn)",
|
|
1510
|
+
" --sessionid <token> Add sessionid directly (skip browser login)",
|
|
1511
|
+
" --debug-port <port> Chrome debug port (default 9333)",
|
|
1512
|
+
" --headless Run Chrome in headless mode",
|
|
1513
|
+
" --json Output structured JSON",
|
|
1514
|
+
" --help Show help",
|
|
1515
|
+
"",
|
|
1516
|
+
"Notes:",
|
|
1517
|
+
" - Without --sessionid, launches Chrome for browser login (requires Python 3).",
|
|
1518
|
+
" - With --sessionid, directly adds the token to the pool.",
|
|
1519
|
+
" - After login, the token is automatically added to the token pool.",
|
|
1520
|
+
" - Token is validated by checking credit balance."
|
|
1521
|
+
].join("\n");
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1197
1524
|
// src/cli/app.ts
|
|
1198
1525
|
var JSON_OPTION = " --json Output structured JSON";
|
|
1199
1526
|
var HELP_OPTION = " --help Show help";
|
|
@@ -1234,6 +1561,21 @@ function usageModelsList() {
|
|
|
1234
1561
|
HELP_OPTION
|
|
1235
1562
|
]);
|
|
1236
1563
|
}
|
|
1564
|
+
function usageModelsRefresh() {
|
|
1565
|
+
return buildUsageText(" jimeng models refresh [options]", [
|
|
1566
|
+
" --json Output structured JSON",
|
|
1567
|
+
HELP_OPTION
|
|
1568
|
+
], [
|
|
1569
|
+
{
|
|
1570
|
+
title: "Notes:",
|
|
1571
|
+
lines: [
|
|
1572
|
+
" - Refreshes dynamicCapabilities (imageModels, videoModels, capabilityTags) for",
|
|
1573
|
+
" all enabled+live tokens in the token pool.",
|
|
1574
|
+
" - Results are persisted to token-pool.json automatically."
|
|
1575
|
+
]
|
|
1576
|
+
}
|
|
1577
|
+
]);
|
|
1578
|
+
}
|
|
1237
1579
|
function usageTokenSubcommand(name) {
|
|
1238
1580
|
const subcommand = TOKEN_SUBCOMMANDS_BY_NAME[name];
|
|
1239
1581
|
return buildUsageText(subcommand.usageLine, subcommand.options, subcommand.sections);
|
|
@@ -1300,6 +1642,34 @@ function usageImageEdit() {
|
|
|
1300
1642
|
]
|
|
1301
1643
|
);
|
|
1302
1644
|
}
|
|
1645
|
+
function usageImageUpscale() {
|
|
1646
|
+
return buildUsageText(
|
|
1647
|
+
" jimeng image upscale --image <path_or_url> [options]",
|
|
1648
|
+
[
|
|
1649
|
+
" --token <token> Optional, override token-pool selection",
|
|
1650
|
+
" --region <region> X-Region header, default cn (cn/us/hk/jp/sg)",
|
|
1651
|
+
" --image <path_or_url> Required, local file or URL",
|
|
1652
|
+
" --model <model> Default jimeng-5.0",
|
|
1653
|
+
" --resolution <res> Default 4k (target resolution)",
|
|
1654
|
+
" --wait / --no-wait Default wait; --no-wait returns task only",
|
|
1655
|
+
" --wait-timeout-seconds Optional wait timeout override",
|
|
1656
|
+
" --poll-interval-ms Optional poll interval override",
|
|
1657
|
+
JSON_OPTION,
|
|
1658
|
+
" --output-dir <dir> Default ./pic/cli-image-upscale",
|
|
1659
|
+
HELP_OPTION
|
|
1660
|
+
],
|
|
1661
|
+
[
|
|
1662
|
+
{
|
|
1663
|
+
title: "Notes:",
|
|
1664
|
+
lines: [
|
|
1665
|
+
" - Upscales an existing image to higher resolution using super_resolution.",
|
|
1666
|
+
" - Supports 2k and 4k target resolutions.",
|
|
1667
|
+
" - Image source can be a local file path or HTTP URL."
|
|
1668
|
+
]
|
|
1669
|
+
}
|
|
1670
|
+
]
|
|
1671
|
+
);
|
|
1672
|
+
}
|
|
1303
1673
|
function usageVideoGenerate() {
|
|
1304
1674
|
return buildUsageText(" jimeng video generate --prompt <text> [options]", [
|
|
1305
1675
|
" --token <token> Optional, override token-pool selection",
|
|
@@ -1369,6 +1739,16 @@ function usageTaskWait() {
|
|
|
1369
1739
|
HELP_OPTION
|
|
1370
1740
|
]);
|
|
1371
1741
|
}
|
|
1742
|
+
function usageTaskList() {
|
|
1743
|
+
return buildUsageText(" jimeng task list [options]", [
|
|
1744
|
+
" --token <token> Optional, override token-pool selection",
|
|
1745
|
+
" --region <region> X-Region header, default cn (cn/us/hk/jp/sg)",
|
|
1746
|
+
" --type <type> Filter by type: image, video, or all (default all)",
|
|
1747
|
+
" --count <num> Number of items per page (default 20)",
|
|
1748
|
+
JSON_OPTION,
|
|
1749
|
+
HELP_OPTION
|
|
1750
|
+
]);
|
|
1751
|
+
}
|
|
1372
1752
|
function configureCliLogging(command) {
|
|
1373
1753
|
if (process2.env.JIMENG_CLI_VERBOSE_LOGS === "true") {
|
|
1374
1754
|
process2.env.JIMENG_CLI_SILENT_LOGS = "false";
|
|
@@ -1502,8 +1882,10 @@ var TOKEN_SUBCOMMANDS = createTokenSubcommands({
|
|
|
1502
1882
|
});
|
|
1503
1883
|
var queryHandlers = createQueryCommandHandlers({
|
|
1504
1884
|
usageModelsList,
|
|
1885
|
+
usageModelsRefresh,
|
|
1505
1886
|
usageTaskGet,
|
|
1506
1887
|
usageTaskWait,
|
|
1888
|
+
usageTaskList,
|
|
1507
1889
|
getSingleString,
|
|
1508
1890
|
getRegionWithDefault,
|
|
1509
1891
|
parseRegionOrFail,
|
|
@@ -1517,6 +1899,7 @@ var queryHandlers = createQueryCommandHandlers({
|
|
|
1517
1899
|
var mediaHandlers = createMediaCommandHandlers({
|
|
1518
1900
|
usageImageGenerate,
|
|
1519
1901
|
usageImageEdit,
|
|
1902
|
+
usageImageUpscale,
|
|
1520
1903
|
usageVideoGenerate,
|
|
1521
1904
|
getSingleString,
|
|
1522
1905
|
getRegionWithDefault,
|
|
@@ -1535,10 +1918,26 @@ function buildHandlersMap(subcommands) {
|
|
|
1535
1918
|
return Object.fromEntries(subcommands.map((item) => [item.name, item.handler]));
|
|
1536
1919
|
}
|
|
1537
1920
|
var COMMAND_SPECS = [
|
|
1921
|
+
{
|
|
1922
|
+
name: "login",
|
|
1923
|
+
description: "Login and add session to token pool",
|
|
1924
|
+
handler: createLoginCommandHandler({
|
|
1925
|
+
getSingleString,
|
|
1926
|
+
getRegionWithDefault,
|
|
1927
|
+
parseRegionOrFail,
|
|
1928
|
+
ensureTokenPoolReady,
|
|
1929
|
+
fail,
|
|
1930
|
+
printJson,
|
|
1931
|
+
printCommandJson
|
|
1932
|
+
})
|
|
1933
|
+
},
|
|
1538
1934
|
{
|
|
1539
1935
|
name: "models",
|
|
1540
1936
|
description: "Model commands",
|
|
1541
|
-
subcommands: [
|
|
1937
|
+
subcommands: [
|
|
1938
|
+
{ name: "list", description: "List available models", handler: queryHandlers.handleModelsList },
|
|
1939
|
+
{ name: "refresh", description: "Refresh token dynamic capabilities (model list)", handler: queryHandlers.handleModelsRefresh }
|
|
1940
|
+
],
|
|
1542
1941
|
usage: usageRoot
|
|
1543
1942
|
},
|
|
1544
1943
|
{
|
|
@@ -1546,7 +1945,8 @@ var COMMAND_SPECS = [
|
|
|
1546
1945
|
description: "Image commands",
|
|
1547
1946
|
subcommands: [
|
|
1548
1947
|
{ name: "generate", description: "Generate image from text", handler: mediaHandlers.handleImageGenerate },
|
|
1549
|
-
{ name: "edit", description: "Edit image(s) with prompt", handler: mediaHandlers.handleImageEdit }
|
|
1948
|
+
{ name: "edit", description: "Edit image(s) with prompt", handler: mediaHandlers.handleImageEdit },
|
|
1949
|
+
{ name: "upscale", description: "Upscale image to higher resolution", handler: mediaHandlers.handleImageUpscale }
|
|
1550
1950
|
],
|
|
1551
1951
|
usage: usageRoot
|
|
1552
1952
|
},
|
|
@@ -1567,7 +1967,8 @@ var COMMAND_SPECS = [
|
|
|
1567
1967
|
description: "Task commands",
|
|
1568
1968
|
subcommands: [
|
|
1569
1969
|
{ name: "get", description: "Get task status", handler: queryHandlers.handleTaskGet },
|
|
1570
|
-
{ name: "wait", description: "Wait until task completion", handler: queryHandlers.handleTaskWait }
|
|
1970
|
+
{ name: "wait", description: "Wait until task completion", handler: queryHandlers.handleTaskWait },
|
|
1971
|
+
{ name: "list", description: "List task history", handler: queryHandlers.handleTaskList }
|
|
1571
1972
|
],
|
|
1572
1973
|
usage: usageRoot
|
|
1573
1974
|
},
|
|
@@ -1629,7 +2030,7 @@ async function run() {
|
|
|
1629
2030
|
failWithUsage(`Unknown command: ${[command, subcommand].filter(Boolean).join(" ")}`, usageRoot());
|
|
1630
2031
|
}
|
|
1631
2032
|
if (spec.handler) {
|
|
1632
|
-
await spec.handler(rest);
|
|
2033
|
+
await spec.handler(subcommand ? [subcommand, ...rest] : rest);
|
|
1633
2034
|
return;
|
|
1634
2035
|
}
|
|
1635
2036
|
if (spec.subcommands) {
|