@lazyingart/agintiflow 0.20.185 → 0.20.186
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.
|
@@ -75,6 +75,21 @@ That SVG request returns a PNG fallback contract rather than pretending SVG was
|
|
|
75
75
|
}
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
+
The CLI exposes the same direct path for shell scripts and other local apps:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
aginti image --json --dry-run \
|
|
82
|
+
--provider venice \
|
|
83
|
+
--format svg \
|
|
84
|
+
--output-dir artifacts/images/robot-cover \
|
|
85
|
+
--output-stem cover.svg \
|
|
86
|
+
"A cyan robot painting a poster, clean product illustration"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`aginti image ...` returns the same `requestedFormat`, `actualFormat`, and `formatNotice` fields as the web API. Use this direct CLI when
|
|
90
|
+
an app needs a deterministic tool call. Use `aginti --image "..."` when the user wants an agent-mediated image task that may plan, inspect
|
|
91
|
+
references, create files, or send artifacts to the canvas.
|
|
92
|
+
|
|
78
93
|
With GRS AI, the tool uses the Nano Banana API:
|
|
79
94
|
|
|
80
95
|
- `POST https://grsaiapi.com/v1/draw/nano-banana`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.186",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AgInTiFlow is a project-aware agent workspace for hybrid wet-dry R&D, hardware-aware intelligence, software automation, and industrial workflows.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -10,6 +10,17 @@ This note records the working publication route for AgInTiFlow so future release
|
|
|
10
10
|
|
|
11
11
|
Latest verified release:
|
|
12
12
|
|
|
13
|
+
- Version: `0.20.185`
|
|
14
|
+
- Commit: `58d6087`
|
|
15
|
+
- GitHub Actions run: `https://github.com/lazyingart/AgInTiFlow/actions/runs/26700387931`
|
|
16
|
+
- Workflow result: success
|
|
17
|
+
- npm registry check: `npm view @lazyingart/agintiflow version dist-tags.latest --registry=https://registry.npmjs.org` returned `0.20.185`.
|
|
18
|
+
- Installed verification: `npm install -g @lazyingart/agintiflow@0.20.185` then `aginti --version` returned `0.20.185`.
|
|
19
|
+
- Webapp verification: `aginti webapp restart --port 3210` then `curl -fsS http://127.0.0.1:3210/health` returned `version":"0.20.185"` from the global npm package path.
|
|
20
|
+
- Image API verification: `POST /api/auxiliary/generate-image` with `format:"svg"` and `dryRun:true` returned `requestedFormat:"svg"`, `actualFormat:"png"`, and a clear raster PNG fallback notice.
|
|
21
|
+
|
|
22
|
+
Previous verified release:
|
|
23
|
+
|
|
13
24
|
- Version: `0.20.184`
|
|
14
25
|
- Commit: `9b22f4c`
|
|
15
26
|
- GitHub Actions run: `https://github.com/lazyingart/AgInTiFlow/actions/runs/26700154894`
|
|
@@ -3,6 +3,8 @@ import fs from "node:fs/promises";
|
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { execFile as execFileCallback } from "node:child_process";
|
|
7
|
+
import { promisify } from "node:util";
|
|
6
8
|
import { runAgent } from "../src/agent-runner.js";
|
|
7
9
|
import { generateImage, listAuxiliarySkills } from "../src/auxiliary-tools.js";
|
|
8
10
|
import { resolveRuntimeConfig } from "../src/config.js";
|
|
@@ -10,6 +12,7 @@ import { providerKeyStatus, setProviderKey } from "../src/project.js";
|
|
|
10
12
|
import { SessionStore } from "../src/session-store.js";
|
|
11
13
|
|
|
12
14
|
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
15
|
+
const execFile = promisify(execFileCallback);
|
|
13
16
|
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "agintiflow-auxiliary-"));
|
|
14
17
|
process.env.AGINTIFLOW_HOME = path.join(tempRoot, ".agintiflow-home");
|
|
15
18
|
const runtimeDir = path.join(tempRoot, "runtime");
|
|
@@ -82,6 +85,37 @@ try {
|
|
|
82
85
|
);
|
|
83
86
|
assert(svgFallbackManifest.requestedFormat === "svg" && svgFallbackManifest.actualFormat === "png", "SVG fallback manifest missing format contract");
|
|
84
87
|
|
|
88
|
+
const cliImage = await execFile(
|
|
89
|
+
process.execPath,
|
|
90
|
+
[
|
|
91
|
+
path.join(repoRoot, "bin/aginti-cli.js"),
|
|
92
|
+
"--no-auto-update",
|
|
93
|
+
"image",
|
|
94
|
+
"--json",
|
|
95
|
+
"--dry-run",
|
|
96
|
+
"--cwd",
|
|
97
|
+
workspace,
|
|
98
|
+
"--provider",
|
|
99
|
+
"venice",
|
|
100
|
+
"--format",
|
|
101
|
+
"svg",
|
|
102
|
+
"--output-dir",
|
|
103
|
+
"artifacts/images/cli-svg-fallback",
|
|
104
|
+
"--output-stem",
|
|
105
|
+
"diagram.svg",
|
|
106
|
+
"A simple geometric diagram requested as SVG.",
|
|
107
|
+
],
|
|
108
|
+
{
|
|
109
|
+
cwd: repoRoot,
|
|
110
|
+
env: { ...process.env, AGINTIFLOW_HOME: process.env.AGINTIFLOW_HOME },
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
const cliImageResult = JSON.parse(cliImage.stdout);
|
|
114
|
+
assert(cliImageResult.ok && cliImageResult.requestedFormat === "svg", "direct image CLI did not record requestedFormat");
|
|
115
|
+
assert(cliImageResult.actualFormat === "png", "direct image CLI did not select PNG fallback");
|
|
116
|
+
assert(/raster PNG/i.test(cliImageResult.formatNotice || ""), "direct image CLI did not explain SVG-to-PNG fallback");
|
|
117
|
+
await fs.access(path.join(workspace, "artifacts/images/cli-svg-fallback/task_manifest.json"));
|
|
118
|
+
|
|
85
119
|
const blocked = await generateImage(
|
|
86
120
|
{
|
|
87
121
|
prompt: "blocked",
|
|
@@ -131,6 +165,7 @@ try {
|
|
|
131
165
|
"generate_image_dry_run",
|
|
132
166
|
"venice_generate_image_dry_run",
|
|
133
167
|
"svg_request_png_fallback",
|
|
168
|
+
"direct_image_cli_svg_request_png_fallback",
|
|
134
169
|
"generate_image_guardrail",
|
|
135
170
|
"mock_agent_image_tool",
|
|
136
171
|
],
|
package/src/cli.js
CHANGED
|
@@ -30,6 +30,7 @@ import { listTaskProfiles } from "./task-profiles.js";
|
|
|
30
30
|
import { recommendedMaxStepsForTask } from "./engineering-guidance.js";
|
|
31
31
|
import { normalizeAuthProvider, promptHidden, runAuthWizard, shouldPromptForDeepSeek } from "./auth-onboarding.js";
|
|
32
32
|
import { listSkills, selectSkillsForGoal } from "./skill-library.js";
|
|
33
|
+
import { generateImage } from "./auxiliary-tools.js";
|
|
33
34
|
import { languageLabel, resolveLanguage } from "./i18n.js";
|
|
34
35
|
import { maybeAutoUpdate } from "./auto-update.js";
|
|
35
36
|
import { readHousekeepingSummary } from "./housekeeping.js";
|
|
@@ -761,7 +762,7 @@ function exitOnUnknownOptions(parsed) {
|
|
|
761
762
|
|
|
762
763
|
function printUsage() {
|
|
763
764
|
console.log(
|
|
764
|
-
'Usage: aginti [chat] OR aginti init [--template minimal|disciplined|coding|research|writing|design|aaps|supervision] OR aginti web [--port 3210] OR aginti docker [status|setup|install-host] OR aginti update OR aginti models OR aginti aaps [status|init|files|validate|compile|check|run] OR aginti mcp [status|config|inspect|tools|resources|read|prompts|prompt|call|restart] OR aginti skills [query] OR aginti skillmesh [status|off|record|share|sync|serve|service] OR aginti housekeeping [--json] OR aginti auth [deepseek|openai|qwen|venice|grsai] OR aginti resume [--all-sessions] [latest|<session-id>] ["prompt"] OR aginti --remove-empty-sessions OR aginti --remove-sessions OR aginti queue <session-id> "message" OR aginti [--no-auto-update] [-s safe|normal|danger] [--language en|ja|zh-Hans|zh-Hant|ko|fr|es|ar|vi|de|ru] [--image] [--latex] [--scs|--scs auto|--no-scs] [--dynamic-steps auto|on|off] [--routing smart|fast|complex|manual] [--provider deepseek|openai|qwen|venice|mock] [--model MODEL] [--route-model MODEL] [--main-model MODEL] [--spare-model MODEL --spare-reasoning medium] [--aux-provider grsai|venice --aux-model MODEL] [--sandbox-mode host|docker-readonly|docker-workspace] [--package-install-policy block|prompt|allow] [--approve-package-installs] [--allow-shell|--no-shell] [--allow-file-tools|--no-file-tools] [--web-search|--no-web-search] [--mcp|--no-mcp] [--parallel-scouts|--no-parallel-scouts --scout-count 1..10] [--allow-auxiliary-tools|--no-auxiliary-tools] [--allow-wrappers --wrapper codex --wrapper-model gpt-5.5] [--list-models|--list-routes] "your task"'
|
|
765
|
+
'Usage: aginti [chat] OR aginti init [--template minimal|disciplined|coding|research|writing|design|aaps|supervision] OR aginti web [--port 3210] OR aginti docker [status|setup|install-host] OR aginti update OR aginti image [--json] [--dry-run] [--format png|webp|svg] "prompt" OR aginti models OR aginti aaps [status|init|files|validate|compile|check|run] OR aginti mcp [status|config|inspect|tools|resources|read|prompts|prompt|call|restart] OR aginti skills [query] OR aginti skillmesh [status|off|record|share|sync|serve|service] OR aginti housekeeping [--json] OR aginti auth [deepseek|openai|qwen|venice|grsai] OR aginti resume [--all-sessions] [latest|<session-id>] ["prompt"] OR aginti --remove-empty-sessions OR aginti --remove-sessions OR aginti queue <session-id> "message" OR aginti [--no-auto-update] [-s safe|normal|danger] [--language en|ja|zh-Hans|zh-Hant|ko|fr|es|ar|vi|de|ru] [--image] [--latex] [--scs|--scs auto|--no-scs] [--dynamic-steps auto|on|off] [--routing smart|fast|complex|manual] [--provider deepseek|openai|qwen|venice|mock] [--model MODEL] [--route-model MODEL] [--main-model MODEL] [--spare-model MODEL --spare-reasoning medium] [--aux-provider grsai|venice --aux-model MODEL] [--sandbox-mode host|docker-readonly|docker-workspace] [--package-install-policy block|prompt|allow] [--approve-package-installs] [--allow-shell|--no-shell] [--allow-file-tools|--no-file-tools] [--web-search|--no-web-search] [--mcp|--no-mcp] [--parallel-scouts|--no-parallel-scouts --scout-count 1..10] [--allow-auxiliary-tools|--no-auxiliary-tools] [--allow-wrappers --wrapper codex --wrapper-model gpt-5.5] [--list-models|--list-routes] "your task"'
|
|
765
766
|
);
|
|
766
767
|
console.log("Permission shortcuts: -s safe asks before writes/setup; -s normal allows current-project writes and Docker setup; -s danger enables trusted host/full-access mode.");
|
|
767
768
|
console.log(`Languages: ${["en", "ja", "zh-Hans", "zh-Hant", "ko", "fr", "es", "ar", "vi", "de", "ru"].map((code) => `${code}=${languageLabel(code)}`).join(", ")}`);
|
|
@@ -790,6 +791,211 @@ function splitToolCommandArgv(argv = []) {
|
|
|
790
791
|
return { actionArgv, optionArgv, json };
|
|
791
792
|
}
|
|
792
793
|
|
|
794
|
+
function takeImageOptionValue(argv, index, option) {
|
|
795
|
+
const equals = String(option || "").match(/^([^=]+)=(.*)$/);
|
|
796
|
+
if (equals) return { value: equals[2], nextIndex: index + 1 };
|
|
797
|
+
const value = argv[index + 1];
|
|
798
|
+
return { value: value && !String(value).startsWith("--") ? value : "", nextIndex: value && !String(value).startsWith("--") ? index + 2 : index + 1 };
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
function parseImageCommandArgs(argv = []) {
|
|
802
|
+
const result = {
|
|
803
|
+
prompt: "",
|
|
804
|
+
provider: "",
|
|
805
|
+
model: "",
|
|
806
|
+
format: "",
|
|
807
|
+
outputDir: "",
|
|
808
|
+
outputStem: "",
|
|
809
|
+
aspectRatio: "",
|
|
810
|
+
imageSize: "",
|
|
811
|
+
host: "",
|
|
812
|
+
referenceImages: [],
|
|
813
|
+
commandCwd: "",
|
|
814
|
+
requestTimeoutMs: "",
|
|
815
|
+
pollTimeoutMs: "",
|
|
816
|
+
pollIntervalMs: "",
|
|
817
|
+
dryRun: false,
|
|
818
|
+
json: false,
|
|
819
|
+
stdin: false,
|
|
820
|
+
help: false,
|
|
821
|
+
unknownOptions: [],
|
|
822
|
+
};
|
|
823
|
+
const promptParts = [];
|
|
824
|
+
let index = 0;
|
|
825
|
+
if (["generate", "create", "make"].includes(String(argv[0] || "").toLowerCase())) index = 1;
|
|
826
|
+
|
|
827
|
+
while (index < argv.length) {
|
|
828
|
+
const arg = String(argv[index] || "");
|
|
829
|
+
const name = arg.split("=")[0];
|
|
830
|
+
if (arg === "--") {
|
|
831
|
+
promptParts.push(...argv.slice(index + 1));
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
834
|
+
if (arg === "--help" || arg === "-h") {
|
|
835
|
+
result.help = true;
|
|
836
|
+
index += 1;
|
|
837
|
+
continue;
|
|
838
|
+
}
|
|
839
|
+
if (arg === "--json") {
|
|
840
|
+
result.json = true;
|
|
841
|
+
index += 1;
|
|
842
|
+
continue;
|
|
843
|
+
}
|
|
844
|
+
if (arg === "--dry-run" || arg === "--dryrun") {
|
|
845
|
+
result.dryRun = true;
|
|
846
|
+
index += 1;
|
|
847
|
+
continue;
|
|
848
|
+
}
|
|
849
|
+
if (arg === "--stdin") {
|
|
850
|
+
result.stdin = true;
|
|
851
|
+
index += 1;
|
|
852
|
+
continue;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
const valueOptions = new Map([
|
|
856
|
+
["--provider", "provider"],
|
|
857
|
+
["--aux-provider", "provider"],
|
|
858
|
+
["--auxiliary-provider", "provider"],
|
|
859
|
+
["--model", "model"],
|
|
860
|
+
["--aux-model", "model"],
|
|
861
|
+
["--auxiliary-model", "model"],
|
|
862
|
+
["--format", "format"],
|
|
863
|
+
["--output-dir", "outputDir"],
|
|
864
|
+
["--out-dir", "outputDir"],
|
|
865
|
+
["--dir", "outputDir"],
|
|
866
|
+
["--output-stem", "outputStem"],
|
|
867
|
+
["--stem", "outputStem"],
|
|
868
|
+
["--aspect-ratio", "aspectRatio"],
|
|
869
|
+
["--ratio", "aspectRatio"],
|
|
870
|
+
["--image-size", "imageSize"],
|
|
871
|
+
["--size", "imageSize"],
|
|
872
|
+
["--host", "host"],
|
|
873
|
+
["--cwd", "commandCwd"],
|
|
874
|
+
["--request-timeout-ms", "requestTimeoutMs"],
|
|
875
|
+
["--poll-timeout-ms", "pollTimeoutMs"],
|
|
876
|
+
["--poll-interval-ms", "pollIntervalMs"],
|
|
877
|
+
]);
|
|
878
|
+
if (valueOptions.has(name)) {
|
|
879
|
+
const { value, nextIndex } = takeImageOptionValue(argv, index, arg);
|
|
880
|
+
if (!value) result.unknownOptions.push(arg);
|
|
881
|
+
else result[valueOptions.get(name)] = value;
|
|
882
|
+
index = nextIndex;
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
885
|
+
if (["--reference", "--reference-image", "--ref", "--image-ref"].includes(name)) {
|
|
886
|
+
const { value, nextIndex } = takeImageOptionValue(argv, index, arg);
|
|
887
|
+
if (!value) result.unknownOptions.push(arg);
|
|
888
|
+
else result.referenceImages.push(value);
|
|
889
|
+
index = nextIndex;
|
|
890
|
+
continue;
|
|
891
|
+
}
|
|
892
|
+
if (arg.startsWith("--") && promptParts.length === 0) {
|
|
893
|
+
result.unknownOptions.push(arg);
|
|
894
|
+
index += 1;
|
|
895
|
+
continue;
|
|
896
|
+
}
|
|
897
|
+
promptParts.push(arg);
|
|
898
|
+
index += 1;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
result.prompt = promptParts.join(" ").trim();
|
|
902
|
+
return result;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
function printImageCommandUsage() {
|
|
906
|
+
console.log(
|
|
907
|
+
'Usage: aginti image [generate] [--json] [--dry-run] [--provider grsai|venice] [--model MODEL] [--format png|webp|svg] [--output-dir DIR] [--output-stem STEM] [--aspect-ratio 1:1] [--image-size 1K|2K|4K|1024x1024] [--reference path-or-url] "prompt"'
|
|
908
|
+
);
|
|
909
|
+
console.log("Direct image CLI calls the same generate_image tool as the web API. SVG/vector requests return PNG with requestedFormat/actualFormat/formatNotice.");
|
|
910
|
+
console.log('Agent-mediated image work is still available as: aginti --image "draw a poster"');
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
function directImageCommandArgv(argv = []) {
|
|
914
|
+
const first = String(argv[0] || "").toLowerCase();
|
|
915
|
+
const second = String(argv[1] || "").toLowerCase();
|
|
916
|
+
if (["image", "imagegen", "image-gen", "generate-image", "image-generate"].includes(first)) return argv.slice(1);
|
|
917
|
+
if (["aux", "auxiliary"].includes(first) && ["image", "imagegen", "image-gen", "generate-image", "generate"].includes(second)) {
|
|
918
|
+
return argv.slice(2);
|
|
919
|
+
}
|
|
920
|
+
return null;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function printImageCommandResult(result = {}) {
|
|
924
|
+
const status = result.dryRun ? "prepared" : result.ok ? "generated" : result.blocked ? "blocked" : "failed";
|
|
925
|
+
console.log(`image: ${status}`);
|
|
926
|
+
if (result.summary) console.log(`summary: ${result.summary}`);
|
|
927
|
+
if (result.provider) console.log(`provider: ${result.provider}`);
|
|
928
|
+
if (result.requestedFormat || result.actualFormat) {
|
|
929
|
+
const requested = result.requestedFormat || "auto";
|
|
930
|
+
const actual = result.actualFormat || "unknown";
|
|
931
|
+
console.log(`format: ${requested}${requested === actual ? "" : ` -> ${actual}`}`);
|
|
932
|
+
}
|
|
933
|
+
if (result.formatNotice) console.log(`notice: ${result.formatNotice}`);
|
|
934
|
+
if (result.path) console.log(`path: ${result.path}`);
|
|
935
|
+
if (result.imagePaths?.length) console.log(`images: ${result.imagePaths.join(", ")}`);
|
|
936
|
+
if (result.manifestPath) console.log(`manifest: ${result.manifestPath}`);
|
|
937
|
+
if (result.promptPath) console.log(`prompt: ${result.promptPath}`);
|
|
938
|
+
if (result.requestPayloadPath) console.log(`request: ${result.requestPayloadPath}`);
|
|
939
|
+
if (result.reason) console.log(`reason: ${result.reason}`);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
async function handleImageCommand(argv, { commandCwd = process.cwd() } = {}) {
|
|
943
|
+
const parsed = parseImageCommandArgs(argv);
|
|
944
|
+
if (parsed.help) {
|
|
945
|
+
printImageCommandUsage();
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
if (parsed.unknownOptions.length) {
|
|
949
|
+
printUnknownCliOptions(parsed.unknownOptions);
|
|
950
|
+
process.exit(1);
|
|
951
|
+
}
|
|
952
|
+
const prompt = parsed.stdin ? await readStdin() : parsed.prompt;
|
|
953
|
+
if (!prompt) {
|
|
954
|
+
printImageCommandUsage();
|
|
955
|
+
process.exit(1);
|
|
956
|
+
}
|
|
957
|
+
const effectiveCommandCwd = path.resolve(parsed.commandCwd || commandCwd || process.cwd());
|
|
958
|
+
const config = loadConfig(
|
|
959
|
+
{
|
|
960
|
+
goal: prompt,
|
|
961
|
+
taskProfile: "image",
|
|
962
|
+
commandCwd: effectiveCommandCwd,
|
|
963
|
+
auxiliaryProvider: parsed.provider,
|
|
964
|
+
auxiliaryModel: parsed.model,
|
|
965
|
+
allowFileTools: true,
|
|
966
|
+
allowAuxiliaryTools: true,
|
|
967
|
+
},
|
|
968
|
+
{ packageDir, baseDir: effectiveCommandCwd }
|
|
969
|
+
);
|
|
970
|
+
const result = await generateImage(
|
|
971
|
+
{
|
|
972
|
+
prompt,
|
|
973
|
+
provider: parsed.provider,
|
|
974
|
+
model: parsed.model,
|
|
975
|
+
format: parsed.format,
|
|
976
|
+
outputDir: parsed.outputDir || undefined,
|
|
977
|
+
outputStem: parsed.outputStem || undefined,
|
|
978
|
+
aspectRatio: parsed.aspectRatio || undefined,
|
|
979
|
+
imageSize: parsed.imageSize || undefined,
|
|
980
|
+
host: parsed.host || undefined,
|
|
981
|
+
referenceImages: parsed.referenceImages,
|
|
982
|
+
requestTimeoutMs: parsed.requestTimeoutMs || undefined,
|
|
983
|
+
pollTimeoutMs: parsed.pollTimeoutMs || undefined,
|
|
984
|
+
pollIntervalMs: parsed.pollIntervalMs || undefined,
|
|
985
|
+
dryRun: parsed.dryRun,
|
|
986
|
+
},
|
|
987
|
+
{
|
|
988
|
+
...config,
|
|
989
|
+
commandCwd: effectiveCommandCwd,
|
|
990
|
+
allowFileTools: true,
|
|
991
|
+
allowAuxiliaryTools: true,
|
|
992
|
+
}
|
|
993
|
+
);
|
|
994
|
+
if (parsed.json) console.log(JSON.stringify(result, null, 2));
|
|
995
|
+
else printImageCommandResult(result);
|
|
996
|
+
if (!result.ok) process.exit(1);
|
|
997
|
+
}
|
|
998
|
+
|
|
793
999
|
function parseDockerCommandArgs(argv = [], fallbackCwd = process.cwd()) {
|
|
794
1000
|
const result = {
|
|
795
1001
|
action: "status",
|
|
@@ -1856,6 +2062,20 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
1856
2062
|
return;
|
|
1857
2063
|
}
|
|
1858
2064
|
|
|
2065
|
+
const imageCommand = directImageCommandArgv(commandArgv);
|
|
2066
|
+
if (imageCommand) {
|
|
2067
|
+
try {
|
|
2068
|
+
await handleImageCommand(imageCommand, { commandCwd });
|
|
2069
|
+
} catch (error) {
|
|
2070
|
+
const wantsJson = imageCommand.includes("--json");
|
|
2071
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2072
|
+
if (wantsJson) console.log(JSON.stringify({ ok: false, error: message }, null, 2));
|
|
2073
|
+
else console.error(message);
|
|
2074
|
+
process.exit(1);
|
|
2075
|
+
}
|
|
2076
|
+
return;
|
|
2077
|
+
}
|
|
2078
|
+
|
|
1859
2079
|
if (commandArgv.includes("--remove-empty-sessions") || commandArgv[0] === "remove-empty-sessions") {
|
|
1860
2080
|
await handleRemoveSessionsCommand({ emptyOnly: true });
|
|
1861
2081
|
return;
|