@artillect/cli 0.1.0 → 0.1.1
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 +15 -43
- package/dist/index.js +56 -50
- package/package.json +3 -8
package/README.md
CHANGED
|
@@ -1,58 +1,30 @@
|
|
|
1
1
|
# `@artillect/cli`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Artillect CLI — генерация картинок и видео из терминала.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
npm i -g @artillect/cli
|
|
7
|
-
# or, without a global install:
|
|
8
|
-
npx @artillect/cli@latest --help
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Requires Node.js **≥ 20**. First publish of a scoped package uses `npm publish --access public` (already set in `publishConfig`).
|
|
5
|
+
## Установка
|
|
12
6
|
|
|
13
7
|
```bash
|
|
14
|
-
|
|
15
|
-
# or: export ARTILLECT_API_KEY=art_…
|
|
16
|
-
# export ARTILLECT_BASE_URL=https://dev.artillect.pro # optional
|
|
17
|
-
|
|
18
|
-
artillect balance
|
|
19
|
-
artillect models list
|
|
20
|
-
artillect generate image --prompt "a cat" --wait
|
|
21
|
-
artillect generate video kling-3 --prompt "a cat walks" --start-image ./a.png --wait
|
|
8
|
+
npm install -g @artillect/cli
|
|
22
9
|
```
|
|
23
10
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
## Updates and hotfixes
|
|
11
|
+
Нужен Node.js 20+. Без глобальной установки: `npx @artillect/cli@latest --help`.
|
|
27
12
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
| Who | What happens |
|
|
31
|
-
| --------------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
32
|
-
| You ship a CLI hotfix | Bump **patch** (`0.1.0` → `0.1.1`), `pnpm --filter @artillect/cli publish`. |
|
|
33
|
-
| You ship a feature | Bump **minor**. Breaking CLI flags → **major**. |
|
|
34
|
-
| API/server hotfix | Users get it on the next request. No CLI reinstall. Catalog, billing, and generation bugs live on the server. |
|
|
35
|
-
| SDK change | SDK is private and inlined in the CLI bundle. Republish `@artillect/cli` — there is no `@artillect/sdk` on npm. |
|
|
36
|
-
|
|
37
|
-
How a user actually receives a new CLI:
|
|
13
|
+
## Использование
|
|
38
14
|
|
|
39
15
|
```bash
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
16
|
+
artillect auth login
|
|
17
|
+
artillect models list
|
|
18
|
+
artillect generate image --prompt "кот в космосе" --wait
|
|
19
|
+
artillect generate video kling-3 --prompt "кот идёт" --start-image ./a.png --wait
|
|
20
|
+
artillect --help
|
|
43
21
|
```
|
|
44
22
|
|
|
45
|
-
|
|
23
|
+
Ключ также можно задать через `ARTILLECT_API_KEY`. `--wait` дожидается результата и сохраняет файлы в текущую папку (или `--out`).
|
|
46
24
|
|
|
47
|
-
`
|
|
25
|
+
Обновление: `npm i -g @artillect/cli@latest`.
|
|
48
26
|
|
|
49
|
-
##
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
pnpm --filter @artillect/sdk run build
|
|
53
|
-
pnpm --filter @artillect/cli run build
|
|
54
|
-
pnpm --filter @artillect/cli run pack:check # tarball + --help/--version
|
|
55
|
-
pnpm --filter @artillect/cli run smoke # live health + models + device/code
|
|
56
|
-
```
|
|
27
|
+
## Ссылки
|
|
57
28
|
|
|
58
|
-
|
|
29
|
+
- Документация: https://app.artillect.pro/docs/cli
|
|
30
|
+
- Артиллект: https://app.artillect.pro
|
package/dist/index.js
CHANGED
|
@@ -355,7 +355,7 @@ function loadCliConfig() {
|
|
|
355
355
|
function requireApiKey() {
|
|
356
356
|
const cfg = loadCliConfig();
|
|
357
357
|
if (!cfg.apiKey) {
|
|
358
|
-
throw new Error("
|
|
358
|
+
throw new Error("\u041D\u0435\u0442 \u0432\u0445\u043E\u0434\u0430. \u0412\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u0435 `artillect auth login` \u0438\u043B\u0438 \u0437\u0430\u0434\u0430\u0439\u0442\u0435 ARTILLECT_API_KEY.");
|
|
359
359
|
}
|
|
360
360
|
return cfg;
|
|
361
361
|
}
|
|
@@ -416,7 +416,9 @@ async function authLogin() {
|
|
|
416
416
|
const { baseUrl } = loadCliConfig();
|
|
417
417
|
const started = await postJson(baseUrl, "/api/v1/device/code", {});
|
|
418
418
|
if (started.status >= 400) {
|
|
419
|
-
throw new Error(
|
|
419
|
+
throw new Error(
|
|
420
|
+
String(started.json.error || `\u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043A\u043E\u0434 \u0432\u0445\u043E\u0434\u0430 (${started.status})`)
|
|
421
|
+
);
|
|
420
422
|
}
|
|
421
423
|
const deviceCode = String(started.json.device_code || "");
|
|
422
424
|
const userCode = String(started.json.user_code || "");
|
|
@@ -424,12 +426,12 @@ async function authLogin() {
|
|
|
424
426
|
const intervalSec = Math.max(1, Number(started.json.interval) || 5);
|
|
425
427
|
const expiresIn = Number(started.json.expires_in) || 600;
|
|
426
428
|
if (!deviceCode || !verificationUrl) {
|
|
427
|
-
throw new Error("
|
|
429
|
+
throw new Error("\u0412 \u043E\u0442\u0432\u0435\u0442\u0435 \u043D\u0435\u0442 device_code \u0438\u043B\u0438 verification_url");
|
|
428
430
|
}
|
|
429
|
-
console.log("
|
|
431
|
+
console.log("\u041E\u0442\u043A\u0440\u043E\u0439\u0442\u0435 \u0441\u0441\u044B\u043B\u043A\u0443 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435, \u0433\u0434\u0435 \u0432\u044B \u0432\u043E\u0448\u043B\u0438 \u0432 \u0410\u0440\u0442\u0438\u043B\u043B\u0435\u043A\u0442:");
|
|
430
432
|
console.log(` ${verificationUrl}`);
|
|
431
|
-
if (userCode) console.log(
|
|
432
|
-
console.log("
|
|
433
|
+
if (userCode) console.log(`\u041A\u043E\u0434 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u044F: ${userCode}`);
|
|
434
|
+
console.log("\u0416\u0434\u0451\u043C \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435\u2026");
|
|
433
435
|
const deadline = Date.now() + expiresIn * 1e3;
|
|
434
436
|
while (Date.now() < deadline) {
|
|
435
437
|
await sleep(intervalSec * 1e3);
|
|
@@ -437,21 +439,21 @@ async function authLogin() {
|
|
|
437
439
|
const status = String(polled.json.status || "");
|
|
438
440
|
if (status === "pending") continue;
|
|
439
441
|
if (status === "expired" || polled.status === 410) {
|
|
440
|
-
throw new Error("
|
|
442
|
+
throw new Error("\u041A\u043E\u0434 \u0438\u0441\u0442\u0435\u043A. \u0421\u043D\u043E\u0432\u0430 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u0435 `artillect auth login`.");
|
|
441
443
|
}
|
|
442
444
|
const apiKey = String(polled.json.api_key || "");
|
|
443
445
|
if (status === "completed" && apiKey) {
|
|
444
446
|
const path = saveCliConfig({ apiKey, baseUrl });
|
|
445
|
-
console.log(
|
|
447
|
+
console.log(`\u0412\u0445\u043E\u0434 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D. \u041A\u043B\u044E\u0447 \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D \u0432 ${path}`);
|
|
446
448
|
return;
|
|
447
449
|
}
|
|
448
|
-
throw new Error(String(polled.json.error ||
|
|
450
|
+
throw new Error(String(polled.json.error || `\u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0432\u043E\u0439\u0442\u0438 (${polled.status})`));
|
|
449
451
|
}
|
|
450
|
-
throw new Error("
|
|
452
|
+
throw new Error("\u0412\u0440\u0435\u043C\u044F \u043D\u0430 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0438\u0441\u0442\u0435\u043A\u043B\u043E.");
|
|
451
453
|
}
|
|
452
454
|
async function authLogout() {
|
|
453
455
|
clearCliConfig();
|
|
454
|
-
console.log("
|
|
456
|
+
console.log("\u0412\u044B \u0432\u044B\u0448\u043B\u0438.");
|
|
455
457
|
}
|
|
456
458
|
async function authStatus() {
|
|
457
459
|
const envKey = Boolean(String(process.env.ARTILLECT_API_KEY || "").trim());
|
|
@@ -461,14 +463,14 @@ async function authStatus() {
|
|
|
461
463
|
const me = await client.getMe();
|
|
462
464
|
if (!me.ok) {
|
|
463
465
|
console.log(
|
|
464
|
-
|
|
466
|
+
`\u041A\u043B\u044E\u0447 \u0437\u0430\u0434\u0430\u043D (${envKey ? "ARTILLECT_API_KEY" : configPath()}), \u043D\u043E /me \u043D\u0435 \u043E\u0442\u0432\u0435\u0442\u0438\u043B: ${me.error}`
|
|
465
467
|
);
|
|
466
468
|
process.exitCode = 1;
|
|
467
469
|
return;
|
|
468
470
|
}
|
|
469
471
|
const body = me.body;
|
|
470
|
-
console.log(
|
|
471
|
-
console.log(
|
|
472
|
+
console.log(`\u0412\u044B \u0432\u043E\u0448\u043B\u0438 \u043A\u0430\u043A ${body.email ?? body.user_id ?? "ok"}`);
|
|
473
|
+
console.log(`\u0421\u0435\u0440\u0432\u0435\u0440: ${cfg.baseUrl}`);
|
|
472
474
|
} catch (err) {
|
|
473
475
|
console.log(err instanceof Error ? err.message : String(err));
|
|
474
476
|
process.exitCode = 1;
|
|
@@ -487,12 +489,12 @@ function asRecord(value) {
|
|
|
487
489
|
}
|
|
488
490
|
function formatModelsList(body, kind) {
|
|
489
491
|
const groups = [
|
|
490
|
-
["images", "
|
|
491
|
-
["video", "
|
|
492
|
-
["chat", "
|
|
493
|
-
["audio", "
|
|
494
|
-
["upscale", "
|
|
495
|
-
["mesh", "
|
|
492
|
+
["images", "\u041A\u0430\u0440\u0442\u0438\u043D\u043A\u0438"],
|
|
493
|
+
["video", "\u0412\u0438\u0434\u0435\u043E"],
|
|
494
|
+
["chat", "\u0427\u0430\u0442"],
|
|
495
|
+
["audio", "\u0410\u0443\u0434\u0438\u043E"],
|
|
496
|
+
["upscale", "\u0410\u043F\u0441\u043A\u0435\u0439\u043B"],
|
|
497
|
+
["mesh", "3D"],
|
|
496
498
|
["switchx", "SwitchX"]
|
|
497
499
|
];
|
|
498
500
|
const lines = [];
|
|
@@ -524,7 +526,7 @@ async function uploadLocal(client, filePath) {
|
|
|
524
526
|
const up = await client.uploadFile({ bytes: file.bytes, filename: file.filename });
|
|
525
527
|
if (!up.ok) fail(up);
|
|
526
528
|
const url = String(asRecord(up.body).url || "").trim();
|
|
527
|
-
if (!url) throw new Error(
|
|
529
|
+
if (!url) throw new Error(`\u0417\u0430\u0433\u0440\u0443\u0437\u043A\u0430 ${basename2(filePath)} \u043D\u0435 \u0432\u0435\u0440\u043D\u0443\u043B\u0430 url`);
|
|
528
530
|
return url;
|
|
529
531
|
}
|
|
530
532
|
function mediaUrls(body) {
|
|
@@ -553,7 +555,11 @@ async function waitForTask(client, taskId, jsonMode) {
|
|
|
553
555
|
const term = terminalStatus(body);
|
|
554
556
|
if (term) {
|
|
555
557
|
if (term !== "completed") {
|
|
556
|
-
throw new Error(
|
|
558
|
+
throw new Error(
|
|
559
|
+
String(
|
|
560
|
+
body.error || (term === "cancelled" ? "\u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044F \u043E\u0442\u043C\u0435\u043D\u0435\u043D\u0430" : "\u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044F \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u0430\u0441\u044C \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439")
|
|
561
|
+
)
|
|
562
|
+
);
|
|
557
563
|
}
|
|
558
564
|
return body;
|
|
559
565
|
}
|
|
@@ -564,13 +570,13 @@ async function waitForTask(client, taskId, jsonMode) {
|
|
|
564
570
|
}
|
|
565
571
|
await sleep(interval * 1e3);
|
|
566
572
|
}
|
|
567
|
-
throw new Error("
|
|
573
|
+
throw new Error("\u0412\u0440\u0435\u043C\u044F \u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u0441\u0442\u0435\u043A\u043B\u043E.");
|
|
568
574
|
}
|
|
569
575
|
async function downloadAll(urls, outDir) {
|
|
570
576
|
const saved = [];
|
|
571
577
|
for (const [i, url] of urls.entries()) {
|
|
572
578
|
const res = await fetch(url);
|
|
573
|
-
if (!res.ok || !res.body) throw new Error(
|
|
579
|
+
if (!res.ok || !res.body) throw new Error(`\u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u0444\u0430\u0439\u043B (HTTP ${res.status})`);
|
|
574
580
|
const extGuess = url.includes(".mp4") ? "mp4" : url.includes(".webm") ? "webm" : "png";
|
|
575
581
|
const dest = `${outDir.replace(/\/+$/, "") || "."}/artillect-${Date.now()}-${i + 1}.${extGuess}`;
|
|
576
582
|
await pipeline(Readable.fromWeb(res.body), createWriteStream(dest));
|
|
@@ -591,7 +597,7 @@ async function cmdBalance(jsonMode) {
|
|
|
591
597
|
const res = await client.getBalance();
|
|
592
598
|
if (!res.ok) fail(res);
|
|
593
599
|
const body = asRecord(res.body);
|
|
594
|
-
printOrJson(jsonMode, body, [
|
|
600
|
+
printOrJson(jsonMode, body, [`\u0411\u0430\u043B\u0430\u043D\u0441: ${body.token_balance ?? 0} \u0442\u043E\u043A\u0435\u043D\u043E\u0432`]);
|
|
595
601
|
}
|
|
596
602
|
async function cmdModels(kind, jsonMode) {
|
|
597
603
|
const cfg = loadCliConfig();
|
|
@@ -599,7 +605,9 @@ async function cmdModels(kind, jsonMode) {
|
|
|
599
605
|
if (cfg.apiKey) headers.Authorization = `Bearer ${cfg.apiKey}`;
|
|
600
606
|
const res = await getJson(cfg.baseUrl, "/api/v1/models", headers);
|
|
601
607
|
if (res.status >= 400) {
|
|
602
|
-
throw new Error(
|
|
608
|
+
throw new Error(
|
|
609
|
+
String(res.json.error || `\u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043A\u0430\u0442\u0430\u043B\u043E\u0433 \u043C\u043E\u0434\u0435\u043B\u0435\u0439 (${res.status})`)
|
|
610
|
+
);
|
|
603
611
|
}
|
|
604
612
|
if (jsonMode) {
|
|
605
613
|
console.log(JSON.stringify(kind ? res.json[kind] ?? res.json : res.json, null, 2));
|
|
@@ -625,16 +633,16 @@ async function cmdGenerateImage(opts) {
|
|
|
625
633
|
const body = asRecord(res.body);
|
|
626
634
|
const taskId = String(body.task_id || body.id || "");
|
|
627
635
|
if (!opts.wait) {
|
|
628
|
-
printOrJson(opts.json, body, [
|
|
636
|
+
printOrJson(opts.json, body, [`\u041E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E ${taskId || "(\u043D\u0435\u0442 task_id)"}`]);
|
|
629
637
|
return;
|
|
630
638
|
}
|
|
631
|
-
if (!taskId) throw new Error("
|
|
639
|
+
if (!taskId) throw new Error("\u0441\u0435\u0440\u0432\u0435\u0440 \u043D\u0435 \u0432\u0435\u0440\u043D\u0443\u043B task_id");
|
|
632
640
|
const done = await waitForTask(client, taskId, opts.json);
|
|
633
641
|
const urls = mediaUrls(done);
|
|
634
642
|
const saved = urls.length ? await downloadAll(urls, opts.out) : [];
|
|
635
643
|
printOrJson(opts.json, { ...done, saved }, [
|
|
636
|
-
|
|
637
|
-
...saved.map((p) =>
|
|
644
|
+
`\u0413\u043E\u0442\u043E\u0432\u043E ${taskId}`,
|
|
645
|
+
...saved.map((p) => `\u0421\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u043E ${p}`),
|
|
638
646
|
...!saved.length ? urls.map((u) => u) : []
|
|
639
647
|
]);
|
|
640
648
|
}
|
|
@@ -649,16 +657,16 @@ async function cmdGenerateVideo(opts) {
|
|
|
649
657
|
const submitted = asRecord(res.body);
|
|
650
658
|
const taskId = String(submitted.task_id || submitted.id || "");
|
|
651
659
|
if (!opts.wait) {
|
|
652
|
-
printOrJson(opts.json, submitted, [
|
|
660
|
+
printOrJson(opts.json, submitted, [`\u041E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043E ${taskId || "(\u043D\u0435\u0442 task_id)"}`]);
|
|
653
661
|
return;
|
|
654
662
|
}
|
|
655
|
-
if (!taskId) throw new Error("
|
|
663
|
+
if (!taskId) throw new Error("\u0441\u0435\u0440\u0432\u0435\u0440 \u043D\u0435 \u0432\u0435\u0440\u043D\u0443\u043B task_id");
|
|
656
664
|
const done = await waitForTask(client, taskId, opts.json);
|
|
657
665
|
const urls = mediaUrls(done);
|
|
658
666
|
const saved = urls.length ? await downloadAll(urls, opts.out) : [];
|
|
659
667
|
printOrJson(opts.json, { ...done, saved }, [
|
|
660
|
-
|
|
661
|
-
...saved.map((p) =>
|
|
668
|
+
`\u0413\u043E\u0442\u043E\u0432\u043E ${taskId}`,
|
|
669
|
+
...saved.map((p) => `\u0421\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u043E ${p}`),
|
|
662
670
|
...!saved.length ? urls.map((u) => u) : []
|
|
663
671
|
]);
|
|
664
672
|
}
|
|
@@ -684,11 +692,11 @@ function parse(raw) {
|
|
|
684
692
|
return [Number(m[1]), Number(m[2]), Number(m[3])];
|
|
685
693
|
}
|
|
686
694
|
function cliVersion() {
|
|
687
|
-
return String("0.1.
|
|
695
|
+
return String("0.1.1");
|
|
688
696
|
}
|
|
689
697
|
function updateAvailableMessage(local, latest) {
|
|
690
|
-
return
|
|
691
|
-
|
|
698
|
+
return `\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F @artillect/cli (${latest}, \u0443 \u0432\u0430\u0441 ${local}).
|
|
699
|
+
\u041E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435: npm i -g @artillect/cli@latest`;
|
|
692
700
|
}
|
|
693
701
|
|
|
694
702
|
// src/updateCheck.ts
|
|
@@ -739,25 +747,23 @@ async function maybeNotifyUpdate() {
|
|
|
739
747
|
|
|
740
748
|
// src/index.ts
|
|
741
749
|
var program = new Command();
|
|
742
|
-
program.name("artillect").description(
|
|
743
|
-
"Artillect CLI \u2014 same Public API v1 as Studio, REST, and MCP. Models come from GET /api/v1/models."
|
|
744
|
-
).version(cliVersion());
|
|
750
|
+
program.name("artillect").description("Artillect CLI \u2014 \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044F \u043A\u0430\u0440\u0442\u0438\u043D\u043E\u043A \u0438 \u0432\u0438\u0434\u0435\u043E \u0438\u0437 \u0442\u0435\u0440\u043C\u0438\u043D\u0430\u043B\u0430.").version(cliVersion());
|
|
745
751
|
program.hook("preAction", async () => {
|
|
746
752
|
await maybeNotifyUpdate();
|
|
747
753
|
});
|
|
748
|
-
var auth = program.command("auth").description("
|
|
749
|
-
auth.command("login").description("
|
|
750
|
-
auth.command("logout").description("
|
|
751
|
-
auth.command("status").description("
|
|
752
|
-
program.command("balance").description("
|
|
754
|
+
var auth = program.command("auth").description("\u0412\u0445\u043E\u0434 (\u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0438\u043B\u0438 ARTILLECT_API_KEY)");
|
|
755
|
+
auth.command("login").description("\u0412\u043E\u0439\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 \u0431\u0440\u0430\u0443\u0437\u0435\u0440").action(authLogin);
|
|
756
|
+
auth.command("logout").description("\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D\u043D\u044B\u0439 \u043A\u043B\u044E\u0447").action(authLogout);
|
|
757
|
+
auth.command("status").description("\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C, \u043F\u043E\u0434 \u043A\u0435\u043C \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D \u0432\u0445\u043E\u0434").action(authStatus);
|
|
758
|
+
program.command("balance").description("\u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u0431\u0430\u043B\u0430\u043D\u0441 \u0442\u043E\u043A\u0435\u043D\u043E\u0432").option("--json", "\u0432\u044B\u0432\u0435\u0441\u0442\u0438 \u0441\u044B\u0440\u043E\u0439 JSON", false).action(async (opts) => {
|
|
753
759
|
await cmdBalance(Boolean(opts.json));
|
|
754
760
|
});
|
|
755
|
-
var models = program.command("models").description("
|
|
756
|
-
models.command("list").description("
|
|
761
|
+
var models = program.command("models").description("\u041A\u0430\u0442\u0430\u043B\u043E\u0433 \u043C\u043E\u0434\u0435\u043B\u0435\u0439 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430");
|
|
762
|
+
models.command("list").description("\u0421\u043F\u0438\u0441\u043E\u043A \u043C\u043E\u0434\u0435\u043B\u0435\u0439").option("-k, --kind <kind>", "images | video | chat | audio | upscale | mesh").option("--json", "\u0432\u044B\u0432\u0435\u0441\u0442\u0438 \u0441\u044B\u0440\u043E\u0439 JSON", false).action(async (opts) => {
|
|
757
763
|
await cmdModels(opts.kind, Boolean(opts.json));
|
|
758
764
|
});
|
|
759
|
-
var generate = program.command("generate").description("
|
|
760
|
-
generate.command("image").description("
|
|
765
|
+
var generate = program.command("generate").description("\u0417\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u0433\u0435\u043D\u0435\u0440\u0430\u0446\u0438\u044E");
|
|
766
|
+
generate.command("image").description("\u041A\u0430\u0440\u0442\u0438\u043D\u043A\u0430 \u043F\u043E \u0442\u0435\u043A\u0441\u0442\u0443 \u0438\u043B\u0438 \u043F\u0440\u0430\u0432\u043A\u0430 \u043F\u043E \u0440\u0435\u0444\u0435\u0440\u0435\u043D\u0441\u0430\u043C").requiredOption("-p, --prompt <text>", "\u043F\u0440\u043E\u043C\u043F\u0442").option("-m, --model <slug>", "\u0441\u043B\u0430\u0433 \u043C\u043E\u0434\u0435\u043B\u0438 (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E gpt-image-2)").option("-i, --input <file...>", "\u043B\u043E\u043A\u0430\u043B\u044C\u043D\u044B\u0435 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438-\u0440\u0435\u0444\u0435\u0440\u0435\u043D\u0441\u044B").option("-w, --wait", "\u0434\u043E\u0436\u0434\u0430\u0442\u044C\u0441\u044F \u0433\u043E\u0442\u043E\u0432\u043D\u043E\u0441\u0442\u0438 \u0438 \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442", false).option("-o, --out <dir>", "\u043F\u0430\u043F\u043A\u0430 \u0434\u043B\u044F \u0444\u0430\u0439\u043B\u043E\u0432", ".").option("--json", "\u0432\u044B\u0432\u0435\u0441\u0442\u0438 \u0441\u044B\u0440\u043E\u0439 JSON", false).action(
|
|
761
767
|
async (opts) => {
|
|
762
768
|
await cmdGenerateImage({
|
|
763
769
|
prompt: opts.prompt,
|
|
@@ -769,7 +775,7 @@ generate.command("image").description("Text-to-image or image edit").requiredOpt
|
|
|
769
775
|
});
|
|
770
776
|
}
|
|
771
777
|
);
|
|
772
|
-
generate.command("video").description("
|
|
778
|
+
generate.command("video").description("\u0412\u0438\u0434\u0435\u043E \u043F\u043E \u0442\u0435\u043A\u0441\u0442\u0443 \u0438\u043B\u0438 \u043A\u0430\u0434\u0440\u0430\u043C").argument("[model]", "\u0441\u043B\u0430\u0433 \u0432\u0438\u0434\u0435\u043E\u043C\u043E\u0434\u0435\u043B\u0438 (\u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E kling-3-turbo)").requiredOption("-p, --prompt <text>", "\u043F\u0440\u043E\u043C\u043F\u0442").option("-m, --model <slug>", "\u0441\u043B\u0430\u0433 \u043C\u043E\u0434\u0435\u043B\u0438 (\u0435\u0441\u043B\u0438 \u043D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u043C)").option("--start-image <file>", "\u043B\u043E\u043A\u0430\u043B\u044C\u043D\u044B\u0439 \u0441\u0442\u0430\u0440\u0442\u043E\u0432\u044B\u0439 \u043A\u0430\u0434\u0440").option("--end-image <file>", "\u043B\u043E\u043A\u0430\u043B\u044C\u043D\u044B\u0439 \u0444\u0438\u043D\u0430\u043B\u044C\u043D\u044B\u0439 \u043A\u0430\u0434\u0440").option("-w, --wait", "\u0434\u043E\u0436\u0434\u0430\u0442\u044C\u0441\u044F \u0433\u043E\u0442\u043E\u0432\u043D\u043E\u0441\u0442\u0438 \u0438 \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442", false).option("-o, --out <dir>", "\u043F\u0430\u043F\u043A\u0430 \u0434\u043B\u044F \u0444\u0430\u0439\u043B\u043E\u0432", ".").option("--json", "\u0432\u044B\u0432\u0435\u0441\u0442\u0438 \u0441\u044B\u0440\u043E\u0439 JSON", false).action(
|
|
773
779
|
async (positionalModel, opts) => {
|
|
774
780
|
const model = String(opts.model || positionalModel || "kling-3-turbo").trim();
|
|
775
781
|
await cmdGenerateVideo({
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@artillect/cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Artillect CLI —
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Artillect CLI — генерация картинок и видео из терминала.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"bin": {
|
|
@@ -14,12 +14,7 @@
|
|
|
14
14
|
"publishConfig": {
|
|
15
15
|
"access": "public"
|
|
16
16
|
},
|
|
17
|
-
"
|
|
18
|
-
"type": "git",
|
|
19
|
-
"url": "https://git.krem.digital/diffusionbooth/artillect.git",
|
|
20
|
-
"directory": "packages/artillect-cli"
|
|
21
|
-
},
|
|
22
|
-
"homepage": "https://app.artillect.pro/docs",
|
|
17
|
+
"homepage": "https://app.artillect.pro/docs/cli",
|
|
23
18
|
"bugs": {
|
|
24
19
|
"url": "https://app.artillect.pro/feedback"
|
|
25
20
|
},
|