--- name: ideogram-local-dev-loop description: 'Configure Ideogram local development with mock responses and testing. Use when setting up a development environment, configuring test workflows, or establishing a fast iteration cycle with Ideogram. Trigger with phrases like "ideogram dev setup", "ideogram local development", "ideogram dev environment", "develop with ideogram", "ideogram testing". ' allowed-tools: Read, Write, Edit, Bash(npm:*), Bash(pnpm:*), Bash(npx:*), Grep version: 1.10.0 license: MIT author: Jeremy Longshore tags: - saas - ideogram - testing - workflow - development compatibility: Designed for Claude Code, also compatible with Codex and OpenClaw --- # Ideogram Local Dev Loop ## Overview Set up a fast local development workflow for Ideogram integrations. Includes a typed client wrapper, mock server for offline development (avoids burning credits), and vitest integration for automated testing. ## Prerequisites - Completed `ideogram-install-auth` setup - Node.js 18+ with npm/pnpm - `IDEOGRAM_API_KEY` environment variable set ## Instructions ### Step 1: Create Project Structure ``` my-ideogram-project/ ├── src/ │ ├── ideogram/ │ │ ├── client.ts # Typed Ideogram client wrapper │ │ ├── types.ts # Request/response type definitions │ │ └── mock-server.ts # Local mock for offline dev │ └── index.ts ├── tests/ │ └── ideogram.test.ts ├── .env.local # Local secrets (git-ignored) ├── .env.example # Template for team ├── tsconfig.json └── package.json ``` ### Step 2: Install Dependencies ```bash set -euo pipefail npm install dotenv npm install -D typescript tsx vitest @types/node ``` ### Step 3: Type Definitions ```typescript // src/ideogram/types.ts export type StyleType = "AUTO" | "GENERAL" | "REALISTIC" | "DESIGN" | "RENDER_3D" | "ANIME"; export type AspectRatio = "ASPECT_1_1" | "ASPECT_16_9" | "ASPECT_9_16" | "ASPECT_3_2" | "ASPECT_2_3" | "ASPECT_4_3" | "ASPECT_3_4" | "ASPECT_10_16" | "ASPECT_16_10" | "ASPECT_1_3" | "ASPECT_3_1"; export type Model = "V_1" | "V_1_TURBO" | "V_2" | "V_2_TURBO" | "V_2A" | "V_2A_TURBO"; export type MagicPrompt = "AUTO" | "ON" | "OFF"; export interface GenerateRequest { prompt: string; model?: Model; style_type?: StyleType; aspect_ratio?: AspectRatio; magic_prompt_option?: MagicPrompt; negative_prompt?: string; num_images?: number; seed?: number; } export interface ImageResult { url: string; prompt: string; resolution: string; is_image_safe: boolean; seed: number; style_type: StyleType; } export interface GenerateResponse { created: string; data: ImageResult[]; } ``` ### Step 4: Client Wrapper ```typescript // src/ideogram/client.ts import type { GenerateRequest, GenerateResponse } from "./types"; const IDEOGRAM_API = "https://api.ideogram.ai"; export class IdeogramClient { constructor(private apiKey: string) { if (!apiKey) throw new Error("IDEOGRAM_API_KEY is required"); } async generate(request: GenerateRequest): Promise { const response = await fetch(`${IDEOGRAM_API}/generate`, { method: "POST", headers: { "Api-Key": this.apiKey, "Content-Type": "application/json", }, body: JSON.stringify({ image_request: request }), }); if (!response.ok) { const body = await response.text(); throw new IdeogramError(response.status, body); } return response.json(); } } export class IdeogramError extends Error { constructor(public status: number, public body: string) { super(`Ideogram API error ${status}: ${body}`); this.name = "IdeogramError"; } } ``` ### Step 5: Mock Server for Offline Development ```typescript // src/ideogram/mock-server.ts import type { GenerateResponse } from "./types"; // Use this in development to avoid burning real credits export function mockGenerate(prompt: string): GenerateResponse { return { created: new Date().toISOString(), data: [{ url: `https://placehold.co/1024x1024/333/fff?text=${encodeURIComponent(prompt.slice(0, 30))}`, prompt, resolution: "1024x1024", is_image_safe: true, seed: Math.floor(Math.random() * 100000), style_type: "GENERAL", }], }; } ``` ### Step 6: Vitest Tests ```typescript // tests/ideogram.test.ts import { describe, it, expect, vi } from "vitest"; import { IdeogramClient, IdeogramError } from "../src/ideogram/client"; import { mockGenerate } from "../src/ideogram/mock-server"; describe("IdeogramClient", () => { it("should reject missing API key", () => { expect(() => new IdeogramClient("")).toThrow("IDEOGRAM_API_KEY is required"); }); it("should construct generate request correctly", async () => { const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValue( new Response(JSON.stringify(mockGenerate("test")), { status: 200 }) ); const client = new IdeogramClient("test-key"); const result = await client.generate({ prompt: "test", model: "V_2" }); expect(fetchSpy).toHaveBeenCalledWith( "https://api.ideogram.ai/generate", expect.objectContaining({ method: "POST", headers: expect.objectContaining({ "Api-Key": "test-key" }), }) ); expect(result.data[0].prompt).toBe("test"); fetchSpy.mockRestore(); }); it("should throw IdeogramError on 401", async () => { vi.spyOn(globalThis, "fetch").mockResolvedValue( new Response("Unauthorized", { status: 401 }) ); const client = new IdeogramClient("bad-key"); await expect(client.generate({ prompt: "test" })).rejects.toThrow(IdeogramError); }); }); describe("mockGenerate", () => { it("should return valid response shape", () => { const result = mockGenerate("hello world"); expect(result.data).toHaveLength(1); expect(result.data[0].is_image_safe).toBe(true); expect(result.data[0].seed).toBeGreaterThan(0); }); }); ``` ### Step 7: Development Scripts ```json { "scripts": { "dev": "tsx watch src/index.ts", "test": "vitest run", "test:watch": "vitest --watch", "generate": "tsx src/index.ts" } } ``` ## Error Handling | Error | Cause | Solution | |-------|-------|----------| | Module not found | Missing dependency | Run `npm install` | | Env not loaded | Missing `.env.local` | Copy from `.env.example` | | Test timeout | Mocking not set up | Use `mockGenerate` in tests | | Credits burned in tests | Using real API in CI | Mock `fetch` in test files | ## Output - Typed client wrapper for Ideogram API - Mock server for offline development - Vitest test suite with fetch mocking - Fast iteration cycle without spending credits ## Resources - [Ideogram API Reference](https://developer.ideogram.ai/api-reference) - [Vitest Documentation](https://vitest.dev/) - [tsx Runner](https://github.com/privatenumber/tsx) ## Next Steps See `ideogram-sdk-patterns` for production-ready code patterns.