ima2-gen 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.env.example ADDED
@@ -0,0 +1,2 @@
1
+ OPENAI_API_KEY=sk-proj-your-key-here
2
+ PORT=3333
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # ima2-gen
2
+
3
+ Minimal CLI + web UI for OpenAI `gpt-image-2` image generation.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ git clone https://github.com/lidge-jun/ima2-gen.git
9
+ cd ima2-gen
10
+ npm install
11
+ npm start
12
+ ```
13
+
14
+ First run prompts you to choose:
15
+
16
+ ```
17
+ 1) API Key — paste your OpenAI API key (paid)
18
+ 2) OAuth — login with ChatGPT account (free)
19
+ ```
20
+
21
+ Then opens `http://localhost:3333`.
22
+
23
+ ## CLI
24
+
25
+ ```bash
26
+ npx ima2 serve # start server (auto-setup on first run)
27
+ npx ima2 setup # reconfigure auth
28
+ npx ima2 reset # clear saved config
29
+ ```
30
+
31
+ Or install globally:
32
+
33
+ ```bash
34
+ npm install -g ima2-gen
35
+ ima2 serve
36
+ ```
37
+
38
+ ## Features
39
+
40
+ - **Dual provider** — OAuth (free, ChatGPT account) or API Key (paid)
41
+ - **Text-to-Image** — generate images from text prompts
42
+ - **Image-to-Image** — edit/inpaint with drag-and-drop
43
+ - **Quality** — low / medium / high
44
+ - **Size** — presets (1024 ~ 4K) + custom (any 16px-aligned ratio)
45
+ - **Format** — PNG / JPEG / WebP
46
+ - **Moderation** — auto (standard) / low (less restrictive)
47
+ - **History** — session thumbnail strip
48
+ - **Download / Copy** — save or clipboard
49
+
50
+ ## Architecture
51
+
52
+ ```
53
+ ima2 serve
54
+ ├── Express (:3333) ← web UI + API
55
+ └── openai-oauth (:10531) ← embedded OAuth proxy
56
+ ```
57
+
58
+ ## Config
59
+
60
+ Stored in `.ima2/config.json` (auto-created, gitignored).
61
+
62
+ Optional `.env`:
63
+ ```
64
+ OPENAI_API_KEY=sk-proj-...
65
+ PORT=3333
66
+ OAUTH_PORT=10531
67
+ ```
68
+
69
+ ## Pricing (API Key mode)
70
+
71
+ | Quality | 1024x1024 | 1024x1536 | 1536x1024 |
72
+ |---------|-----------|-----------|-----------|
73
+ | Low | $0.006 | $0.005 | $0.005 |
74
+ | Medium | $0.053 | $0.041 | $0.041 |
75
+ | High | $0.211 | $0.165 | $0.165 |
76
+
77
+ OAuth mode is free (uses your ChatGPT Plus/Pro subscription).
package/bin/ima2.js ADDED
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+ import { createInterface } from "readline/promises";
3
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
4
+ import { join, dirname } from "path";
5
+ import { fileURLToPath } from "url";
6
+ import { spawn, execSync } from "child_process";
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ const ROOT = join(__dirname, "..");
10
+ const CONFIG_DIR = join(ROOT, ".ima2");
11
+ const CONFIG_FILE = join(CONFIG_DIR, "config.json");
12
+
13
+ function loadConfig() {
14
+ if (existsSync(CONFIG_FILE)) {
15
+ return JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
16
+ }
17
+ return {};
18
+ }
19
+
20
+ function saveConfig(config) {
21
+ mkdirSync(CONFIG_DIR, { recursive: true });
22
+ writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
23
+ }
24
+
25
+ async function setup() {
26
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
27
+
28
+ console.log("\n ima2-gen — GPT Image 2 Generator\n");
29
+ console.log(" Choose authentication method:\n");
30
+ console.log(" 1) API Key — paste your OpenAI API key (paid)");
31
+ console.log(" 2) OAuth — login with ChatGPT account (free)\n");
32
+
33
+ const choice = await rl.question(" Enter 1 or 2: ");
34
+ const config = loadConfig();
35
+
36
+ if (choice.trim() === "1") {
37
+ const key = await rl.question(" OpenAI API Key: ");
38
+ if (!key.startsWith("sk-")) {
39
+ console.log(" Invalid API key format. Expected sk-...");
40
+ rl.close();
41
+ process.exit(1);
42
+ }
43
+ config.provider = "api";
44
+ config.apiKey = key.trim();
45
+ saveConfig(config);
46
+ console.log("\n API key saved. Starting server...\n");
47
+ } else {
48
+ config.provider = "oauth";
49
+ delete config.apiKey;
50
+ saveConfig(config);
51
+ console.log("\n Starting OAuth login...\n");
52
+
53
+ // Check if codex auth exists
54
+ const hasAuth =
55
+ existsSync(join(process.env.HOME, ".codex", "auth.json")) ||
56
+ existsSync(join(process.env.HOME, ".chatgpt-local", "auth.json"));
57
+
58
+ if (!hasAuth) {
59
+ console.log(" Running 'codex login' — follow the browser prompt.\n");
60
+ try {
61
+ execSync("npx @openai/codex login", { stdio: "inherit" });
62
+ } catch {
63
+ console.log("\n Login failed or cancelled. You can retry with 'ima2 serve'.\n");
64
+ rl.close();
65
+ process.exit(1);
66
+ }
67
+ } else {
68
+ console.log(" Existing OAuth session found.\n");
69
+ }
70
+
71
+ saveConfig(config);
72
+ console.log(" OAuth configured. Starting server...\n");
73
+ }
74
+
75
+ rl.close();
76
+ return config;
77
+ }
78
+
79
+ async function serve() {
80
+ let config = loadConfig();
81
+
82
+ if (!config.provider) {
83
+ config = await setup();
84
+ }
85
+
86
+ const env = { ...process.env };
87
+
88
+ if (config.provider === "api" && config.apiKey) {
89
+ env.OPENAI_API_KEY = config.apiKey;
90
+ }
91
+
92
+ const serverPath = join(ROOT, "server.js");
93
+ const child = spawn("node", [serverPath], {
94
+ stdio: "inherit",
95
+ env,
96
+ cwd: ROOT,
97
+ });
98
+
99
+ child.on("exit", (code) => process.exit(code));
100
+
101
+ process.on("SIGINT", () => child.kill("SIGINT"));
102
+ process.on("SIGTERM", () => child.kill("SIGTERM"));
103
+ }
104
+
105
+ // ── CLI ──
106
+ const args = process.argv.slice(2);
107
+ const command = args[0];
108
+
109
+ switch (command) {
110
+ case "serve":
111
+ serve();
112
+ break;
113
+ case "setup":
114
+ case "login":
115
+ setup().then(() => console.log(" Done. Run 'ima2 serve' to start."));
116
+ break;
117
+ case "reset":
118
+ if (existsSync(CONFIG_FILE)) {
119
+ writeFileSync(CONFIG_FILE, "{}");
120
+ console.log(" Config reset. Run 'ima2 serve' to reconfigure.");
121
+ }
122
+ break;
123
+ default:
124
+ console.log(`
125
+ ima2-gen — GPT Image 2 Generator
126
+
127
+ Usage:
128
+ ima2 serve Start the image generation server
129
+ ima2 setup Configure API key or OAuth (interactive)
130
+ ima2 reset Reset configuration
131
+
132
+ First run of 'ima2 serve' will prompt for setup automatically.
133
+ `);
134
+ }
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "ima2-gen",
3
+ "version": "1.0.0",
4
+ "description": "GPT Image 2 generator with OAuth & API key support",
5
+ "type": "module",
6
+ "bin": {
7
+ "ima2": "./bin/ima2.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node bin/ima2.js serve",
11
+ "dev": "node --watch server.js",
12
+ "setup": "node bin/ima2.js setup",
13
+ "prepublishOnly": "npm run lint:pkg",
14
+ "lint:pkg": "node -e \"const p=require('./package.json'); if(!p.name||!p.version||!p.bin) throw new Error('missing fields')\"",
15
+ "release:patch": "npm version patch && npm publish && git push origin main --tags",
16
+ "release:minor": "npm version minor && npm publish && git push origin main --tags",
17
+ "release:major": "npm version major && npm publish && git push origin main --tags"
18
+ },
19
+ "keywords": ["openai", "gpt-image-2", "image-generation", "oauth", "cli"],
20
+ "license": "MIT",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/lidge-jun/ima2-gen.git"
24
+ },
25
+ "files": [
26
+ "bin/",
27
+ "public/",
28
+ "server.js",
29
+ ".env.example",
30
+ "README.md"
31
+ ],
32
+ "engines": {
33
+ "node": ">=18"
34
+ },
35
+ "dependencies": {
36
+ "dotenv": "^17.4.2",
37
+ "express": "^5.1.0",
38
+ "openai": "^5.8.2",
39
+ "openai-oauth": "^1.0.2"
40
+ }
41
+ }