opencode-antigravity-img 0.1.2 → 0.2.1

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 ADDED
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.2.1] - 2026-01-28
9
+
10
+ ### Fixed
11
+ - Clarify in tool description that output is always JPEG format
12
+ - Fix default filename extension from `.png` to `.jpg`
13
+ - Remove unnecessary PNG check since API always returns JPEG
14
+
15
+ ## [0.2.0] - 2026-01-27
16
+
17
+ ### Added
18
+ - Related plugins section in README linking to sibling plugins
19
+
20
+ ### Changed
21
+ - Updated auth plugin link to correct repository (NoeFabris)
22
+
23
+ ## [0.1.0] - 2026-01-26
24
+
25
+ ### Added
26
+ - Initial release
27
+ - `generate_image` tool for generating images with Gemini 3 Pro Image model
28
+ - `image_quota` tool for checking remaining quota
29
+ - Support for aspect ratios: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9
30
+ - Support for image sizes: 1K, 2K, 4K
31
+ - Automatic fallback between CloudCode API endpoints
package/README.md CHANGED
@@ -43,10 +43,12 @@ Generate an image from a text prompt.
43
43
  - `prompt` (required): Text description of the image to generate
44
44
  - `filename` (optional): Output filename (default: `generated_<timestamp>.jpg`)
45
45
  - `output_dir` (optional): Output directory (default: current working directory)
46
+ - `aspect_ratio` (optional): Image aspect ratio. Supported values: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9` (default: `1:1`)
47
+ - `image_size` (optional): Image resolution. Supported values: `1K`, `2K`, `4K` (default: `1K`)
46
48
 
47
49
  **Example:**
48
50
  ```
49
- Generate an image of a sunset over mountains with a lake in the foreground
51
+ Generate a 16:9 landscape image of a sunset over mountains with a lake in the foreground
50
52
  ```
51
53
 
52
54
  **Output:**
@@ -66,10 +68,24 @@ Check the remaining quota for the Gemini 3 Pro Image model.
66
68
  ## Image Details
67
69
 
68
70
  - **Model**: Gemini 3 Pro Image
69
- - **Resolution**: 1408x768 pixels
70
- - **Format**: JPEG (typically 600KB - 1MB)
71
+ - **Resolutions**:
72
+ - `1K`: 1024x1024 (default)
73
+ - `2K`: 2048x2048
74
+ - `4K`: 4096x4096
75
+ - **Aspect ratios**: `1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9`
76
+ - **Format**: JPEG (always, regardless of filename extension)
71
77
  - **Generation time**: 10-30 seconds
72
78
 
79
+ ## Unsupported Parameters
80
+
81
+ The following parameters are documented in Google's API but are **not supported** by the Gemini 3 Pro Image model (they are Imagen-specific):
82
+
83
+ - `personGeneration` - Control generation of people in images
84
+ - `outputMimeType` - Output format selection (always returns JPEG)
85
+ - `compressionQuality` - JPEG compression control
86
+
87
+ These parameters may work with Imagen models but have no effect with Gemini 3 Pro Image.
88
+
73
89
  ## Quota
74
90
 
75
91
  Image generation uses a separate quota from text models. The quota resets every 5 hours. Use the `image_quota` tool to check your remaining quota.
@@ -102,8 +118,8 @@ The plugin uses Google's CloudCode API with fallback endpoints:
102
118
 
103
119
  ## Related Plugins
104
120
 
105
- - [opencode-antigravity-auth](https://www.npmjs.com/package/opencode-antigravity-auth) - Authentication (required)
106
- - [opencode-antigravity-quota](https://www.npmjs.com/package/opencode-antigravity-quota) - Text model quota checking
121
+ - [opencode-antigravity-auth](https://github.com/NoeFabris/opencode-antigravity-auth) - Authentication (required)
122
+ - [opencode-antigravity-web](https://github.com/ominiverdi/opencode-antigravity-web) - Web search and URL reading
107
123
 
108
124
  ## License
109
125
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-antigravity-img",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "description": "OpenCode plugin for Gemini image generation via Antigravity/CloudCode API",
5
5
  "main": "src/index.ts",
6
6
  "type": "module",
package/src/api.ts CHANGED
@@ -15,6 +15,7 @@ import type {
15
15
  CloudCodeQuotaResponse,
16
16
  GenerateContentResponse,
17
17
  ImageGenerationResult,
18
+ ImageGenerationOptions,
18
19
  QuotaInfo,
19
20
  } from "./types";
20
21
 
@@ -149,12 +150,34 @@ export async function getImageModelQuota(account: Account): Promise<QuotaInfo |
149
150
  }
150
151
  }
151
152
 
153
+ /**
154
+ * Build imageConfig from options
155
+ */
156
+ function buildImageConfig(options?: ImageGenerationOptions): ImageGenerationOptions | undefined {
157
+ if (!options) return undefined;
158
+
159
+ const { aspectRatio, imageSize } = options;
160
+
161
+ // Only include if at least one option is set
162
+ if (!aspectRatio && !imageSize) {
163
+ return undefined;
164
+ }
165
+
166
+ const imageConfig: ImageGenerationOptions = {};
167
+
168
+ if (aspectRatio) imageConfig.aspectRatio = aspectRatio;
169
+ if (imageSize) imageConfig.imageSize = imageSize;
170
+
171
+ return imageConfig;
172
+ }
173
+
152
174
  /**
153
175
  * Generate an image using the Gemini 3 Pro Image model
154
176
  */
155
177
  export async function generateImage(
156
178
  account: Account,
157
- prompt: string
179
+ prompt: string,
180
+ options?: ImageGenerationOptions
158
181
  ): Promise<ImageGenerationResult> {
159
182
  try {
160
183
  // Get access token
@@ -172,6 +195,7 @@ export async function generateImage(
172
195
  }
173
196
 
174
197
  // Build request
198
+ const imageConfig = buildImageConfig(options);
175
199
  const requestBody = {
176
200
  project: projectId,
177
201
  requestId: `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
