codex-imagegen-mcp 0.1.2
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/CHANGELOG.md +96 -0
- package/LICENSE +201 -0
- package/NOTICE +19 -0
- package/README.md +373 -0
- package/dist/src/auth/borrowed.js +77 -0
- package/dist/src/auth/borrowed.js.map +1 -0
- package/dist/src/auth/browser-login.js +179 -0
- package/dist/src/auth/browser-login.js.map +1 -0
- package/dist/src/auth/device-login.js +39 -0
- package/dist/src/auth/device-login.js.map +1 -0
- package/dist/src/auth/jwt.js +69 -0
- package/dist/src/auth/jwt.js.map +1 -0
- package/dist/src/auth/manager.js +289 -0
- package/dist/src/auth/manager.js.map +1 -0
- package/dist/src/auth/oauth.js +246 -0
- package/dist/src/auth/oauth.js.map +1 -0
- package/dist/src/auth/pages.js +39 -0
- package/dist/src/auth/pages.js.map +1 -0
- package/dist/src/auth/pkce.js +14 -0
- package/dist/src/auth/pkce.js.map +1 -0
- package/dist/src/auth/store.js +75 -0
- package/dist/src/auth/store.js.map +1 -0
- package/dist/src/backend/images-client.js +223 -0
- package/dist/src/backend/images-client.js.map +1 -0
- package/dist/src/backend/ratelimits.js +183 -0
- package/dist/src/backend/ratelimits.js.map +1 -0
- package/dist/src/cli.js +407 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/config.js +87 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/constants.js +52 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/doctor.js +122 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/errors.js +76 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/generation.js +183 -0
- package/dist/src/generation.js.map +1 -0
- package/dist/src/history.js +47 -0
- package/dist/src/history.js.map +1 -0
- package/dist/src/images/chroma.js +200 -0
- package/dist/src/images/chroma.js.map +1 -0
- package/dist/src/images/codec.js +159 -0
- package/dist/src/images/codec.js.map +1 -0
- package/dist/src/images/inputs.js +83 -0
- package/dist/src/images/inputs.js.map +1 -0
- package/dist/src/images/output.js +100 -0
- package/dist/src/images/output.js.map +1 -0
- package/dist/src/images/preview.js +20 -0
- package/dist/src/images/preview.js.map +1 -0
- package/dist/src/images/resize.js +135 -0
- package/dist/src/images/resize.js.map +1 -0
- package/dist/src/install/opencode.js +138 -0
- package/dist/src/install/opencode.js.map +1 -0
- package/dist/src/install/skill.js +128 -0
- package/dist/src/install/skill.js.map +1 -0
- package/dist/src/install/snippets.js +127 -0
- package/dist/src/install/snippets.js.map +1 -0
- package/dist/src/log.js +58 -0
- package/dist/src/log.js.map +1 -0
- package/dist/src/remove-background.js +101 -0
- package/dist/src/remove-background.js.map +1 -0
- package/dist/src/server/context.js +2 -0
- package/dist/src/server/context.js.map +1 -0
- package/dist/src/server/index.js +94 -0
- package/dist/src/server/index.js.map +1 -0
- package/dist/src/server/instructions.js +20 -0
- package/dist/src/server/instructions.js.map +1 -0
- package/dist/src/server/login-coordinator.js +73 -0
- package/dist/src/server/login-coordinator.js.map +1 -0
- package/dist/src/server/progress.js +33 -0
- package/dist/src/server/progress.js.map +1 -0
- package/dist/src/server/prompts.js +45 -0
- package/dist/src/server/prompts.js.map +1 -0
- package/dist/src/server/resources.js +73 -0
- package/dist/src/server/resources.js.map +1 -0
- package/dist/src/server/tools.js +338 -0
- package/dist/src/server/tools.js.map +1 -0
- package/dist/src/server/workspace.js +45 -0
- package/dist/src/server/workspace.js.map +1 -0
- package/dist/src/status.js +86 -0
- package/dist/src/status.js.map +1 -0
- package/dist/src/util/format.js +36 -0
- package/dist/src/util/format.js.map +1 -0
- package/dist/src/util/fs.js +117 -0
- package/dist/src/util/fs.js.map +1 -0
- package/dist/src/util/http.js +65 -0
- package/dist/src/util/http.js.map +1 -0
- package/dist/src/util/invocation.js +43 -0
- package/dist/src/util/invocation.js.map +1 -0
- package/dist/src/util/open.js +41 -0
- package/dist/src/util/open.js.map +1 -0
- package/docs/ARCHITECTURE.md +123 -0
- package/docs/AUTH.md +242 -0
- package/docs/BACKEND.md +169 -0
- package/docs/CLIENTS.md +154 -0
- package/docs/DEVELOPMENT.md +171 -0
- package/docs/README.md +84 -0
- package/docs/TOOLS.md +221 -0
- package/package.json +67 -0
- package/skill/imagegen/LICENSE.txt +201 -0
- package/skill/imagegen/SKILL.md +189 -0
- package/skill/imagegen/references/prompting.md +112 -0
- package/skill/imagegen/references/sample-prompts.md +418 -0
- package/skill/imagegen/references/tools.md +90 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"images-client.js","sourceRoot":"","sources":["../../../src/backend/images-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { formatWhen } from "../util/format.js";
|
|
2
|
+
import { isRecord, num, str } from "../util/http.js";
|
|
3
|
+
const WINDOW_HEADER = /^x-([a-z0-9-]+?)-(primary|secondary)-(used-percent|window-minutes|reset-at|reset-after-seconds)$/;
|
|
4
|
+
const WINDOW_FIELD = {
|
|
5
|
+
"used-percent": "usedPercent",
|
|
6
|
+
"window-minutes": "windowMinutes",
|
|
7
|
+
"reset-at": "resetAt",
|
|
8
|
+
"reset-after-seconds": "resetAfterSeconds",
|
|
9
|
+
};
|
|
10
|
+
function bool(value) {
|
|
11
|
+
if (value === null)
|
|
12
|
+
return undefined;
|
|
13
|
+
if (/^true$/i.test(value))
|
|
14
|
+
return true;
|
|
15
|
+
if (/^false$/i.test(value))
|
|
16
|
+
return false;
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
export function parseRateLimitHeaders(headers) {
|
|
20
|
+
const snapshot = { limits: {} };
|
|
21
|
+
let found = false;
|
|
22
|
+
headers.forEach((value, key) => {
|
|
23
|
+
const name = key.toLowerCase();
|
|
24
|
+
const m = WINDOW_HEADER.exec(name);
|
|
25
|
+
if (m) {
|
|
26
|
+
const [, id, which, field] = m;
|
|
27
|
+
const n = num(value);
|
|
28
|
+
const prop = WINDOW_FIELD[field];
|
|
29
|
+
if (n === undefined || !prop)
|
|
30
|
+
return;
|
|
31
|
+
const limit = (snapshot.limits[id] ??= {});
|
|
32
|
+
const window = (limit[which] ??= {});
|
|
33
|
+
window[prop] = n;
|
|
34
|
+
found = true;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const limitName = /^x-([a-z0-9-]+?)-limit-name$/.exec(name);
|
|
38
|
+
if (limitName?.[1] && value) {
|
|
39
|
+
(snapshot.limits[limitName[1]] ??= {}).name = value;
|
|
40
|
+
found = true;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
const plan = headers.get("x-codex-plan-type");
|
|
44
|
+
if (plan)
|
|
45
|
+
snapshot.planType = plan;
|
|
46
|
+
const active = headers.get("x-codex-active-limit");
|
|
47
|
+
if (active)
|
|
48
|
+
snapshot.activeLimit = active;
|
|
49
|
+
const hasCredits = bool(headers.get("x-codex-credits-has-credits"));
|
|
50
|
+
const unlimited = bool(headers.get("x-codex-credits-unlimited"));
|
|
51
|
+
const balance = headers.get("x-codex-credits-balance");
|
|
52
|
+
if (hasCredits !== undefined || unlimited !== undefined || balance) {
|
|
53
|
+
snapshot.credits = {};
|
|
54
|
+
if (hasCredits !== undefined)
|
|
55
|
+
snapshot.credits.hasCredits = hasCredits;
|
|
56
|
+
if (unlimited !== undefined)
|
|
57
|
+
snapshot.credits.unlimited = unlimited;
|
|
58
|
+
if (balance)
|
|
59
|
+
snapshot.credits.balance = balance;
|
|
60
|
+
}
|
|
61
|
+
return found || plan || active ? snapshot : undefined;
|
|
62
|
+
}
|
|
63
|
+
/** Latest reset time (epoch seconds) among windows that are exhausted. */
|
|
64
|
+
export function exhaustedResetAt(snapshot) {
|
|
65
|
+
if (!snapshot)
|
|
66
|
+
return undefined;
|
|
67
|
+
let latest;
|
|
68
|
+
for (const limit of Object.values(snapshot.limits)) {
|
|
69
|
+
for (const w of [limit.primary, limit.secondary]) {
|
|
70
|
+
if (w?.usedPercent !== undefined && w.usedPercent >= 100 && w.resetAt !== undefined) {
|
|
71
|
+
latest = latest === undefined ? w.resetAt : Math.max(latest, w.resetAt);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return latest;
|
|
76
|
+
}
|
|
77
|
+
function parseWindow(raw) {
|
|
78
|
+
if (!isRecord(raw))
|
|
79
|
+
return undefined;
|
|
80
|
+
const w = {};
|
|
81
|
+
const used = num(raw.used_percent);
|
|
82
|
+
if (used !== undefined)
|
|
83
|
+
w.usedPercent = used;
|
|
84
|
+
const secs = num(raw.limit_window_seconds);
|
|
85
|
+
if (secs !== undefined)
|
|
86
|
+
w.windowSeconds = secs;
|
|
87
|
+
const resetAt = num(raw.reset_at);
|
|
88
|
+
if (resetAt !== undefined)
|
|
89
|
+
w.resetAt = resetAt;
|
|
90
|
+
const after = num(raw.reset_after_seconds);
|
|
91
|
+
if (after !== undefined)
|
|
92
|
+
w.resetAfterSeconds = after;
|
|
93
|
+
return w;
|
|
94
|
+
}
|
|
95
|
+
function parseLimitBlock(raw) {
|
|
96
|
+
if (!isRecord(raw))
|
|
97
|
+
return {};
|
|
98
|
+
const out = {};
|
|
99
|
+
if (typeof raw.allowed === "boolean")
|
|
100
|
+
out.allowed = raw.allowed;
|
|
101
|
+
if (typeof raw.limit_reached === "boolean")
|
|
102
|
+
out.limitReached = raw.limit_reached;
|
|
103
|
+
const primary = parseWindow(raw.primary_window);
|
|
104
|
+
if (primary)
|
|
105
|
+
out.primary = primary;
|
|
106
|
+
const secondary = parseWindow(raw.secondary_window);
|
|
107
|
+
if (secondary)
|
|
108
|
+
out.secondary = secondary;
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
export function parseUsageResponse(json) {
|
|
112
|
+
const out = { additional: [] };
|
|
113
|
+
if (!isRecord(json))
|
|
114
|
+
return out;
|
|
115
|
+
const plan = str(json.plan_type);
|
|
116
|
+
if (plan)
|
|
117
|
+
out.planType = plan;
|
|
118
|
+
Object.assign(out, parseLimitBlock(json.rate_limit));
|
|
119
|
+
const additional = json.additional_rate_limits;
|
|
120
|
+
const entries = Array.isArray(additional) ? additional : isRecord(additional) ? Object.entries(additional).map(([k, v]) => ({ limit_name: k, ...(isRecord(v) ? v : {}) })) : [];
|
|
121
|
+
for (const entry of entries) {
|
|
122
|
+
if (!isRecord(entry))
|
|
123
|
+
continue;
|
|
124
|
+
const name = str(entry.limit_name) ?? str(entry.metered_feature) ?? "additional";
|
|
125
|
+
const block = parseLimitBlock(isRecord(entry.rate_limit) ? entry.rate_limit : entry);
|
|
126
|
+
const limit = { name };
|
|
127
|
+
if (block.limitReached !== undefined)
|
|
128
|
+
limit.limitReached = block.limitReached;
|
|
129
|
+
if (block.primary)
|
|
130
|
+
limit.primary = block.primary;
|
|
131
|
+
if (block.secondary)
|
|
132
|
+
limit.secondary = block.secondary;
|
|
133
|
+
out.additional.push(limit);
|
|
134
|
+
}
|
|
135
|
+
if (isRecord(json.credits)) {
|
|
136
|
+
out.credits = {};
|
|
137
|
+
if (typeof json.credits.has_credits === "boolean")
|
|
138
|
+
out.credits.hasCredits = json.credits.has_credits;
|
|
139
|
+
if (typeof json.credits.unlimited === "boolean")
|
|
140
|
+
out.credits.unlimited = json.credits.unlimited;
|
|
141
|
+
const balance = str(json.credits.balance);
|
|
142
|
+
if (balance)
|
|
143
|
+
out.credits.balance = balance;
|
|
144
|
+
}
|
|
145
|
+
const reachedType = str(json.rate_limit_reached_type);
|
|
146
|
+
if (reachedType)
|
|
147
|
+
out.limitReachedType = reachedType;
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
function windowLabel(seconds) {
|
|
151
|
+
if (seconds === undefined)
|
|
152
|
+
return "window";
|
|
153
|
+
if (seconds === 604_800)
|
|
154
|
+
return "weekly window";
|
|
155
|
+
if (seconds % 86_400 === 0)
|
|
156
|
+
return `${seconds / 86_400}-day window`;
|
|
157
|
+
if (seconds % 3_600 === 0)
|
|
158
|
+
return `${seconds / 3_600}-hour window`;
|
|
159
|
+
return `${Math.round(seconds / 60)}-minute window`;
|
|
160
|
+
}
|
|
161
|
+
export function describeUsageWindow(w, now = Date.now()) {
|
|
162
|
+
const used = w.usedPercent === undefined ? "?" : `${Math.round(w.usedPercent)}%`;
|
|
163
|
+
const reset = w.resetAt !== undefined ? `, resets ${formatWhen(w.resetAt * 1000, now)}` : "";
|
|
164
|
+
return `${windowLabel(w.windowSeconds)}: ${used} used${reset}`;
|
|
165
|
+
}
|
|
166
|
+
/** Human-readable usage lines for status output. */
|
|
167
|
+
export function describeUsage(u, now = Date.now()) {
|
|
168
|
+
const lines = [];
|
|
169
|
+
if (u.limitReached)
|
|
170
|
+
lines.push(`Limit reached${u.limitReachedType ? ` (${u.limitReachedType})` : ""}.`);
|
|
171
|
+
if (u.primary)
|
|
172
|
+
lines.push(`Codex ${describeUsageWindow(u.primary, now)}`);
|
|
173
|
+
if (u.secondary)
|
|
174
|
+
lines.push(`Codex ${describeUsageWindow(u.secondary, now)}`);
|
|
175
|
+
for (const a of u.additional) {
|
|
176
|
+
if (a.primary)
|
|
177
|
+
lines.push(`${a.name} ${describeUsageWindow(a.primary, now)}`);
|
|
178
|
+
if (a.secondary)
|
|
179
|
+
lines.push(`${a.name} ${describeUsageWindow(a.secondary, now)}`);
|
|
180
|
+
}
|
|
181
|
+
return lines;
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=ratelimits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ratelimits.js","sourceRoot":"","sources":["../../../src/backend/ratelimits.ts"],"names":[],"mappings":"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"}
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
3
|
+
import { startBrowserLogin } from "./auth/browser-login.js";
|
|
4
|
+
import { startDeviceLogin } from "./auth/device-login.js";
|
|
5
|
+
import { loadConfig } from "./config.js";
|
|
6
|
+
import { DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_SERVER_NAME, PACKAGE_NAME, SKILL_SOURCE_DIR, VERSION } from "./constants.js";
|
|
7
|
+
import { runDoctor } from "./doctor.js";
|
|
8
|
+
import { describeError, ImagegenError, toImagegenError } from "./errors.js";
|
|
9
|
+
import { ASPECT_RATIOS, runGeneration } from "./generation.js";
|
|
10
|
+
import { installOpencode, uninstallOpencode } from "./install/opencode.js";
|
|
11
|
+
import { absoluteServerCommand, clientSnippet, CLIENTS } from "./install/snippets.js";
|
|
12
|
+
import { createLogger } from "./log.js";
|
|
13
|
+
import { runRemoveBackground } from "./remove-background.js";
|
|
14
|
+
import { createDeps, runStdioServer } from "./server/index.js";
|
|
15
|
+
import { collectStatus, formatStatus } from "./status.js";
|
|
16
|
+
import { formatBytes, formatSeconds } from "./util/format.js";
|
|
17
|
+
import { cliInvocation, detectInvocation, serverCommand } from "./util/invocation.js";
|
|
18
|
+
import { openInBrowser } from "./util/open.js";
|
|
19
|
+
const HELP = `${PACKAGE_NAME} ${VERSION}
|
|
20
|
+
OpenAI Codex's image generation (gpt-image via your ChatGPT plan — no API key) as an MCP
|
|
21
|
+
server + Agent Skill for opencode, Claude Code, Cursor, VS Code and other MCP clients.
|
|
22
|
+
|
|
23
|
+
Usage: ${PACKAGE_NAME} <command> [options]
|
|
24
|
+
|
|
25
|
+
Setup
|
|
26
|
+
install [opencode] Add the MCP server + skill to opencode (global; --project for ./opencode.json)
|
|
27
|
+
--project --name <server> --no-skill --dry-run --force --timeout <ms>
|
|
28
|
+
--command "<cmd …>" custom launch command --env KEY=VALUE (repeatable)
|
|
29
|
+
uninstall [opencode] Remove them again (--project --name --keep-skill --dry-run)
|
|
30
|
+
config <client> Print the config for: ${CLIENTS.join(", ")}
|
|
31
|
+
doctor Diagnose Node, credentials, backend reachability, opencode setup
|
|
32
|
+
|
|
33
|
+
Account
|
|
34
|
+
login Sign in with your ChatGPT account in the browser
|
|
35
|
+
--device use a device code instead (headless/remote machines)
|
|
36
|
+
--no-browser print the URL instead of opening it
|
|
37
|
+
logout Delete this tool's saved sign-in (--no-revoke keeps it valid server-side)
|
|
38
|
+
status Sign-in state, credential sources and usage (--json, --no-usage)
|
|
39
|
+
|
|
40
|
+
Images (terminal use; the same engine as the MCP tools)
|
|
41
|
+
generate <prompt…> Generate an image; with --image it edits/uses references
|
|
42
|
+
-o, --out <path> file or directory (default: ~/.local/share/${PACKAGE_NAME}/images)
|
|
43
|
+
-i, --image <ref> input image path/URL (repeatable, max 5)
|
|
44
|
+
-a, --aspect <ratio> ${ASPECT_RATIOS.join(", ")}
|
|
45
|
+
-b, --background <auto|transparent|opaque> -n <1-4> --format <png|jpeg> --overwrite --json
|
|
46
|
+
remove-bg <input> Remove a flat background locally (chroma key) -> transparent PNG
|
|
47
|
+
-o, --out <path> --key-color <#hex> --hard --no-despill --tolerance <n>
|
|
48
|
+
--transparent-threshold <n> --opaque-threshold <n> --edge-contract <n> --edge-feather <n> --overwrite
|
|
49
|
+
|
|
50
|
+
Server
|
|
51
|
+
serve Run the MCP server on stdio (this is what MCP clients launch)
|
|
52
|
+
|
|
53
|
+
Environment: CODEX_IMAGEGEN_HOME, CODEX_IMAGEGEN_OUTPUT_DIR, CODEX_IMAGEGEN_CREDENTIALS
|
|
54
|
+
(auto|own|codex|opencode), CODEX_IMAGEGEN_TIMEOUT_MS, CODEX_IMAGEGEN_LOG_LEVEL, CODEX_HOME.
|
|
55
|
+
Docs: README.md and docs/ in the package.`;
|
|
56
|
+
function out(line = "") {
|
|
57
|
+
process.stdout.write(`${line}\n`);
|
|
58
|
+
}
|
|
59
|
+
function fail(message, code = 1) {
|
|
60
|
+
process.stderr.write(`Error: ${message}\n`);
|
|
61
|
+
process.exit(code);
|
|
62
|
+
}
|
|
63
|
+
function parse(args, options, allowPositionals = false) {
|
|
64
|
+
try {
|
|
65
|
+
return parseArgs({ args, options, allowPositionals, strict: true });
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
fail(`${err instanceof Error ? err.message : String(err)}\nRun \`${PACKAGE_NAME} help\` for usage.`, 2);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function cliDeps() {
|
|
72
|
+
const config = loadConfig();
|
|
73
|
+
const logger = createLogger({ level: config.logLevel === "debug" ? "debug" : "warn", stderr: true });
|
|
74
|
+
return createDeps(config, logger);
|
|
75
|
+
}
|
|
76
|
+
function intOption(value, name, min, max) {
|
|
77
|
+
if (value === undefined)
|
|
78
|
+
return undefined;
|
|
79
|
+
const n = Number(value);
|
|
80
|
+
if (!Number.isFinite(n) || n < min || n > max)
|
|
81
|
+
fail(`--${name} must be a number between ${min} and ${max}.`, 2);
|
|
82
|
+
return n;
|
|
83
|
+
}
|
|
84
|
+
function abortOnSigint() {
|
|
85
|
+
const controller = new AbortController();
|
|
86
|
+
process.once("SIGINT", () => {
|
|
87
|
+
process.stderr.write("\nCancelled.\n");
|
|
88
|
+
controller.abort(new ImagegenError("cancelled", "Cancelled by user."));
|
|
89
|
+
});
|
|
90
|
+
return controller.signal;
|
|
91
|
+
}
|
|
92
|
+
async function cmdLogin(args) {
|
|
93
|
+
const { values } = parse(args, { device: { type: "boolean" }, "no-browser": { type: "boolean" } });
|
|
94
|
+
const deps = cliDeps();
|
|
95
|
+
const signal = abortOnSigint();
|
|
96
|
+
let tokens;
|
|
97
|
+
const method = values.device ? "device" : "browser";
|
|
98
|
+
if (values.device) {
|
|
99
|
+
const login = await startDeviceLogin(deps.auth.oauthClient, signal);
|
|
100
|
+
out(`To sign in, open this page on any device and enter the code:\n\n ${login.verificationUrl}\n Code: ${login.userCode}\n`);
|
|
101
|
+
out("The code expires in 15 minutes. If ChatGPT says device codes are disabled, enable");
|
|
102
|
+
out("“device code authorization for Codex” in ChatGPT → Settings → Security, or use browser login.\n");
|
|
103
|
+
out("Waiting for approval… (Ctrl+C to cancel)");
|
|
104
|
+
tokens = await login.result;
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
const login = await startBrowserLogin({ ...deps.auth.oauthClient, originator: deps.config.originator, signal });
|
|
108
|
+
const opened = !values["no-browser"] && !deps.config.noBrowser ? await openInBrowser(login.url) : false;
|
|
109
|
+
out(opened ? "Opened your browser to sign in with ChatGPT. If it did not open, visit:\n" : "Open this URL in a browser on this machine to sign in with ChatGPT:\n");
|
|
110
|
+
out(` ${login.url}\n`);
|
|
111
|
+
out("Waiting for you to finish signing in… (Ctrl+C to cancel; use --device on a headless machine)");
|
|
112
|
+
tokens = await login.result;
|
|
113
|
+
}
|
|
114
|
+
const { identity, revokedPrevious } = await deps.auth.saveLogin(tokens, method);
|
|
115
|
+
out(`\n✓ Signed in${identity.email ? ` as ${identity.email}` : ""}${identity.planType ? ` (ChatGPT ${identity.planType} plan)` : ""}.`);
|
|
116
|
+
if (revokedPrevious)
|
|
117
|
+
out(" The previous sign-in of this tool was revoked.");
|
|
118
|
+
if (identity.planType === "free")
|
|
119
|
+
out(" Note: Codex image generation is not available on the ChatGPT Free plan.");
|
|
120
|
+
out(` Credentials saved to ${deps.config.authFile} (readable only by you).`);
|
|
121
|
+
}
|
|
122
|
+
async function cmdLogout(args) {
|
|
123
|
+
const { values } = parse(args, { "no-revoke": { type: "boolean" } });
|
|
124
|
+
const deps = cliDeps();
|
|
125
|
+
const r = await deps.auth.logout({ revoke: !values["no-revoke"] });
|
|
126
|
+
if (!r.hadCredentials && !r.removed) {
|
|
127
|
+
out(`Not signed in (no credentials at ${deps.config.authFile}).`);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
out(`✓ Signed out: removed ${deps.config.authFile}${r.revoked ? " and revoked the sign-in" : values["no-revoke"] ? "" : " (revocation could not be confirmed)"}.`);
|
|
131
|
+
}
|
|
132
|
+
out("Borrowed Codex/opencode sign-ins are never modified; sign out of those apps separately if needed.");
|
|
133
|
+
}
|
|
134
|
+
async function cmdStatus(args) {
|
|
135
|
+
const { values } = parse(args, { json: { type: "boolean" }, "no-usage": { type: "boolean" } });
|
|
136
|
+
const deps = cliDeps();
|
|
137
|
+
const report = await collectStatus(deps, { checkUsage: !values["no-usage"] });
|
|
138
|
+
if (values.json)
|
|
139
|
+
out(JSON.stringify(report, null, 2));
|
|
140
|
+
else
|
|
141
|
+
out(formatStatus(report));
|
|
142
|
+
if (!report.signedIn)
|
|
143
|
+
process.exitCode = 1;
|
|
144
|
+
}
|
|
145
|
+
async function cmdGenerate(args) {
|
|
146
|
+
const { values, positionals } = parse(args, {
|
|
147
|
+
out: { type: "string", short: "o" },
|
|
148
|
+
image: { type: "string", short: "i", multiple: true },
|
|
149
|
+
aspect: { type: "string", short: "a" },
|
|
150
|
+
background: { type: "string", short: "b" },
|
|
151
|
+
n: { type: "string", short: "n" },
|
|
152
|
+
format: { type: "string" },
|
|
153
|
+
overwrite: { type: "boolean" },
|
|
154
|
+
json: { type: "boolean" },
|
|
155
|
+
}, true);
|
|
156
|
+
const prompt = positionals.join(" ").trim();
|
|
157
|
+
if (!prompt)
|
|
158
|
+
fail("Provide a prompt, e.g. `generate \"a watercolor fox\" -o fox.png`.", 2);
|
|
159
|
+
const aspect = values.aspect ?? "auto";
|
|
160
|
+
if (!ASPECT_RATIOS.includes(aspect))
|
|
161
|
+
fail(`--aspect must be one of ${ASPECT_RATIOS.join(", ")}.`, 2);
|
|
162
|
+
const background = values.background ?? "auto";
|
|
163
|
+
if (!["auto", "transparent", "opaque"].includes(background))
|
|
164
|
+
fail("--background must be auto, transparent or opaque.", 2);
|
|
165
|
+
if (values.format && !["png", "jpeg"].includes(values.format))
|
|
166
|
+
fail("--format must be png or jpeg.", 2);
|
|
167
|
+
const images = values.image ?? [];
|
|
168
|
+
const req = {
|
|
169
|
+
tool: images.length > 0 ? "edit_image" : "generate_image",
|
|
170
|
+
prompt,
|
|
171
|
+
aspectRatio: aspect,
|
|
172
|
+
background: background,
|
|
173
|
+
n: intOption(values.n, "n", 1, 4) ?? 1,
|
|
174
|
+
overwrite: Boolean(values.overwrite),
|
|
175
|
+
preview: false,
|
|
176
|
+
};
|
|
177
|
+
if (images.length > 0)
|
|
178
|
+
req.imageRefs = images;
|
|
179
|
+
if (values.out)
|
|
180
|
+
req.outputPath = values.out;
|
|
181
|
+
if (values.format)
|
|
182
|
+
req.outputFormat = values.format;
|
|
183
|
+
const deps = cliDeps();
|
|
184
|
+
const signal = abortOnSigint();
|
|
185
|
+
if (!values.json)
|
|
186
|
+
process.stderr.write(`${req.tool === "edit_image" ? "Editing" : "Generating"}… (usually 15-60 s)\n`);
|
|
187
|
+
const result = await runGeneration(deps, req, {
|
|
188
|
+
baseDir: process.cwd(),
|
|
189
|
+
signal,
|
|
190
|
+
onProgress: (m) => (values.json ? undefined : process.stderr.write(`${m}\n`)),
|
|
191
|
+
});
|
|
192
|
+
if (values.json) {
|
|
193
|
+
out(JSON.stringify({ ...result, saved: result.saved.map(({ preview: _p, ...s }) => s), failures: result.failures.map((f) => ({ kind: f.kind, message: f.message })) }, null, 2));
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
for (const s of result.saved) {
|
|
197
|
+
out(`✓ ${s.path} (${s.width ?? "?"}×${s.height ?? "?"}, ${formatBytes(s.bytes)}, ${s.transparent === true || s.background === "transparent" ? "transparent" : "opaque"}, ${formatSeconds(s.elapsedMs)})`);
|
|
198
|
+
}
|
|
199
|
+
for (const w of result.warnings)
|
|
200
|
+
process.stderr.write(`Warning: ${w}\n`);
|
|
201
|
+
for (const f of result.failures)
|
|
202
|
+
process.stderr.write(`✗ ${describeError(f)}\n`);
|
|
203
|
+
}
|
|
204
|
+
if (result.saved.length === 0)
|
|
205
|
+
process.exitCode = 1;
|
|
206
|
+
}
|
|
207
|
+
async function cmdRemoveBg(args) {
|
|
208
|
+
const { values, positionals } = parse(args, {
|
|
209
|
+
out: { type: "string", short: "o" },
|
|
210
|
+
"key-color": { type: "string" },
|
|
211
|
+
hard: { type: "boolean" },
|
|
212
|
+
"no-despill": { type: "boolean" },
|
|
213
|
+
tolerance: { type: "string" },
|
|
214
|
+
"transparent-threshold": { type: "string" },
|
|
215
|
+
"opaque-threshold": { type: "string" },
|
|
216
|
+
"edge-contract": { type: "string" },
|
|
217
|
+
"edge-feather": { type: "string" },
|
|
218
|
+
overwrite: { type: "boolean" },
|
|
219
|
+
}, true);
|
|
220
|
+
const input = positionals[0];
|
|
221
|
+
if (!input)
|
|
222
|
+
fail("Provide an input image, e.g. `remove-bg sprite.png -o sprite-cutout.png`.", 2);
|
|
223
|
+
const deps = cliDeps();
|
|
224
|
+
const req = {
|
|
225
|
+
inputPath: input,
|
|
226
|
+
softMatte: !values.hard,
|
|
227
|
+
despill: !values["no-despill"],
|
|
228
|
+
overwrite: Boolean(values.overwrite),
|
|
229
|
+
preview: false,
|
|
230
|
+
};
|
|
231
|
+
if (values.out)
|
|
232
|
+
req.outputPath = values.out;
|
|
233
|
+
if (values["key-color"])
|
|
234
|
+
req.keyColor = values["key-color"];
|
|
235
|
+
const tol = intOption(values.tolerance, "tolerance", 0, 255);
|
|
236
|
+
if (tol !== undefined)
|
|
237
|
+
req.tolerance = tol;
|
|
238
|
+
const tt = intOption(values["transparent-threshold"], "transparent-threshold", 0, 255);
|
|
239
|
+
if (tt !== undefined)
|
|
240
|
+
req.transparentThreshold = tt;
|
|
241
|
+
const ot = intOption(values["opaque-threshold"], "opaque-threshold", 0, 255);
|
|
242
|
+
if (ot !== undefined)
|
|
243
|
+
req.opaqueThreshold = ot;
|
|
244
|
+
const ec = intOption(values["edge-contract"], "edge-contract", 0, 16);
|
|
245
|
+
if (ec !== undefined)
|
|
246
|
+
req.edgeContract = ec;
|
|
247
|
+
const ef = intOption(values["edge-feather"], "edge-feather", 0, 64);
|
|
248
|
+
if (ef !== undefined)
|
|
249
|
+
req.edgeFeather = ef;
|
|
250
|
+
const r = await runRemoveBackground(deps, req, { baseDir: process.cwd() });
|
|
251
|
+
out(`✓ ${r.outputPath} (${r.width}×${r.height}, key ${r.keyColor}, ${r.transparentPercent.toFixed(1)}% transparent, ${r.partialPercent.toFixed(1)}% soft edges)`);
|
|
252
|
+
for (const w of r.warnings)
|
|
253
|
+
process.stderr.write(`Warning: ${w}\n`);
|
|
254
|
+
}
|
|
255
|
+
function printReport(report, dryRun) {
|
|
256
|
+
if (dryRun)
|
|
257
|
+
out("(dry run — nothing was written)");
|
|
258
|
+
for (const step of report.steps)
|
|
259
|
+
out(`✓ ${step.action}: ${step.path}`);
|
|
260
|
+
for (const w of report.warnings)
|
|
261
|
+
out(`! ${w}`);
|
|
262
|
+
}
|
|
263
|
+
async function cmdInstall(args) {
|
|
264
|
+
const { values, positionals } = parse(args, {
|
|
265
|
+
project: { type: "boolean" },
|
|
266
|
+
name: { type: "string" },
|
|
267
|
+
"no-skill": { type: "boolean" },
|
|
268
|
+
"dry-run": { type: "boolean" },
|
|
269
|
+
force: { type: "boolean" },
|
|
270
|
+
timeout: { type: "string" },
|
|
271
|
+
command: { type: "string" },
|
|
272
|
+
env: { type: "string", multiple: true },
|
|
273
|
+
}, true);
|
|
274
|
+
const client = (positionals[0] ?? "opencode");
|
|
275
|
+
const serverName = values.name ?? DEFAULT_SERVER_NAME;
|
|
276
|
+
const command = values.command ? values.command.trim().split(/\s+/) : serverCommand();
|
|
277
|
+
if (client !== "opencode") {
|
|
278
|
+
if (!CLIENTS.includes(client))
|
|
279
|
+
fail(`Unknown client "${client}". Known: ${CLIENTS.join(", ")}.`, 2);
|
|
280
|
+
out(`Automatic install is implemented for opencode. For ${client}, add this configuration:\n`);
|
|
281
|
+
printSnippet(client, serverName, command);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
const environment = {};
|
|
285
|
+
for (const pair of values.env ?? []) {
|
|
286
|
+
const eq = pair.indexOf("=");
|
|
287
|
+
if (eq <= 0)
|
|
288
|
+
fail(`--env expects KEY=VALUE (got "${pair}").`, 2);
|
|
289
|
+
environment[pair.slice(0, eq)] = pair.slice(eq + 1);
|
|
290
|
+
}
|
|
291
|
+
const dryRun = Boolean(values["dry-run"]);
|
|
292
|
+
const report = await installOpencode({
|
|
293
|
+
scope: values.project ? "project" : "global",
|
|
294
|
+
projectDir: process.cwd(),
|
|
295
|
+
serverName,
|
|
296
|
+
command,
|
|
297
|
+
environment,
|
|
298
|
+
timeoutMs: intOption(values.timeout, "timeout", 10_000, 3_600_000) ?? DEFAULT_REQUEST_TIMEOUT_MS,
|
|
299
|
+
installSkill: !values["no-skill"],
|
|
300
|
+
dryRun,
|
|
301
|
+
force: Boolean(values.force),
|
|
302
|
+
});
|
|
303
|
+
printReport(report, dryRun);
|
|
304
|
+
out(`\nServer command: ${command.join(" ")}`);
|
|
305
|
+
const deps = cliDeps();
|
|
306
|
+
const status = await collectStatus(deps, { checkUsage: false });
|
|
307
|
+
out(status.active
|
|
308
|
+
? `Credentials: ready (${status.active.label}${status.active.identity?.email ? `, ${status.active.identity.email}` : ""}).`
|
|
309
|
+
: `Credentials: not signed in yet — run \`${cliInvocation()} login\` (or ask the agent to call the sign_in tool).`);
|
|
310
|
+
out(`\nNext: restart opencode, then check \`opencode mcp list\` shows "${serverName}" as connected.`);
|
|
311
|
+
out(`Tools appear as ${serverName}_generate_image, ${serverName}_edit_image, ${serverName}_remove_background, ${serverName}_auth_status, ${serverName}_sign_in.`);
|
|
312
|
+
}
|
|
313
|
+
async function cmdUninstall(args) {
|
|
314
|
+
const { values, positionals } = parse(args, { project: { type: "boolean" }, name: { type: "string" }, "keep-skill": { type: "boolean" }, "dry-run": { type: "boolean" } }, true);
|
|
315
|
+
const client = positionals[0] ?? "opencode";
|
|
316
|
+
if (client !== "opencode")
|
|
317
|
+
fail(`Automatic uninstall is implemented for opencode only; remove the "${values.name ?? DEFAULT_SERVER_NAME}" entry from ${client}'s config manually.`, 2);
|
|
318
|
+
const dryRun = Boolean(values["dry-run"]);
|
|
319
|
+
const report = await uninstallOpencode({
|
|
320
|
+
scope: values.project ? "project" : "global",
|
|
321
|
+
projectDir: process.cwd(),
|
|
322
|
+
serverName: values.name ?? DEFAULT_SERVER_NAME,
|
|
323
|
+
dryRun,
|
|
324
|
+
keepSkill: Boolean(values["keep-skill"]),
|
|
325
|
+
});
|
|
326
|
+
printReport(report, dryRun);
|
|
327
|
+
out(`Your sign-in was kept; run \`${cliInvocation()} logout\` to remove it too.`);
|
|
328
|
+
}
|
|
329
|
+
function printSnippet(client, serverName, command, custom = false) {
|
|
330
|
+
// GUI clients need absolute paths; a custom --command is used exactly as given.
|
|
331
|
+
const { kind, script } = detectInvocation();
|
|
332
|
+
const absolute = !custom && kind !== "npx" && script.endsWith(".js") ? absoluteServerCommand(script) : undefined;
|
|
333
|
+
const s = clientSnippet(client, serverName, command, absolute);
|
|
334
|
+
out(`# ${s.title}\n# ${s.location}\n`);
|
|
335
|
+
out(s.body);
|
|
336
|
+
for (const n of s.notes)
|
|
337
|
+
out(`\n# ${n}`);
|
|
338
|
+
}
|
|
339
|
+
async function cmdConfig(args) {
|
|
340
|
+
const { values, positionals } = parse(args, { name: { type: "string" }, command: { type: "string" } }, true);
|
|
341
|
+
const client = positionals[0];
|
|
342
|
+
if (!client || !CLIENTS.includes(client))
|
|
343
|
+
fail(`Usage: config <client>. Clients: ${CLIENTS.join(", ")}.`, 2);
|
|
344
|
+
const custom = Boolean(values.command);
|
|
345
|
+
printSnippet(client, values.name ?? DEFAULT_SERVER_NAME, custom ? (values.command ?? "").trim().split(/\s+/) : serverCommand(), custom);
|
|
346
|
+
out(`\n# Skill source: ${SKILL_SOURCE_DIR}`);
|
|
347
|
+
}
|
|
348
|
+
async function cmdDoctor(args) {
|
|
349
|
+
const { values } = parse(args, { name: { type: "string" } });
|
|
350
|
+
const deps = cliDeps();
|
|
351
|
+
const checks = await runDoctor(deps, { serverName: values.name ?? DEFAULT_SERVER_NAME, projectDir: process.cwd() });
|
|
352
|
+
const mark = { ok: "✓", warn: "!", fail: "✗" };
|
|
353
|
+
for (const c of checks)
|
|
354
|
+
out(`${mark[c.status]} ${c.name}: ${c.detail}`);
|
|
355
|
+
if (checks.some((c) => c.status === "fail"))
|
|
356
|
+
process.exitCode = 1;
|
|
357
|
+
}
|
|
358
|
+
async function main(argv) {
|
|
359
|
+
const [command, ...rest] = argv;
|
|
360
|
+
switch (command) {
|
|
361
|
+
case undefined:
|
|
362
|
+
if (!process.stdin.isTTY)
|
|
363
|
+
return runStdioServer();
|
|
364
|
+
out(HELP);
|
|
365
|
+
out(`\nTip: MCP clients start this with \`${serverCommand().join(" ")}\`.`);
|
|
366
|
+
return;
|
|
367
|
+
case "serve":
|
|
368
|
+
return runStdioServer();
|
|
369
|
+
case "login":
|
|
370
|
+
return cmdLogin(rest);
|
|
371
|
+
case "logout":
|
|
372
|
+
return cmdLogout(rest);
|
|
373
|
+
case "status":
|
|
374
|
+
return cmdStatus(rest);
|
|
375
|
+
case "generate":
|
|
376
|
+
return cmdGenerate(rest);
|
|
377
|
+
case "remove-bg":
|
|
378
|
+
case "remove-background":
|
|
379
|
+
return cmdRemoveBg(rest);
|
|
380
|
+
case "install":
|
|
381
|
+
return cmdInstall(rest);
|
|
382
|
+
case "uninstall":
|
|
383
|
+
return cmdUninstall(rest);
|
|
384
|
+
case "config":
|
|
385
|
+
return cmdConfig(rest);
|
|
386
|
+
case "doctor":
|
|
387
|
+
return cmdDoctor(rest);
|
|
388
|
+
case "help":
|
|
389
|
+
case "--help":
|
|
390
|
+
case "-h":
|
|
391
|
+
out(HELP);
|
|
392
|
+
return;
|
|
393
|
+
case "version":
|
|
394
|
+
case "--version":
|
|
395
|
+
case "-v":
|
|
396
|
+
out(VERSION);
|
|
397
|
+
return;
|
|
398
|
+
default:
|
|
399
|
+
fail(`Unknown command "${command}". Run \`${PACKAGE_NAME} help\`.`, 2);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
main(process.argv.slice(2)).catch((err) => {
|
|
403
|
+
const e = toImagegenError(err);
|
|
404
|
+
process.stderr.write(`Error: ${describeError(e)}\n`);
|
|
405
|
+
process.exit(e.kind === "cancelled" || e.kind === "login_cancelled" ? 130 : 1);
|
|
406
|
+
});
|
|
407
|
+
//# sourceMappingURL=cli.js.map
|