2.8 KiB
2.8 KiB
AGENTS.md
Bun + TypeScript single-file server that exposes an OpenAI-compatible image generation endpoint and serves a small vanilla HTML/JS playground.
Runtime
- Bun, not Node. See
CLAUDE.mdfor the full Bun-vs-Node cheatsheet (preferBun.serve,Bun.file,bun:test,Bun.sql, etc.). Do not adddotenv— Bun loads.envautomatically. - Bun version baseline:
1.3.13(perREADME.md).
Commands
- Install:
bun install - Dev (HMR):
bun run dev→bun --hot ./index.ts - Start:
bun run start→bun ./index.ts - Typecheck: no script defined. Use
bunx tsc --noEmit(tsconfig already setsnoEmit: true, so plainbunx tscworks too). - Tests / lint / formatter: none configured. If adding tests, use
bun test.
The server binds 0.0.0.0 (see index.ts:6), so it is reachable from other
hosts on the network when running locally — be mindful when entering API keys.
Architecture
index.ts— the entire backend. OneBun.serveinstance with:/servesindex.htmlvia Bun's HTML import (import index from "./index.html").POST /api/generateaccepts{ baseURL, apiKey, model, prompt, size }, builds an OpenAI-compatible provider with@ai-sdk/openai-compatible, and callsgenerateImagefromai. Images come back as base64 and are returned asdata:URLs in{ images: string[] }.
index.html— self-contained UI: inline CSS, plain DOM JS, no build step. Settings (baseURL, apiKey, model, size, prompt) persist inlocalStorageunder theaip:<field>prefix. There is no React code despitereact/react-dom/@types/react*being inpackage.json— treat those deps as latent. Do not invent a React frontend unless asked.- No router, no DB, no auth. API key is supplied per-request by the browser and never stored server-side.
TypeScript conventions
tsconfig.json is strict with bundler-mode resolution:
strict,noUncheckedIndexedAccess,noImplicitOverride,noFallthroughCasesInSwitchare on — array/object index access isT | undefinedand must be narrowed.verbatimModuleSyntax+moduleDetection: "force"— useimport typefor type-only imports; every file is a module.allowImportingTsExtensionsis on;.tsextensions in imports are fine.jsx: "react-jsx"is set but unused (see frontend note above).
When extending the API
- Add new routes inside the
routesobject inindex.ts; keep the{ POST: async (req) => … }shape used by/api/generate. - Return JSON with
Response.json(...). Validate the request body shape explicitly — the existing handler asserts required fields and returns 400 before calling the model. - The AI SDK image type is loose; the current handler casts to
{ mediaType?: string; base64?: string }. Mirror that pattern rather than trusting field presence.