@@ -183,6 +207,7 @@ export async function generateImage(
183
207
  session_id: `sess_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
184
208
  generationConfig: {
185
209
  responseModalities: ["TEXT", "IMAGE"],
210
+ ...(imageConfig && { imageConfig }),
186
211
  },
187
212
  },
188
213
  };
package/src/index.ts CHANGED
@@ -3,7 +3,7 @@ import * as fs from "fs/promises";
3
3
  import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
4
4
  import { join, dirname } from "path";
5
5
  import { CONFIG_PATHS, COMMAND_DIR, COMMAND_FILE, COMMAND_CONTENT, IMAGE_MODEL } from "./constants";
6
- import type { AccountsConfig, Account } from "./types";
6
+ import type { AccountsConfig, Account, ImageGenerationOptions, AspectRatio, ImageSize } from "./types";
7
7
  import { generateImage, getImageModelQuota } from "./api";
8
8
 
9
9
  // Create command file for opencode discovery
@@ -72,20 +72,29 @@ export const plugin: Plugin = async (ctx) => {
72
72
  description:
73
73
  "Generate an image using Gemini 3 Pro Image model. " +
74
74
  "Provide a text prompt describing the image you want. " +
75
+ "IMPORTANT: Output is always JPEG format regardless of filename extension. " +
75
76
  "Returns the path to the generated image file.",
76
77
  args: {
77
78
  prompt: tool.schema.string().describe("Text description of the image to generate"),
78
79
  filename: tool.schema
79
80
  .string()
80
81
  .optional()
81
- .describe("Output filename (default: generated_<timestamp>.png)"),
82
+ .describe("Output filename (default: generated_<timestamp>.jpg). Note: format is always JPEG regardless of extension"),
82
83
  output_dir: tool.schema
83
84
  .string()
84
85
  .optional()
85
86
  .describe("Output directory (default: current working directory)"),
87
+ aspect_ratio: tool.schema
88
+ .string()
89
+ .optional()
90
+ .describe("Aspect ratio: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9 (default: 1:1)"),
91
+ image_size: tool.schema
92
+ .string()
93
+ .optional()
94
+ .describe("Image resolution: 1K, 2K, 4K (default: 1K)"),
86
95
  },
87
96
  async execute(args, context) {
88
- const { prompt, filename, output_dir } = args;
97
+ const { prompt, filename, output_dir, aspect_ratio, image_size } = args;
89
98
 
90
99
  if (!prompt?.trim()) {
91
100
  return "Error: Please provide a prompt describing the image to generate.";
@@ -105,17 +114,21 @@ export const plugin: Plugin = async (ctx) => {
105
114
 
106
115
  context.metadata({ title: "Generating image..." });
107
116
 
117
+ // Build generation options
118
+ const options: ImageGenerationOptions = {};
119
+ if (aspect_ratio) options.aspectRatio = aspect_ratio as AspectRatio;
120
+ if (image_size) options.imageSize = image_size as ImageSize;
121
+
108
122
  // Generate image
109
- const result = await generateImage(account, prompt);
123
+ const result = await generateImage(account, prompt, Object.keys(options).length > 0 ? options : undefined);
110
124
 
111
125
  if (!result.success || !result.imageData) {
112
126
  return `Error generating image: ${result.error || "Unknown error"}`;
113
127
  }
114
128
 
115
- // Determine output path
129
+ // Determine output path (always JPEG regardless of extension)
116
130
  const dir = output_dir || ctx.directory;
117
- const ext = result.mimeType === "image/png" ? "png" : "jpg";
118
- const name = filename || `generated_${Date.now()}.${ext}`;
131
+ const name = filename || `generated_${Date.now()}.jpg`;
119
132
  const outputPath = join(dir, name);
120
133
 
121
134
  // Ensure directory exists
package/src/types.ts CHANGED
@@ -37,7 +37,20 @@ export interface ModelInfo {
37
37
  };
38
38
  }
39
39
 
40
- // Image generation
40
+ // Image generation options
41
+ export type AspectRatio = "1:1" | "2:3" | "3:2" | "3:4" | "4:3" | "4:5" | "5:4" | "9:16" | "16:9" | "21:9";
42
+ export type ImageSize = "1K" | "2K" | "4K";
43
+
44
+ export interface ImageConfig {
45
+ aspectRatio?: AspectRatio;
46
+ imageSize?: ImageSize;
47
+ }
48
+
49
+ export interface ImageGenerationOptions {
50
+ aspectRatio?: AspectRatio;
51
+ imageSize?: ImageSize;
52
+ }
53
+
41
54
  export interface GenerateContentRequest {
42
55
  project: string;
43
56
  requestId: string;
@@ -52,6 +65,7 @@ export interface GenerateContentRequest {
52
65
  session_id: string;
53
66
  generationConfig: {
54
67
  responseModalities: string[];
68
+ imageConfig?: ImageConfig;
55
69
  };
56
70
  };
57
71
  }