egaki 0.2.0 → 0.4.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/CHANGELOG.md +70 -0
- package/README.md +32 -5
- package/dist/chatgpt-auth.d.ts +25 -0
- package/dist/chatgpt-auth.d.ts.map +1 -0
- package/dist/chatgpt-auth.js +18 -11
- package/dist/cli.js +246 -19
- package/dist/credentials.d.ts +17 -4
- package/dist/credentials.d.ts.map +1 -1
- package/dist/credentials.js +55 -10
- package/dist/login.d.ts +1 -1
- package/dist/login.d.ts.map +1 -1
- package/dist/login.js +44 -3
- package/dist/model-catalog.d.ts.map +1 -1
- package/dist/model-catalog.js +87 -3
- package/dist/models.d.ts +5 -0
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +58 -8
- package/dist/video-model-catalog.d.ts.map +1 -1
- package/dist/video-model-catalog.js +61 -0
- package/package.json +5 -2
- package/skills/egaki/SKILL.md +100 -0
- package/src/chatgpt-auth.ts +387 -0
- package/src/cli.ts +317 -22
- package/src/credentials.ts +75 -17
- package/src/login.ts +49 -4
- package/src/model-catalog.ts +92 -3
- package/src/models.ts +59 -8
- package/src/video-model-catalog.ts +61 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,76 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## 0.4.0
|
|
6
|
+
|
|
7
|
+
1. **ChatGPT login for OpenAI image generation** — use your ChatGPT subscription in `egaki` without a separate OpenAI platform API key:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
egaki login --provider chatgpt
|
|
11
|
+
egaki image "a dreamy studio ghibli style bakery at sunrise" -m gpt-image-1.5 -o bakery.png
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
OpenAI image requests authenticated this way now follow the same Codex backend flow used by ChatGPT instead of the normal Image API path.
|
|
15
|
+
|
|
16
|
+
2. **ChatGPT-backed image editing** — edit existing images with OpenAI image models through the ChatGPT/Codex backend:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
egaki image "change the red jacket to a blue jacket" -m gpt-image-1.5 --input portrait.png -o portrait-blue.png
|
|
20
|
+
egaki image "turn this product shot into a clay render" -m gpt-image-1.5 --input product.png -o product-clay.png
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Multiple input images are supported. For this backend path, `egaki` now explicitly rejects unsupported options like `--seed`, `--mask`, and multi-image output instead of pretending they work.
|
|
24
|
+
|
|
25
|
+
3. **Aspect ratio support for ChatGPT image generation** — supported ChatGPT/OpenAI aspect ratios now map to the backend's real size controls:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
egaki image "wide landscape matte painting" -m gpt-image-1.5 --aspect-ratio 3:2 -o wide.png
|
|
29
|
+
egaki image "book cover concept art" -m gpt-image-1.5 --aspect-ratio 2:3 -o cover.png
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Supported ratios on this path are `1:1`, `3:2`, and `2:3`.
|
|
33
|
+
|
|
34
|
+
4. **`egaki models` now shows login availability** — model discovery output includes whether each provider is currently usable from your configured credentials:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
egaki models
|
|
38
|
+
egaki models --json | jq '.[] | {id, provider, auth}'
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The output now includes `auth.available` and `auth.source` (`env`, `stored`, `oauth`, or `none`) so you can see which model families are ready to use.
|
|
42
|
+
|
|
43
|
+
## 0.3.0
|
|
44
|
+
|
|
45
|
+
1. **Google Vertex AI provider** — use Google Cloud billing instead of AI Studio by
|
|
46
|
+
prefixing model IDs with `vertex/`:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
egaki login --provider vertex --key AIza...
|
|
50
|
+
egaki image "product shot on marble" -m vertex/imagen-4.0-generate-001 -o product.png
|
|
51
|
+
egaki image "editorial portrait" -m vertex/gemini-3.1-flash-image-preview --aspect-ratio 4:5
|
|
52
|
+
egaki video "storm over mountains" -m vertex/veo-3.1-fast-generate-001 --duration 6 -o storm.mp4
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Bare model IDs (e.g. `imagen-4.0-generate-001`) continue to route through Google AI
|
|
56
|
+
Studio as before. `vertex/` prefix routes through `@ai-sdk/google-vertex` using your
|
|
57
|
+
`GOOGLE_VERTEX_API_KEY`. The two providers are fully independent — having one key does
|
|
58
|
+
not affect the other.
|
|
59
|
+
|
|
60
|
+
Supported Vertex models:
|
|
61
|
+
- `vertex/imagen-4.0-generate-001`, `vertex/imagen-4.0-ultra-generate-001`, `vertex/imagen-4.0-fast-generate-001`
|
|
62
|
+
- `vertex/gemini-2.5-flash-image`, `vertex/gemini-3-pro-image-preview`, `vertex/gemini-3.1-flash-image-preview`
|
|
63
|
+
- `vertex/veo-3.1-generate-001`, `vertex/veo-3.1-fast-generate-001`
|
|
64
|
+
|
|
65
|
+
2. **`egaki models --provider vertex`** — list only Vertex models:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
egaki models --provider vertex
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
3. **Fixed confusing error for Vertex without a key** — if you attempt a `vertex/` model
|
|
72
|
+
without a `GOOGLE_VERTEX_API_KEY` configured, you now get a clear error pointing you
|
|
73
|
+
to set one up instead of a cryptic upstream failure.
|
|
74
|
+
|
|
5
75
|
## 0.2.0
|
|
6
76
|
|
|
7
77
|
1. **New `egaki video` command** — generate videos from text prompts or still images.
|
package/README.md
CHANGED
|
@@ -20,6 +20,14 @@ egaki image "a watercolor fox reading a map" -o fox.png
|
|
|
20
20
|
egaki video "a paper boat drifting on a calm lake at sunrise" -o boat.mp4
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
### Quick start with ChatGPT auth
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
egaki login --provider chatgpt
|
|
27
|
+
egaki image "a dreamy studio ghibli style bakery at sunrise" -m gpt-image-1.5 -o bakery.png
|
|
28
|
+
egaki image "change the red jacket to a blue jacket" -m gpt-image-1.5 --input portrait.png -o portrait-blue.png
|
|
29
|
+
```
|
|
30
|
+
|
|
23
31
|
## CLI examples
|
|
24
32
|
|
|
25
33
|
### Generate an image from text
|
|
@@ -34,6 +42,7 @@ egaki image "isometric floating city, detailed, soft colors" -m imagen-4.0-gener
|
|
|
34
42
|
```bash
|
|
35
43
|
egaki image "add a red scarf and make it winter" --input portrait.jpg -o portrait-winter.png
|
|
36
44
|
egaki image "turn this into a manga panel" --input https://example.com/photo.jpg -o manga.png
|
|
45
|
+
egaki image "change the red square to a blue square" -m gpt-image-1.5 --input input.png -o output.png
|
|
37
46
|
```
|
|
38
47
|
|
|
39
48
|
### Inpainting with a mask
|
|
@@ -53,6 +62,15 @@ egaki image "minimal logo concepts for a cat cafe" -n 4 -o logo.png
|
|
|
53
62
|
```bash
|
|
54
63
|
egaki image "cyberpunk alley at night" --aspect-ratio 16:9
|
|
55
64
|
egaki image "polaroid-style travel photo" --aspect-ratio 4:5
|
|
65
|
+
egaki image "wide landscape matte painting" -m gpt-image-1.5 --aspect-ratio 3:2 -o wide.png
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Use Google Cloud billing via Vertex AI
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
egaki login --provider vertex --key AIza...
|
|
72
|
+
egaki image "editorial sneaker photo on white seamless" -m vertex/imagen-4.0-generate-001 -o sneaker.png
|
|
73
|
+
egaki video "storm over mountains" -m vertex/veo-3.1-fast-generate-001 --duration 6 -o storm.mp4
|
|
56
74
|
```
|
|
57
75
|
|
|
58
76
|
### Pipe image output to other tools
|
|
@@ -67,7 +85,7 @@ egaki image "flat icon of a fox" --stdout | magick - -resize 512x512 fox-icon.pn
|
|
|
67
85
|
|
|
68
86
|
```bash
|
|
69
87
|
egaki video "a paper boat drifting on a calm lake at sunrise" -o boat.mp4
|
|
70
|
-
egaki video "timelapse of a stormy sea, cinematic" -m
|
|
88
|
+
egaki video "timelapse of a stormy sea, cinematic" -m veo-3.1-generate-001 --duration 8 -o storm.mp4
|
|
71
89
|
```
|
|
72
90
|
|
|
73
91
|
### Generate with a cheap model
|
|
@@ -88,7 +106,7 @@ egaki video "slowly animate the clouds" --input photo.jpg -m klingai/kling-v2.6-
|
|
|
88
106
|
|
|
89
107
|
```bash
|
|
90
108
|
egaki video "aerial drone shot over a city grid" \
|
|
91
|
-
-m
|
|
109
|
+
-m veo-3.1-fast-generate-001 \
|
|
92
110
|
--aspect-ratio 16:9 \
|
|
93
111
|
--resolution 1080p \
|
|
94
112
|
--duration 6 \
|
|
@@ -175,8 +193,9 @@ egaki image "mascot variations, flat vector look" \
|
|
|
175
193
|
|
|
176
194
|
| Model ID | Best for | Example command |
|
|
177
195
|
| --- | --- | --- |
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
196
|
+
| `veo-3.1-generate-001` | Highest quality video with audio, up to 4K | `egaki video "rainy Tokyo street at night" -m veo-3.1-generate-001 --duration 8 -o tokyo.mp4` |
|
|
197
|
+
| `veo-3.1-fast-generate-001` | Fast Veo with 720p–4K, good for iteration | `egaki video "abstract paint patterns" -m veo-3.1-fast-generate-001 --duration 5 -o paint.mp4` |
|
|
198
|
+
| `vertex/veo-3.1-generate-001` | Same as above, routed through Vertex AI | `egaki video "rainy Tokyo street" -m vertex/veo-3.1-generate-001 --duration 8 -o tokyo.mp4` |
|
|
180
199
|
| `klingai/kling-v2.5-turbo-t2v` | Cheap, fast Kling text-to-video | `egaki video "a paper boat on a pond" -m klingai/kling-v2.5-turbo-t2v --duration 5 -o boat.mp4` |
|
|
181
200
|
| `bytedance/seedance-v1.5-pro` | Bytedance, audio support, three resolutions | `egaki video "timelapse of clouds above mountains" -m bytedance/seedance-v1.5-pro -o clouds.mp4` |
|
|
182
201
|
| `xai/grok-imagine-video` | xAI video generation, cheap for short clips | `egaki video "a dog catching a frisbee" -m xai/grok-imagine-video --duration 3 -o dog.mp4` |
|
|
@@ -189,6 +208,7 @@ egaki image "mascot variations, flat vector look" \
|
|
|
189
208
|
- **BFL image models (`flux-*`)**: Kontext/Pro variants via AI Gateway subscription
|
|
190
209
|
- **Recraft models (`recraft-*`)**: v2/v3/v4 families available via AI Gateway subscription
|
|
191
210
|
- **xAI image models (`grok-imagine-*`)**: Grok image generation via AI Gateway subscription
|
|
211
|
+
- **Vertex models (`vertex/*`)**: same models as Google AI Studio, routed through Vertex AI / Google Cloud billing
|
|
192
212
|
- **Google Veo video models**: up to 4K, audio optional, duration 4–8s
|
|
193
213
|
- **Kling video models**: mode (std/pro), audio on v2.6+, image-to-video support
|
|
194
214
|
- **Bytedance Seedance**: 480p–1080p, audio support on v1.5-pro
|
|
@@ -199,7 +219,9 @@ egaki image "mascot variations, flat vector look" \
|
|
|
199
219
|
egaki supports **both** authentication modes:
|
|
200
220
|
|
|
201
221
|
- **BYOK (bring your own keys):** add provider keys with `egaki login` per provider.
|
|
222
|
+
- **ChatGPT auth:** log in with `egaki login --provider chatgpt` to use the ChatGPT/Codex backend for supported OpenAI image generation and editing flows.
|
|
202
223
|
- **Egaki subscription:** use one `egaki_...` key to access all supported models without managing keys for each provider.
|
|
224
|
+
- **Google vs Vertex:** bare model IDs (e.g. `imagen-4.0-generate-001`) use Google AI Studio. Prefix with `vertex/` (e.g. `vertex/imagen-4.0-generate-001`) to route through Vertex AI / Google Cloud billing.
|
|
203
225
|
|
|
204
226
|
```bash
|
|
205
227
|
# Subscribe and get a checkout URL
|
|
@@ -211,8 +233,13 @@ egaki subscribe --plan pro
|
|
|
211
233
|
# Save your Egaki key after checkout
|
|
212
234
|
egaki login --provider egaki --key egaki_...
|
|
213
235
|
|
|
214
|
-
# BYOK
|
|
236
|
+
# BYOK examples (direct provider keys)
|
|
215
237
|
egaki login --provider google --key AIza...
|
|
238
|
+
egaki login --provider vertex --key AIza...
|
|
239
|
+
|
|
240
|
+
# ChatGPT OAuth for Codex-backed image generation/editing
|
|
241
|
+
egaki login --provider chatgpt
|
|
242
|
+
egaki image "turn this product shot into a clay render" -m gpt-image-1.5 --input product.png -o product-clay.png
|
|
216
243
|
|
|
217
244
|
# Check subscription usage / cancel
|
|
218
245
|
egaki usage
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type ChatGptAuth = {
|
|
2
|
+
email?: string;
|
|
3
|
+
accountId?: string;
|
|
4
|
+
plan?: string;
|
|
5
|
+
refresh: string;
|
|
6
|
+
access: string;
|
|
7
|
+
expires: number;
|
|
8
|
+
};
|
|
9
|
+
/** Extract the ChatGPT plan type (e.g. "plus", "pro") from the access token. */
|
|
10
|
+
export declare function extractPlanType(auth: ChatGptAuth): string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Run the full ChatGPT OAuth browser flow with clack UI.
|
|
13
|
+
* Returns the ChatGptAuth object to be stored in credentials.json.
|
|
14
|
+
*/
|
|
15
|
+
export declare function chatGptOAuthLogin(): Promise<ChatGptAuth>;
|
|
16
|
+
/**
|
|
17
|
+
* Refresh an expired ChatGPT access token using the refresh token.
|
|
18
|
+
* Returns the updated auth object, or an Error if refresh fails.
|
|
19
|
+
*/
|
|
20
|
+
export declare function refreshChatGptToken(auth: ChatGptAuth): Promise<ChatGptAuth | Error>;
|
|
21
|
+
/**
|
|
22
|
+
* Refresh the auth object if needed and return the full updated state.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getValidChatGptAuth(auth: ChatGptAuth, onRefresh?: (updated: ChatGptAuth) => void): Promise<ChatGptAuth | Error>;
|
|
25
|
+
//# sourceMappingURL=chatgpt-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chatgpt-auth.d.ts","sourceRoot":"","sources":["../src/chatgpt-auth.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAgGD,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAOrE;AA8JD;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,WAAW,CAAC,CA8C9D;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC,CAyBzF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,WAAW,EACjB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,GACzC,OAAO,CAAC,WAAW,GAAG,KAAK,CAAC,CAS9B"}
|
package/dist/chatgpt-auth.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// Tokens are stored inside credentials.json under the 'chatgpt' key as a
|
|
4
4
|
// structured object (not a plain string like other providers).
|
|
5
5
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
6
|
+
// Tokens are stored so egaki can reuse the ChatGPT login for Codex-style
|
|
7
|
+
// backend requests and refresh them when needed.
|
|
8
8
|
import { createServer } from 'node:http';
|
|
9
9
|
import { spawn } from 'node:child_process';
|
|
10
10
|
import { spinner, log, note } from '@clack/prompts';
|
|
@@ -55,6 +55,13 @@ function extractEmail(tokens) {
|
|
|
55
55
|
return ((typeof idClaims?.email === 'string' ? idClaims.email : undefined) ??
|
|
56
56
|
(typeof accessClaims?.email === 'string' ? accessClaims.email : undefined));
|
|
57
57
|
}
|
|
58
|
+
function extractPlanTypeFromTokens(tokens) {
|
|
59
|
+
const idClaims = tokens.id_token ? parseJwtClaims(tokens.id_token) : undefined;
|
|
60
|
+
const accessClaims = parseJwtClaims(tokens.access_token);
|
|
61
|
+
const idAuth = idClaims?.['https://api.openai.com/auth'];
|
|
62
|
+
const accessAuth = accessClaims?.['https://api.openai.com/auth'];
|
|
63
|
+
return idAuth?.chatgpt_plan_type ?? accessAuth?.chatgpt_plan_type;
|
|
64
|
+
}
|
|
58
65
|
function extractAccountId(tokens) {
|
|
59
66
|
const idClaims = tokens.id_token ? parseJwtClaims(tokens.id_token) : undefined;
|
|
60
67
|
const accessClaims = parseJwtClaims(tokens.access_token);
|
|
@@ -71,6 +78,8 @@ function extractAccountId(tokens) {
|
|
|
71
78
|
}
|
|
72
79
|
/** Extract the ChatGPT plan type (e.g. "plus", "pro") from the access token. */
|
|
73
80
|
export function extractPlanType(auth) {
|
|
81
|
+
if (auth.plan)
|
|
82
|
+
return auth.plan;
|
|
74
83
|
const claims = parseJwtClaims(auth.access);
|
|
75
84
|
const authClaim = claims?.['https://api.openai.com/auth'];
|
|
76
85
|
return authClaim?.chatgpt_plan_type;
|
|
@@ -81,7 +90,7 @@ function buildAuthorizeUrl(pkce, state) {
|
|
|
81
90
|
response_type: 'code',
|
|
82
91
|
client_id: CLIENT_ID,
|
|
83
92
|
redirect_uri: REDIRECT_URI,
|
|
84
|
-
scope: 'openid profile email offline_access',
|
|
93
|
+
scope: 'openid profile email offline_access api.connectors.read api.connectors.invoke',
|
|
85
94
|
code_challenge: pkce.challenge,
|
|
86
95
|
code_challenge_method: 'S256',
|
|
87
96
|
id_token_add_organizations: 'true',
|
|
@@ -236,6 +245,7 @@ export async function chatGptOAuthLogin() {
|
|
|
236
245
|
const auth = {
|
|
237
246
|
email: extractEmail(tokens),
|
|
238
247
|
accountId: extractAccountId(tokens),
|
|
248
|
+
plan: extractPlanTypeFromTokens(tokens),
|
|
239
249
|
refresh: tokens.refresh_token,
|
|
240
250
|
access: tokens.access_token,
|
|
241
251
|
expires: now + (tokens.expires_in ?? 3600) * 1000,
|
|
@@ -266,6 +276,7 @@ export async function refreshChatGptToken(auth) {
|
|
|
266
276
|
const json = (await response.json());
|
|
267
277
|
return {
|
|
268
278
|
...auth,
|
|
279
|
+
plan: extractPlanTypeFromTokens(json) ?? auth.plan,
|
|
269
280
|
access: json.access_token,
|
|
270
281
|
refresh: json.refresh_token ?? auth.refresh,
|
|
271
282
|
expires: Date.now() + (json.expires_in ?? 3600) * 1000,
|
|
@@ -276,19 +287,15 @@ export async function refreshChatGptToken(auth) {
|
|
|
276
287
|
}
|
|
277
288
|
}
|
|
278
289
|
/**
|
|
279
|
-
*
|
|
280
|
-
* Auto-refreshes if expired. Returns the token string or an Error.
|
|
281
|
-
* If the auth was refreshed, the `onRefresh` callback is called with
|
|
282
|
-
* the updated auth so the caller can persist it.
|
|
290
|
+
* Refresh the auth object if needed and return the full updated state.
|
|
283
291
|
*/
|
|
284
|
-
export async function
|
|
285
|
-
// Token still valid (with 60s buffer)
|
|
292
|
+
export async function getValidChatGptAuth(auth, onRefresh) {
|
|
286
293
|
if (auth.expires > Date.now() + 60_000) {
|
|
287
|
-
return auth
|
|
294
|
+
return auth;
|
|
288
295
|
}
|
|
289
296
|
const refreshed = await refreshChatGptToken(auth);
|
|
290
297
|
if (refreshed instanceof Error)
|
|
291
298
|
return refreshed;
|
|
292
299
|
onRefresh?.(refreshed);
|
|
293
|
-
return refreshed
|
|
300
|
+
return refreshed;
|
|
294
301
|
}
|