ima2-gen 1.1.9 → 1.1.10
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 +4 -0
- package/bin/commands/annotate.js +5 -3
- package/bin/commands/annotate.ts +13 -12
- package/bin/commands/cancel.js +5 -2
- package/bin/commands/cancel.ts +6 -3
- package/bin/commands/canvas-versions.js +4 -4
- package/bin/commands/canvas-versions.ts +10 -10
- package/bin/commands/cardnews.js +3 -1
- package/bin/commands/cardnews.ts +18 -17
- package/bin/commands/comfy.js +2 -2
- package/bin/commands/comfy.ts +4 -4
- package/bin/commands/config.ts +6 -6
- package/bin/commands/edit.js +11 -8
- package/bin/commands/edit.ts +12 -9
- package/bin/commands/gen.js +16 -13
- package/bin/commands/gen.ts +20 -17
- package/bin/commands/history.js +2 -1
- package/bin/commands/history.ts +11 -10
- package/bin/commands/ls.js +7 -4
- package/bin/commands/ls.ts +13 -10
- package/bin/commands/metadata.js +4 -1
- package/bin/commands/metadata.ts +5 -2
- package/bin/commands/multimode.js +4 -4
- package/bin/commands/multimode.ts +5 -6
- package/bin/commands/node.js +7 -7
- package/bin/commands/node.ts +14 -14
- package/bin/commands/observability.js +6 -6
- package/bin/commands/observability.ts +20 -20
- package/bin/commands/ping.js +4 -2
- package/bin/commands/ping.ts +5 -3
- package/bin/commands/prompt.js +14 -11
- package/bin/commands/prompt.ts +40 -38
- package/bin/commands/ps.js +9 -6
- package/bin/commands/ps.ts +14 -11
- package/bin/commands/session.js +4 -3
- package/bin/commands/session.ts +23 -22
- package/bin/commands/show.js +5 -2
- package/bin/commands/show.ts +8 -5
- package/bin/ima2.js +4 -4
- package/bin/ima2.ts +6 -6
- package/bin/lib/args.ts +20 -1
- package/bin/lib/client.ts +20 -7
- package/bin/lib/error-hints.ts +3 -3
- package/bin/lib/files.ts +8 -8
- package/bin/lib/output.js +19 -17
- package/bin/lib/output.ts +38 -23
- package/bin/lib/platform.js +3 -1
- package/bin/lib/platform.ts +9 -7
- package/bin/lib/star-prompt.ts +1 -1
- package/bin/lib/storage-doctor.ts +3 -2
- package/config.js +1 -1
- package/config.ts +8 -6
- package/docs/migration/runtime-test-inventory.md +135 -0
- package/lib/assetLifecycle.ts +8 -8
- package/lib/canvasVersionStore.ts +52 -12
- package/lib/cardNewsGenerator.js +7 -3
- package/lib/cardNewsGenerator.ts +117 -14
- package/lib/cardNewsJobStore.ts +47 -12
- package/lib/cardNewsManifestStore.js +13 -6
- package/lib/cardNewsManifestStore.ts +56 -14
- package/lib/cardNewsPlanner.js +11 -9
- package/lib/cardNewsPlanner.ts +86 -30
- package/lib/cardNewsPlannerClient.js +23 -10
- package/lib/cardNewsPlannerClient.ts +58 -17
- package/lib/cardNewsPlannerSchema.js +43 -36
- package/lib/cardNewsPlannerSchema.ts +120 -58
- package/lib/cardNewsTemplateStore.js +20 -35
- package/lib/cardNewsTemplateStore.ts +100 -58
- package/lib/codexDetect.js +5 -3
- package/lib/codexDetect.ts +5 -3
- package/lib/comfyBridge.js +3 -1
- package/lib/comfyBridge.ts +37 -16
- package/lib/db.ts +5 -5
- package/lib/errInfo.js +32 -0
- package/lib/errInfo.ts +43 -0
- package/lib/errorClassify.ts +2 -2
- package/lib/generationErrors.ts +37 -11
- package/lib/historyList.js +10 -6
- package/lib/historyList.ts +17 -13
- package/lib/imageMetadata.js +1 -1
- package/lib/imageMetadata.ts +8 -8
- package/lib/imageMetadataStore.ts +6 -6
- package/lib/imageModels.ts +6 -4
- package/lib/inflight.js +1 -8
- package/lib/inflight.ts +59 -16
- package/lib/localImportStore.ts +6 -5
- package/lib/logger.js +7 -5
- package/lib/logger.ts +34 -23
- package/lib/nodeStore.ts +18 -10
- package/lib/oauthLauncher.js +2 -2
- package/lib/oauthLauncher.ts +7 -6
- package/lib/oauthNormalize.ts +1 -1
- package/lib/oauthProxy/errors.js +93 -0
- package/lib/oauthProxy/errors.ts +128 -0
- package/lib/oauthProxy/generators.js +426 -0
- package/lib/oauthProxy/generators.ts +494 -0
- package/lib/oauthProxy/index.js +8 -0
- package/lib/oauthProxy/index.ts +28 -0
- package/lib/oauthProxy/prompts.js +84 -0
- package/lib/oauthProxy/prompts.ts +108 -0
- package/lib/oauthProxy/references.js +32 -0
- package/lib/oauthProxy/references.ts +45 -0
- package/lib/oauthProxy/runtime.js +101 -0
- package/lib/oauthProxy/runtime.ts +115 -0
- package/lib/oauthProxy/streams.js +211 -0
- package/lib/oauthProxy/streams.ts +232 -0
- package/lib/oauthProxy/types.js +6 -0
- package/lib/oauthProxy/types.ts +9 -0
- package/lib/oauthProxy.js +3 -911
- package/lib/oauthProxy.ts +3 -995
- package/lib/openDirectory.js +4 -2
- package/lib/openDirectory.ts +8 -6
- package/lib/pngInfo.ts +2 -2
- package/lib/promptImport/curatedSources.ts +4 -2
- package/lib/promptImport/discoveryRegistry.js +17 -9
- package/lib/promptImport/discoveryRegistry.ts +121 -28
- package/lib/promptImport/errors.ts +6 -6
- package/lib/promptImport/githubDiscovery.js +13 -7
- package/lib/promptImport/githubDiscovery.ts +84 -23
- package/lib/promptImport/githubFolder.js +22 -14
- package/lib/promptImport/githubFolder.ts +130 -41
- package/lib/promptImport/githubSource.js +3 -1
- package/lib/promptImport/githubSource.ts +32 -14
- package/lib/promptImport/gptImageHints.ts +10 -8
- package/lib/promptImport/parsePromptCandidates.js +2 -0
- package/lib/promptImport/parsePromptCandidates.ts +43 -17
- package/lib/promptImport/promptIndex.js +33 -23
- package/lib/promptImport/promptIndex.ts +124 -46
- package/lib/promptImport/rankPromptCandidates.js +2 -2
- package/lib/promptImport/rankPromptCandidates.ts +22 -6
- package/lib/promptImport/types.js +1 -0
- package/lib/promptImport/types.ts +103 -0
- package/lib/promptSafetyPolicy.js +5 -0
- package/lib/promptSafetyPolicy.ts +5 -0
- package/lib/providerOptions.ts +3 -2
- package/lib/referenceImageCompress.ts +15 -6
- package/lib/refs.js +2 -0
- package/lib/refs.ts +27 -11
- package/lib/requestLogger.ts +4 -3
- package/lib/responsesImageAdapter.js +16 -10
- package/lib/responsesImageAdapter.ts +109 -31
- package/lib/runtimeContext.js +100 -0
- package/lib/runtimeContext.ts +131 -0
- package/lib/runtimePorts.js +2 -1
- package/lib/runtimePorts.ts +28 -16
- package/lib/sessionStore.js +7 -5
- package/lib/sessionStore.ts +73 -37
- package/lib/storageMigration.js +18 -11
- package/lib/storageMigration.ts +63 -37
- package/lib/styleSheet.js +7 -6
- package/lib/styleSheet.ts +34 -23
- package/package.json +4 -2
- package/routes/annotations.js +9 -4
- package/routes/annotations.ts +35 -12
- package/routes/canvasVersions.js +8 -3
- package/routes/canvasVersions.ts +14 -9
- package/routes/cardNews.js +31 -18
- package/routes/cardNews.ts +66 -38
- package/routes/comfy.js +6 -3
- package/routes/comfy.ts +10 -6
- package/routes/edit.js +9 -5
- package/routes/edit.ts +30 -10
- package/routes/generate.js +33 -21
- package/routes/generate.ts +43 -29
- package/routes/health.js +7 -3
- package/routes/health.ts +15 -10
- package/routes/history.js +29 -14
- package/routes/history.ts +41 -23
- package/routes/imageImport.js +6 -2
- package/routes/imageImport.ts +9 -5
- package/routes/index.js +3 -1
- package/routes/index.ts +4 -1
- package/routes/metadata.js +9 -4
- package/routes/metadata.ts +13 -7
- package/routes/multimode.js +17 -11
- package/routes/multimode.ts +40 -19
- package/routes/nodes.js +30 -20
- package/routes/nodes.ts +73 -34
- package/routes/promptImport.js +42 -36
- package/routes/promptImport.ts +89 -64
- package/routes/prompts.js +62 -39
- package/routes/prompts.ts +120 -71
- package/routes/sessions.js +46 -24
- package/routes/sessions.ts +60 -35
- package/routes/storage.js +4 -2
- package/routes/storage.ts +13 -5
- package/server.js +25 -21
- package/server.ts +57 -37
- package/ui/dist/.vite/manifest.json +11 -10
- package/ui/dist/assets/{CardNewsWorkspace-BJOCey7Z.js → CardNewsWorkspace-C9Cpxuxc.js} +1 -1
- package/ui/dist/assets/{NodeCanvas-C3dzYNsk.js → NodeCanvas-BllpfcQW.js} +1 -1
- package/ui/dist/assets/{PromptImportDialog-Dqu1VpUh.js → PromptImportDialog-D8EMO--u.js} +2 -2
- package/ui/dist/assets/{PromptImportDiscoverySection-Dg8T9X0L.js → PromptImportDiscoverySection-BB2FrKuq.js} +1 -1
- package/ui/dist/assets/{PromptImportFolderSection-DBaqsFO4.js → PromptImportFolderSection-aVteBUcb.js} +1 -1
- package/ui/dist/assets/PromptLibraryPanel-Z-4B8RSs.js +2 -0
- package/ui/dist/assets/SettingsWorkspace-DBYdgpPI.js +1 -0
- package/ui/dist/assets/index-B2TDuGqy.css +1 -0
- package/ui/dist/assets/index-DFlbOIxI.js +25 -0
- package/ui/dist/assets/{index-Cvld7dUZ.js → index-Deo5wBiA.js} +1 -1
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/PromptLibraryPanel-p5QqR97M.js +0 -2
- package/ui/dist/assets/SettingsWorkspace-B5bSAZ6u.js +0 -1
- package/ui/dist/assets/index-C9cXwiWE.js +0 -25
- package/ui/dist/assets/index-CGMIkZXn.css +0 -1
package/bin/commands/edit.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { fileToDataUri, dataUriToFile, defaultOutName } from "../lib/files.js";
|
|
|
4
4
|
import { out, die, dieWithError, color, json } from "../lib/output.js";
|
|
5
5
|
import { config } from "../../config.js";
|
|
6
6
|
|
|
7
|
+
import { errInfo } from "../../lib/errInfo.js";
|
|
7
8
|
const VALID_MODES = new Set(["auto", "direct"]);
|
|
8
9
|
const VALID_MODERATION = new Set(["auto", "low"]);
|
|
9
10
|
const KNOWN_IMAGE_MODELS = new Set(["gpt-5.5", "gpt-5.4", "gpt-5.4-mini", "gpt-5.3-codex-spark"]);
|
|
@@ -47,19 +48,19 @@ const HELP = `
|
|
|
47
48
|
--web-search / --no-web-search Override default web-search toggle
|
|
48
49
|
`;
|
|
49
50
|
|
|
50
|
-
export default async function editCmd(argv) {
|
|
51
|
+
export default async function editCmd(argv: string[]) {
|
|
51
52
|
const args = parseArgs(argv, SPEC);
|
|
52
53
|
if (args.help) { out(HELP); return; }
|
|
53
54
|
const input = args.positional[0];
|
|
54
55
|
if (!input) die(2, "input image path required");
|
|
55
56
|
if (!args.prompt) die(2, "--prompt is required");
|
|
56
|
-
if (!VALID_MODES.has(args.mode)) die(2, "--mode must be one of: auto, direct");
|
|
57
|
-
if (!VALID_MODERATION.has(args.moderation)) die(2, "--moderation must be one of: auto, low");
|
|
58
|
-
if (args.model && !KNOWN_IMAGE_MODELS.has(args.model)) {
|
|
57
|
+
if (!VALID_MODES.has(String(args.mode))) die(2, "--mode must be one of: auto, direct");
|
|
58
|
+
if (!VALID_MODERATION.has(String(args.moderation))) die(2, "--moderation must be one of: auto, low");
|
|
59
|
+
if (args.model && !KNOWN_IMAGE_MODELS.has(String(args.model))) {
|
|
59
60
|
die(2, "--model must be one of: gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.3-codex-spark");
|
|
60
61
|
}
|
|
61
62
|
const VALID_REASONING = new Set(["none", "low", "medium", "high", "xhigh"]);
|
|
62
|
-
if (args["reasoning-effort"] && !VALID_REASONING.has(args["reasoning-effort"])) {
|
|
63
|
+
if (args["reasoning-effort"] && !VALID_REASONING.has(String(args["reasoning-effort"]))) {
|
|
63
64
|
die(2, "--reasoning-effort must be one of: none, low, medium, high, xhigh");
|
|
64
65
|
}
|
|
65
66
|
if (args["web-search"] && args["no-web-search"]) {
|
|
@@ -69,14 +70,15 @@ export default async function editCmd(argv) {
|
|
|
69
70
|
let server;
|
|
70
71
|
try { server = await resolveServer({ serverFlag: args.server }); }
|
|
71
72
|
catch (e) {
|
|
72
|
-
|
|
73
|
+
const err = errInfo(e);
|
|
74
|
+
if (args.json) json({ ok: false, error: err.message, code: err.code, status: err.status });
|
|
73
75
|
dieWithError(e);
|
|
74
76
|
}
|
|
75
77
|
|
|
76
78
|
const imageDataUri = await fileToDataUri(input);
|
|
77
79
|
const imageB64 = imageDataUri.split(",")[1];
|
|
78
80
|
|
|
79
|
-
const timeoutMs = (parseInt(args.timeout) || 180) * 1000;
|
|
81
|
+
const timeoutMs = (parseInt(String(args.timeout)) || 180) * 1000;
|
|
80
82
|
let resp;
|
|
81
83
|
try {
|
|
82
84
|
const editBody: any = {
|
|
@@ -98,14 +100,15 @@ export default async function editCmd(argv) {
|
|
|
98
100
|
timeoutMs,
|
|
99
101
|
});
|
|
100
102
|
} catch (e) {
|
|
101
|
-
|
|
103
|
+
const err = errInfo(e);
|
|
104
|
+
if (args.json) json({ ok: false, error: err.message, code: err.code });
|
|
102
105
|
dieWithError(e);
|
|
103
106
|
}
|
|
104
107
|
|
|
105
108
|
const image = resp.image;
|
|
106
109
|
if (!image) die(1, "server returned no image");
|
|
107
110
|
const target = args.out || `${config.storage.generatedDir}/${defaultOutName(0, 1)}`;
|
|
108
|
-
await dataUriToFile(image, target);
|
|
111
|
+
await dataUriToFile(image, String(target));
|
|
109
112
|
|
|
110
113
|
if (args.json) {
|
|
111
114
|
json({ ok: true, path: target, requestId: resp.requestId, elapsed: resp.elapsed });
|
package/bin/commands/gen.js
CHANGED
|
@@ -3,6 +3,7 @@ import { resolveServer, request, normalizeGenerate } from "../lib/client.js";
|
|
|
3
3
|
import { fileToDataUri, dataUriToFile, defaultOutName, readStdin } from "../lib/files.js";
|
|
4
4
|
import { out, die, dieWithError, color, json } from "../lib/output.js";
|
|
5
5
|
import { config } from "../../config.js";
|
|
6
|
+
import { errInfo } from "../../lib/errInfo.js";
|
|
6
7
|
const VALID_MODES = new Set(["auto", "direct"]);
|
|
7
8
|
const VALID_MODERATION = new Set(["auto", "low"]);
|
|
8
9
|
const KNOWN_IMAGE_MODELS = new Set(["gpt-5.5", "gpt-5.4", "gpt-5.4-mini", "gpt-5.3-codex-spark"]);
|
|
@@ -75,32 +76,33 @@ export default async function genCmd(argv) {
|
|
|
75
76
|
}
|
|
76
77
|
if (!prompt)
|
|
77
78
|
die(2, "prompt is required (positional or via --stdin)");
|
|
78
|
-
const refs = args.ref
|
|
79
|
+
const refs = (Array.isArray(args.ref) ? args.ref : []);
|
|
79
80
|
if (refs.length > 5)
|
|
80
81
|
die(2, "max 5 --ref attachments");
|
|
81
|
-
if (!VALID_MODES.has(args.mode))
|
|
82
|
+
if (!VALID_MODES.has(String(args.mode)))
|
|
82
83
|
die(2, "--mode must be one of: auto, direct");
|
|
83
|
-
if (!VALID_MODERATION.has(args.moderation))
|
|
84
|
+
if (!VALID_MODERATION.has(String(args.moderation)))
|
|
84
85
|
die(2, "--moderation must be one of: auto, low");
|
|
85
|
-
if (args.model && !KNOWN_IMAGE_MODELS.has(args.model)) {
|
|
86
|
+
if (args.model && !KNOWN_IMAGE_MODELS.has(String(args.model))) {
|
|
86
87
|
die(2, "--model must be one of: gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.3-codex-spark");
|
|
87
88
|
}
|
|
88
89
|
const VALID_REASONING = new Set(["none", "low", "medium", "high", "xhigh"]);
|
|
89
|
-
if (args["reasoning-effort"] && !VALID_REASONING.has(args["reasoning-effort"])) {
|
|
90
|
+
if (args["reasoning-effort"] && !VALID_REASONING.has(String(args["reasoning-effort"]))) {
|
|
90
91
|
die(2, "--reasoning-effort must be one of: none, low, medium, high, xhigh");
|
|
91
92
|
}
|
|
92
93
|
if (args["web-search"] && args["no-web-search"]) {
|
|
93
94
|
die(2, "--web-search and --no-web-search are mutually exclusive");
|
|
94
95
|
}
|
|
95
|
-
const n = Math.max(1, Math.min(8, parseInt(args.count) || 1));
|
|
96
|
-
const timeoutMs = (parseInt(args.timeout) || 180) * 1000;
|
|
96
|
+
const n = Math.max(1, Math.min(8, parseInt(String(args.count)) || 1));
|
|
97
|
+
const timeoutMs = (parseInt(String(args.timeout)) || 180) * 1000;
|
|
97
98
|
let server;
|
|
98
99
|
try {
|
|
99
100
|
server = await resolveServer({ serverFlag: args.server });
|
|
100
101
|
}
|
|
101
102
|
catch (e) {
|
|
103
|
+
const err = errInfo(e);
|
|
102
104
|
if (args.json)
|
|
103
|
-
json({ ok: false, error:
|
|
105
|
+
json({ ok: false, error: err.message, code: err.code, status: err.status });
|
|
104
106
|
dieWithError(e);
|
|
105
107
|
}
|
|
106
108
|
const references = await Promise.all(refs.map((p) => fileToDataUri(p)));
|
|
@@ -126,8 +128,9 @@ export default async function genCmd(argv) {
|
|
|
126
128
|
resp = await request(server.base, "/api/generate", { method: "POST", body, timeoutMs });
|
|
127
129
|
}
|
|
128
130
|
catch (e) {
|
|
131
|
+
const err = errInfo(e);
|
|
129
132
|
if (args.json)
|
|
130
|
-
json({ ok: false, error:
|
|
133
|
+
json({ ok: false, error: err.message, code: err.code, status: err.status });
|
|
131
134
|
dieWithError(e);
|
|
132
135
|
}
|
|
133
136
|
const norm = normalizeGenerate(resp);
|
|
@@ -135,7 +138,7 @@ export default async function genCmd(argv) {
|
|
|
135
138
|
die(1, "server returned no images");
|
|
136
139
|
// --no-save path
|
|
137
140
|
if (args["no-save"]) {
|
|
138
|
-
const totalBytes = norm.images.reduce((s, im) => s + im.image
|
|
141
|
+
const totalBytes = norm.images.reduce((s, im) => s + (im.image?.length ?? 0), 0);
|
|
139
142
|
if (process.stdout.isTTY && totalBytes > 2 * 1024 * 1024 && !args.force) {
|
|
140
143
|
die(2, "refusing to print >2MB of b64 to TTY; use --force or drop --no-save");
|
|
141
144
|
}
|
|
@@ -144,8 +147,8 @@ export default async function genCmd(argv) {
|
|
|
144
147
|
return;
|
|
145
148
|
}
|
|
146
149
|
// Save path
|
|
147
|
-
const outDir = args["out-dir"]
|
|
148
|
-
const explicitOut = args.out
|
|
150
|
+
const outDir = args["out-dir"] ? String(args["out-dir"]) : null;
|
|
151
|
+
const explicitOut = args.out ? String(args.out) : null;
|
|
149
152
|
if (explicitOut && norm.images.length > 1) {
|
|
150
153
|
die(2, "--out only supports a single image; use --out-dir for n>1");
|
|
151
154
|
}
|
|
@@ -162,7 +165,7 @@ export default async function genCmd(argv) {
|
|
|
162
165
|
else {
|
|
163
166
|
target = `${config.storage.generatedDir}/${defaultOutName(i, norm.images.length)}`;
|
|
164
167
|
}
|
|
165
|
-
await dataUriToFile(im.image, target);
|
|
168
|
+
await dataUriToFile(String(im.image), target);
|
|
166
169
|
savedPaths.push(target);
|
|
167
170
|
}
|
|
168
171
|
if (args.json) {
|
package/bin/commands/gen.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { fileToDataUri, dataUriToFile, defaultOutName, readStdin } from "../lib/
|
|
|
4
4
|
import { out, die, dieWithError, color, json } from "../lib/output.js";
|
|
5
5
|
import { config } from "../../config.js";
|
|
6
6
|
|
|
7
|
+
import { errInfo } from "../../lib/errInfo.js";
|
|
7
8
|
const VALID_MODES = new Set(["auto", "direct"]);
|
|
8
9
|
const VALID_MODERATION = new Set(["auto", "low"]);
|
|
9
10
|
const KNOWN_IMAGE_MODELS = new Set(["gpt-5.5", "gpt-5.4", "gpt-5.4-mini", "gpt-5.3-codex-spark"]);
|
|
@@ -65,7 +66,7 @@ const HELP = `
|
|
|
65
66
|
cat prompt.txt | ima2 gen --stdin -n 2 -d ./out
|
|
66
67
|
`;
|
|
67
68
|
|
|
68
|
-
export default async function genCmd(argv) {
|
|
69
|
+
export default async function genCmd(argv: string[]) {
|
|
69
70
|
const args = parseArgs(argv, SPEC);
|
|
70
71
|
if (args.help) { out(HELP); return; }
|
|
71
72
|
|
|
@@ -76,33 +77,34 @@ export default async function genCmd(argv) {
|
|
|
76
77
|
}
|
|
77
78
|
if (!prompt) die(2, "prompt is required (positional or via --stdin)");
|
|
78
79
|
|
|
79
|
-
const refs = args.ref
|
|
80
|
+
const refs = (Array.isArray(args.ref) ? args.ref : []) as string[];
|
|
80
81
|
if (refs.length > 5) die(2, "max 5 --ref attachments");
|
|
81
|
-
if (!VALID_MODES.has(args.mode)) die(2, "--mode must be one of: auto, direct");
|
|
82
|
-
if (!VALID_MODERATION.has(args.moderation)) die(2, "--moderation must be one of: auto, low");
|
|
83
|
-
if (args.model && !KNOWN_IMAGE_MODELS.has(args.model)) {
|
|
82
|
+
if (!VALID_MODES.has(String(args.mode))) die(2, "--mode must be one of: auto, direct");
|
|
83
|
+
if (!VALID_MODERATION.has(String(args.moderation))) die(2, "--moderation must be one of: auto, low");
|
|
84
|
+
if (args.model && !KNOWN_IMAGE_MODELS.has(String(args.model))) {
|
|
84
85
|
die(2, "--model must be one of: gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.3-codex-spark");
|
|
85
86
|
}
|
|
86
87
|
const VALID_REASONING = new Set(["none", "low", "medium", "high", "xhigh"]);
|
|
87
|
-
if (args["reasoning-effort"] && !VALID_REASONING.has(args["reasoning-effort"])) {
|
|
88
|
+
if (args["reasoning-effort"] && !VALID_REASONING.has(String(args["reasoning-effort"]))) {
|
|
88
89
|
die(2, "--reasoning-effort must be one of: none, low, medium, high, xhigh");
|
|
89
90
|
}
|
|
90
91
|
if (args["web-search"] && args["no-web-search"]) {
|
|
91
92
|
die(2, "--web-search and --no-web-search are mutually exclusive");
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
const n = Math.max(1, Math.min(8, parseInt(args.count) || 1));
|
|
95
|
-
const timeoutMs = (parseInt(args.timeout) || 180) * 1000;
|
|
95
|
+
const n = Math.max(1, Math.min(8, parseInt(String(args.count)) || 1));
|
|
96
|
+
const timeoutMs = (parseInt(String(args.timeout)) || 180) * 1000;
|
|
96
97
|
|
|
97
98
|
let server;
|
|
98
99
|
try {
|
|
99
100
|
server = await resolveServer({ serverFlag: args.server });
|
|
100
101
|
} catch (e) {
|
|
101
|
-
|
|
102
|
+
const err = errInfo(e);
|
|
103
|
+
if (args.json) json({ ok: false, error: err.message, code: err.code, status: err.status });
|
|
102
104
|
dieWithError(e);
|
|
103
105
|
}
|
|
104
106
|
|
|
105
|
-
const references = await Promise.all(refs.map((p) => fileToDataUri(p)));
|
|
107
|
+
const references = await Promise.all(refs.map((p: string) => fileToDataUri(p)));
|
|
106
108
|
|
|
107
109
|
const body: any = {
|
|
108
110
|
prompt,
|
|
@@ -123,7 +125,8 @@ export default async function genCmd(argv) {
|
|
|
123
125
|
try {
|
|
124
126
|
resp = await request(server.base, "/api/generate", { method: "POST", body, timeoutMs });
|
|
125
127
|
} catch (e) {
|
|
126
|
-
|
|
128
|
+
const err = errInfo(e);
|
|
129
|
+
if (args.json) json({ ok: false, error: err.message, code: err.code, status: err.status });
|
|
127
130
|
dieWithError(e);
|
|
128
131
|
}
|
|
129
132
|
|
|
@@ -132,7 +135,7 @@ export default async function genCmd(argv) {
|
|
|
132
135
|
|
|
133
136
|
// --no-save path
|
|
134
137
|
if (args["no-save"]) {
|
|
135
|
-
const totalBytes = norm.images.reduce((s, im) => s + im.image
|
|
138
|
+
const totalBytes = norm.images.reduce((s: number, im) => s + (im.image?.length ?? 0), 0);
|
|
136
139
|
if (process.stdout.isTTY && totalBytes > 2 * 1024 * 1024 && !args.force) {
|
|
137
140
|
die(2, "refusing to print >2MB of b64 to TTY; use --force or drop --no-save");
|
|
138
141
|
}
|
|
@@ -141,16 +144,16 @@ export default async function genCmd(argv) {
|
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
// Save path
|
|
144
|
-
const outDir = args["out-dir"]
|
|
145
|
-
const explicitOut = args.out
|
|
147
|
+
const outDir = args["out-dir"] ? String(args["out-dir"]) : null;
|
|
148
|
+
const explicitOut = args.out ? String(args.out) : null;
|
|
146
149
|
if (explicitOut && norm.images.length > 1) {
|
|
147
150
|
die(2, "--out only supports a single image; use --out-dir for n>1");
|
|
148
151
|
}
|
|
149
152
|
|
|
150
|
-
const savedPaths = [];
|
|
153
|
+
const savedPaths: string[] = [];
|
|
151
154
|
for (let i = 0; i < norm.images.length; i++) {
|
|
152
155
|
const im = norm.images[i];
|
|
153
|
-
let target;
|
|
156
|
+
let target: string;
|
|
154
157
|
if (explicitOut) {
|
|
155
158
|
target = explicitOut;
|
|
156
159
|
} else if (outDir) {
|
|
@@ -158,7 +161,7 @@ export default async function genCmd(argv) {
|
|
|
158
161
|
} else {
|
|
159
162
|
target = `${config.storage.generatedDir}/${defaultOutName(i, norm.images.length)}`;
|
|
160
163
|
}
|
|
161
|
-
await dataUriToFile(im.image, target);
|
|
164
|
+
await dataUriToFile(String(im.image), target);
|
|
162
165
|
savedPaths.push(target);
|
|
163
166
|
}
|
|
164
167
|
|
package/bin/commands/history.js
CHANGED
|
@@ -36,7 +36,8 @@ async function getServer(args) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
function handle(e) {
|
|
39
|
-
|
|
39
|
+
const err = e;
|
|
40
|
+
die(exitCodeForError(e), `${err.message}${err.code ? ` (${err.code})` : ""}`);
|
|
40
41
|
}
|
|
41
42
|
async function readLine() {
|
|
42
43
|
return new Promise((resolve) => {
|
package/bin/commands/history.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFile } from "fs/promises";
|
|
2
2
|
import { extname, basename } from "path";
|
|
3
|
-
import { parseArgs } from "../lib/args.js";
|
|
3
|
+
import { parseArgs, type ParsedArgs } from "../lib/args.js";
|
|
4
4
|
import { resolveServer, request } from "../lib/client.js";
|
|
5
5
|
import { out, die, color, json, exitCodeForError } from "../lib/output.js";
|
|
6
6
|
import { getCliBrowserId } from "../lib/browser-id.js";
|
|
@@ -29,20 +29,21 @@ const COMMON_FLAGS = {
|
|
|
29
29
|
help: { short: "h", type: "boolean" },
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
async function getServer(args) {
|
|
32
|
+
async function getServer(args: ParsedArgs) {
|
|
33
33
|
try { return await resolveServer({ serverFlag: args.server }); }
|
|
34
34
|
catch (e: any) { die(exitCodeForError(e), e.message); throw e; }
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function handle(e) {
|
|
38
|
-
|
|
37
|
+
function handle(e: unknown) {
|
|
38
|
+
const err = e as { message?: string; code?: string };
|
|
39
|
+
die(exitCodeForError(e), `${err.message}${err.code ? ` (${err.code})` : ""}`);
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
async function readLine(): Promise<string> {
|
|
42
43
|
return new Promise((resolve) => {
|
|
43
44
|
let buf = "";
|
|
44
45
|
process.stdin.setEncoding("utf-8");
|
|
45
|
-
const onData = (chunk) => {
|
|
46
|
+
const onData = (chunk: Buffer | string) => {
|
|
46
47
|
buf += chunk;
|
|
47
48
|
const nl = buf.indexOf("\n");
|
|
48
49
|
if (nl !== -1) {
|
|
@@ -56,7 +57,7 @@ async function readLine(): Promise<string> {
|
|
|
56
57
|
});
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
async function rmSub(argv) {
|
|
60
|
+
async function rmSub(argv: string[]) {
|
|
60
61
|
const args = parseArgs(argv, { flags: COMMON_FLAGS });
|
|
61
62
|
const filename = args.positional[0];
|
|
62
63
|
if (!filename) die(2, "filename required");
|
|
@@ -76,7 +77,7 @@ async function rmSub(argv) {
|
|
|
76
77
|
if (resp?.trashId) out(color.dim(` trashId: ${resp.trashId}`));
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
async function restoreSub(argv) {
|
|
80
|
+
async function restoreSub(argv: string[]) {
|
|
80
81
|
const args = parseArgs(argv, { flags: COMMON_FLAGS });
|
|
81
82
|
const filename = args.positional[0];
|
|
82
83
|
if (!filename) die(2, "filename required");
|
|
@@ -91,7 +92,7 @@ async function restoreSub(argv) {
|
|
|
91
92
|
out(color.green("✓ restored"));
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
async function favoriteSub(argv) {
|
|
95
|
+
async function favoriteSub(argv: string[]) {
|
|
95
96
|
const args = parseArgs(argv, { flags: COMMON_FLAGS });
|
|
96
97
|
const filename = args.positional[0];
|
|
97
98
|
if (!filename) die(2, "filename required");
|
|
@@ -106,7 +107,7 @@ async function favoriteSub(argv) {
|
|
|
106
107
|
out(color.green(resp.isFavorite ? "✓ favorited" : "✓ unfavorited"));
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
async function importSub(argv) {
|
|
110
|
+
async function importSub(argv: string[]) {
|
|
110
111
|
const args = parseArgs(argv, { flags: COMMON_FLAGS });
|
|
111
112
|
const filepath = args.positional[0];
|
|
112
113
|
if (!filepath) die(2, "filename required");
|
|
@@ -136,7 +137,7 @@ const SUB: Record<string, (argv: any[]) => Promise<void>> = {
|
|
|
136
137
|
import: importSub,
|
|
137
138
|
};
|
|
138
139
|
|
|
139
|
-
export default async function historyCmd(argv) {
|
|
140
|
+
export default async function historyCmd(argv: string[]) {
|
|
140
141
|
const sub = argv[0];
|
|
141
142
|
if (!sub || sub === "--help" || sub === "-h") { out(HELP); return; }
|
|
142
143
|
const handler = SUB[sub];
|
package/bin/commands/ls.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { parseArgs } from "../lib/args.js";
|
|
2
2
|
import { resolveServer, request } from "../lib/client.js";
|
|
3
3
|
import { out, die, color, json, table, exitCodeForError } from "../lib/output.js";
|
|
4
|
+
import { errInfo } from "../../lib/errInfo.js";
|
|
4
5
|
const SPEC = {
|
|
5
6
|
flags: {
|
|
6
7
|
count: { short: "n", type: "string", default: "20" },
|
|
@@ -22,12 +23,13 @@ export default async function lsCmd(argv) {
|
|
|
22
23
|
server = await resolveServer({ serverFlag: args.server });
|
|
23
24
|
}
|
|
24
25
|
catch (e) {
|
|
25
|
-
|
|
26
|
+
const err = errInfo(e);
|
|
27
|
+
die(exitCodeForError(e), err.message);
|
|
26
28
|
}
|
|
27
|
-
const limit = parseInt(args.count) || 20;
|
|
29
|
+
const limit = parseInt(String(args.count)) || 20;
|
|
28
30
|
const qs = new URLSearchParams();
|
|
29
31
|
if (args.session)
|
|
30
|
-
qs.set("sessionId", args.session);
|
|
32
|
+
qs.set("sessionId", String(args.session));
|
|
31
33
|
qs.set("limit", String(Math.max(limit, args.favorites ? 200 : limit)));
|
|
32
34
|
const path = `/api/history?${qs.toString()}`;
|
|
33
35
|
let resp;
|
|
@@ -35,7 +37,8 @@ export default async function lsCmd(argv) {
|
|
|
35
37
|
resp = await request(server.base, path);
|
|
36
38
|
}
|
|
37
39
|
catch (e) {
|
|
38
|
-
|
|
40
|
+
const err = errInfo(e);
|
|
41
|
+
die(exitCodeForError(e), err.message);
|
|
39
42
|
}
|
|
40
43
|
let items = (resp.items || resp.history || []);
|
|
41
44
|
if (args.favorites)
|
package/bin/commands/ls.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { parseArgs } from "../lib/args.js";
|
|
|
2
2
|
import { resolveServer, request } from "../lib/client.js";
|
|
3
3
|
import { out, die, color, json, table, exitCodeForError } from "../lib/output.js";
|
|
4
4
|
|
|
5
|
+
import { errInfo } from "../../lib/errInfo.js";
|
|
5
6
|
const SPEC = {
|
|
6
7
|
flags: {
|
|
7
8
|
count: { short: "n", type: "string", default: "20" },
|
|
@@ -13,7 +14,7 @@ const SPEC = {
|
|
|
13
14
|
},
|
|
14
15
|
};
|
|
15
16
|
|
|
16
|
-
export default async function lsCmd(argv) {
|
|
17
|
+
export default async function lsCmd(argv: string[]) {
|
|
17
18
|
const args = parseArgs(argv, SPEC);
|
|
18
19
|
if (args.help) {
|
|
19
20
|
out("ima2 ls [-n count] [--session <id>] [--favorites] [--json]");
|
|
@@ -22,19 +23,21 @@ export default async function lsCmd(argv) {
|
|
|
22
23
|
|
|
23
24
|
let server;
|
|
24
25
|
try { server = await resolveServer({ serverFlag: args.server }); }
|
|
25
|
-
catch (e) {
|
|
26
|
+
catch (e) {
|
|
27
|
+
const err = errInfo(e); die(exitCodeForError(e), err.message); }
|
|
26
28
|
|
|
27
|
-
const limit = parseInt(args.count) || 20;
|
|
29
|
+
const limit = parseInt(String(args.count)) || 20;
|
|
28
30
|
const qs = new URLSearchParams();
|
|
29
|
-
if (args.session) qs.set("sessionId", args.session);
|
|
31
|
+
if (args.session) qs.set("sessionId", String(args.session));
|
|
30
32
|
qs.set("limit", String(Math.max(limit, args.favorites ? 200 : limit)));
|
|
31
33
|
const path = `/api/history?${qs.toString()}`;
|
|
32
34
|
let resp;
|
|
33
35
|
try { resp = await request(server.base, path); }
|
|
34
|
-
catch (e) {
|
|
36
|
+
catch (e) {
|
|
37
|
+
const err = errInfo(e); die(exitCodeForError(e), err.message); }
|
|
35
38
|
|
|
36
|
-
let items = (resp.items || resp.history || []);
|
|
37
|
-
if (args.favorites) items = items.filter((it) => it.isFavorite === true);
|
|
39
|
+
let items: Record<string, unknown>[] = (resp.items || resp.history || []);
|
|
40
|
+
if (args.favorites) items = items.filter((it: Record<string, unknown>) => it.isFavorite === true);
|
|
38
41
|
items = items.slice(0, limit);
|
|
39
42
|
|
|
40
43
|
if (args.json) { json({ items }); return; }
|
|
@@ -47,12 +50,12 @@ export default async function lsCmd(argv) {
|
|
|
47
50
|
{ key: "filename", label: "FILENAME" },
|
|
48
51
|
{ key: "quality", label: "Q" },
|
|
49
52
|
{ key: "size", label: "SIZE" },
|
|
50
|
-
{ key: "createdAt", label: "WHEN", format: (v) => {
|
|
53
|
+
{ key: "createdAt", label: "WHEN", format: (v: unknown) => {
|
|
51
54
|
if (!v) return "";
|
|
52
|
-
const d = new Date(v);
|
|
55
|
+
const d = new Date(v as string);
|
|
53
56
|
return d.toISOString().replace("T", " ").slice(0, 19);
|
|
54
57
|
} },
|
|
55
|
-
{ key: "prompt", label: "PROMPT", format: (v) => {
|
|
58
|
+
{ key: "prompt", label: "PROMPT", format: (v: unknown) => {
|
|
56
59
|
const s = String(v || "").replace(/\s+/g, " ");
|
|
57
60
|
return s.length > 48 ? s.slice(0, 45) + "…" : s;
|
|
58
61
|
} },
|
package/bin/commands/metadata.js
CHANGED
|
@@ -36,7 +36,10 @@ export default async function metadataCmd(argv) {
|
|
|
36
36
|
const resp = await request(server.base, "/api/metadata/read", {
|
|
37
37
|
method: "POST",
|
|
38
38
|
body: { dataUrl },
|
|
39
|
-
}).catch((e) =>
|
|
39
|
+
}).catch((e) => {
|
|
40
|
+
const err = e;
|
|
41
|
+
die(exitCodeForError(e), `${err.message}${err.code ? ` (${err.code})` : ""}`);
|
|
42
|
+
});
|
|
40
43
|
if (args.json) {
|
|
41
44
|
json(resp);
|
|
42
45
|
}
|
package/bin/commands/metadata.ts
CHANGED
|
@@ -18,7 +18,7 @@ const HELP = `
|
|
|
18
18
|
POSTs { dataUrl } to /api/metadata/read.
|
|
19
19
|
`;
|
|
20
20
|
|
|
21
|
-
export default async function metadataCmd(argv) {
|
|
21
|
+
export default async function metadataCmd(argv: string[]) {
|
|
22
22
|
const args = parseArgs(argv, SPEC);
|
|
23
23
|
if (args.help) { out(HELP); return; }
|
|
24
24
|
const file = args.positional[0];
|
|
@@ -30,7 +30,10 @@ export default async function metadataCmd(argv) {
|
|
|
30
30
|
const resp = await request(server.base, "/api/metadata/read", {
|
|
31
31
|
method: "POST",
|
|
32
32
|
body: { dataUrl },
|
|
33
|
-
}).catch((e) =>
|
|
33
|
+
}).catch((e: unknown) => {
|
|
34
|
+
const err = e as { message?: string; code?: string };
|
|
35
|
+
die(exitCodeForError(e), `${err.message}${err.code ? ` (${err.code})` : ""}`);
|
|
36
|
+
});
|
|
34
37
|
if (args.json) { json(resp); }
|
|
35
38
|
else out(JSON.stringify(resp, null, 2));
|
|
36
39
|
}
|
|
@@ -54,7 +54,7 @@ export default async function multimodeCmd(argv) {
|
|
|
54
54
|
if (!prompt)
|
|
55
55
|
die(2, "prompt required");
|
|
56
56
|
const VALID_REASONING = new Set(["none", "low", "medium", "high", "xhigh"]);
|
|
57
|
-
if (args["reasoning-effort"] && !VALID_REASONING.has(args["reasoning-effort"])) {
|
|
57
|
+
if (args["reasoning-effort"] && !VALID_REASONING.has(String(args["reasoning-effort"]))) {
|
|
58
58
|
die(2, "--reasoning-effort must be one of: none, low, medium, high, xhigh");
|
|
59
59
|
}
|
|
60
60
|
if (args["web-search"] && args["no-web-search"]) {
|
|
@@ -68,7 +68,7 @@ export default async function multimodeCmd(argv) {
|
|
|
68
68
|
die(exitCodeForError(e), e.message);
|
|
69
69
|
throw e;
|
|
70
70
|
}
|
|
71
|
-
const maxImages = Math.max(1, Math.min(8, parseInt(args["max-images"]) || 4));
|
|
71
|
+
const maxImages = Math.max(1, Math.min(8, parseInt(String(args["max-images"])) || 4));
|
|
72
72
|
const body = {
|
|
73
73
|
prompt,
|
|
74
74
|
quality: args.quality,
|
|
@@ -124,8 +124,8 @@ export default async function multimodeCmd(argv) {
|
|
|
124
124
|
die(exitCodeForError(e), `${e.message}${e.code ? ` (${e.code})` : ""}`);
|
|
125
125
|
}
|
|
126
126
|
// Save images
|
|
127
|
-
const outDir = args["out-dir"]
|
|
128
|
-
const explicitOut = args.out
|
|
127
|
+
const outDir = args["out-dir"] ? String(args["out-dir"]) : null;
|
|
128
|
+
const explicitOut = args.out ? String(args.out) : null;
|
|
129
129
|
if (explicitOut && images.length > 1) {
|
|
130
130
|
if (!args.json)
|
|
131
131
|
out(color.yellow(`(received ${images.length} images, --out only saves first)`));
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { writeFile } from "fs/promises";
|
|
2
1
|
import { parseArgs } from "../lib/args.js";
|
|
3
2
|
import { resolveServer } from "../lib/client.js";
|
|
4
3
|
import { streamSse } from "../lib/sse.js";
|
|
@@ -48,14 +47,14 @@ const HELP = `
|
|
|
48
47
|
--timeout <sec> Default: 600
|
|
49
48
|
`;
|
|
50
49
|
|
|
51
|
-
export default async function multimodeCmd(argv) {
|
|
50
|
+
export default async function multimodeCmd(argv: string[]) {
|
|
52
51
|
const args = parseArgs(argv, SPEC);
|
|
53
52
|
if (args.help) { out(HELP); return; }
|
|
54
53
|
const prompt = args.positional.join(" ");
|
|
55
54
|
if (!prompt) die(2, "prompt required");
|
|
56
55
|
|
|
57
56
|
const VALID_REASONING = new Set(["none", "low", "medium", "high", "xhigh"]);
|
|
58
|
-
if (args["reasoning-effort"] && !VALID_REASONING.has(args["reasoning-effort"])) {
|
|
57
|
+
if (args["reasoning-effort"] && !VALID_REASONING.has(String(args["reasoning-effort"]))) {
|
|
59
58
|
die(2, "--reasoning-effort must be one of: none, low, medium, high, xhigh");
|
|
60
59
|
}
|
|
61
60
|
if (args["web-search"] && args["no-web-search"]) {
|
|
@@ -66,7 +65,7 @@ export default async function multimodeCmd(argv) {
|
|
|
66
65
|
try { server = await resolveServer({ serverFlag: args.server }); }
|
|
67
66
|
catch (e: any) { die(exitCodeForError(e), e.message); throw e; }
|
|
68
67
|
|
|
69
|
-
const maxImages = Math.max(1, Math.min(8, parseInt(args["max-images"]) || 4));
|
|
68
|
+
const maxImages = Math.max(1, Math.min(8, parseInt(String(args["max-images"])) || 4));
|
|
70
69
|
const body: any = {
|
|
71
70
|
prompt,
|
|
72
71
|
quality: args.quality,
|
|
@@ -117,8 +116,8 @@ export default async function multimodeCmd(argv) {
|
|
|
117
116
|
}
|
|
118
117
|
|
|
119
118
|
// Save images
|
|
120
|
-
const outDir = args["out-dir"]
|
|
121
|
-
const explicitOut = args.out
|
|
119
|
+
const outDir = args["out-dir"] ? String(args["out-dir"]) : null;
|
|
120
|
+
const explicitOut = args.out ? String(args.out) : null;
|
|
122
121
|
if (explicitOut && images.length > 1) {
|
|
123
122
|
if (!args.json) out(color.yellow(`(received ${images.length} images, --out only saves first)`));
|
|
124
123
|
}
|
package/bin/commands/node.js
CHANGED
|
@@ -53,9 +53,9 @@ async function generateSub(argv) {
|
|
|
53
53
|
const prompt = args.positional.join(" ");
|
|
54
54
|
if (!prompt)
|
|
55
55
|
die(2, "prompt required");
|
|
56
|
-
const refs = args.ref
|
|
56
|
+
const refs = (Array.isArray(args.ref) ? args.ref : []);
|
|
57
57
|
const VALID_REASONING = new Set(["none", "low", "medium", "high", "xhigh"]);
|
|
58
|
-
if (args["reasoning-effort"] && !VALID_REASONING.has(args["reasoning-effort"])) {
|
|
58
|
+
if (args["reasoning-effort"] && !VALID_REASONING.has(String(args["reasoning-effort"]))) {
|
|
59
59
|
die(2, "--reasoning-effort must be one of: none, low, medium, high, xhigh");
|
|
60
60
|
}
|
|
61
61
|
if (args["web-search"] && args["no-web-search"]) {
|
|
@@ -67,7 +67,7 @@ async function generateSub(argv) {
|
|
|
67
67
|
prompt,
|
|
68
68
|
quality: args.quality,
|
|
69
69
|
size: args.size,
|
|
70
|
-
n: Math.max(1, Math.min(8, parseInt(args.count) || 1)),
|
|
70
|
+
n: Math.max(1, Math.min(8, parseInt(String(args.count)) || 1)),
|
|
71
71
|
references,
|
|
72
72
|
moderation: args.moderation,
|
|
73
73
|
sessionId: args.session,
|
|
@@ -86,8 +86,8 @@ async function generateSub(argv) {
|
|
|
86
86
|
const resp = await request(server.base, "/api/node/generate", {
|
|
87
87
|
method: "POST",
|
|
88
88
|
body,
|
|
89
|
-
timeoutMs: (parseInt(args.timeout) || 600) * 1000,
|
|
90
|
-
}).catch((e) => die(exitCodeForError(e), `${
|
|
89
|
+
timeoutMs: (parseInt(String(args.timeout)) || 600) * 1000,
|
|
90
|
+
}).catch((e) => { const err = e; die(exitCodeForError(e), `${err.message}${err.code ? ` (${err.code})` : ""}`); });
|
|
91
91
|
if (args.json) {
|
|
92
92
|
json(resp);
|
|
93
93
|
return;
|
|
@@ -137,7 +137,7 @@ async function generateSub(argv) {
|
|
|
137
137
|
if (!im.image)
|
|
138
138
|
continue;
|
|
139
139
|
const target = args.out && i === 0
|
|
140
|
-
? args.out
|
|
140
|
+
? String(args.out)
|
|
141
141
|
: `${config.storage.generatedDir}/${defaultOutName(i, images.length)}`;
|
|
142
142
|
await dataUriToFile(im.image, target);
|
|
143
143
|
savedPaths.push(target);
|
|
@@ -156,7 +156,7 @@ async function showSub(argv) {
|
|
|
156
156
|
if (!id)
|
|
157
157
|
die(2, "nodeId required");
|
|
158
158
|
const server = await getServer(args);
|
|
159
|
-
const resp = await request(server.base, `/api/node/${encodeURIComponent(id)}`).catch((e) => die(exitCodeForError(e),
|
|
159
|
+
const resp = await request(server.base, `/api/node/${encodeURIComponent(id)}`).catch((e) => { const err = e; die(exitCodeForError(e), err.message); });
|
|
160
160
|
json(resp);
|
|
161
161
|
}
|
|
162
162
|
const SUB = {
|