Skip to content
Development
Skill

/glaze-byok-ai

Give Glaze app users a choice of AI engine - built-in Glaze AI (zero setup, uses their Glaze credits), their own free API key (Google Gemini free tier, optionally OpenRouter free models), or their local Claude Code CLI (their Claude subscription). Use whenever an app built with

From plugin
glaze-coder
102 skills1 command

Claude Code

$ npx -y skills add GaimsDevSoftware/glaze-coder --skill glaze-byok-ai --agent claude-code

SKILL.md

glaze-byok-ai.SKILL.md
name: glaze-byok-ai
description: Give Glaze app users a choice of AI engine - built-in Glaze AI (zero setup, uses their Glaze credits), their own free API key (Google Gemini free tier, optionally OpenRouter free models), or their local Claude Code CLI (their Claude subscription). Use whenever an app built with glaze-coder gets an AI feature, so end users can decide whether using the app costs them anything. Covers the provider service, encrypted key storage, the Claude CLI engine, IPC handlers, settings UI, and blocked-state fallback.

User-selectable AI engine for Glaze apps (Glaze AI or BYOK)

Before scaffolding, read the developer's saved policy if present: `~/.config/glaze-coder/defaults.json` with `{"aiDefault": "glaze" | "byok-fallback" | "byok-first"}` (written by the Free Coder for Glaze onboarding app). `byok-fallback` = Glaze default + auto-fallback on (this skill's default); `byok-first` = scaffold with a free engine as the app's default provider and Glaze never running unasked; `glaze` = built-in AI only, skip the engine picker. A missing file means `byok-fallback`.

Default policy for apps built with glaze-coder: when an app calls AI, the end user gets to pick the engine. Glaze AI works with zero setup but spends the user's Glaze credits; a bring-your-own-key engine is free for them (Gemini has a real free tier); the local Claude Code CLI is free for users who already pay for a Claude subscription. Implement this choice unless the user building the app explicitly wants Glaze-only.

Reference implementation: the News Flow app (`ai-provider.ts` + `claude-cli.ts` + "AI-motor" settings section + onboarding engine step). This file contains everything needed to reproduce it in any app.

The four engines

| Engine | Cost for the user | Setup | Notes | | --- | --- | --- | --- | | `glaze` (default) | Glaze credits | none | Always the default and the fallback | | `gemini` | free | paste a free AI Studio key | ~250 calls/day free tier; recommended free option | | `openrouter` | free | paste an OpenRouter key | ~50 calls/day unfunded; `openrouter/free` auto-routes; optional third choice | | `claude` | free with a Claude subscription | Claude Code installed + logged in | For users known to have Claude Code; settings-only, slower (seconds to a minute per call) |

Rules that keep this correct and honest:

  • Glaze stays the default. A missing or invalid BYOK key must silently fall back to

Glaze AI, never break the feature.

  • Keep `glaze.capabilities.ai` declared in `package.json` (grades matching the code),

since Glaze remains default + fallback. Publish rejects AI apps without it.

  • Keys are encrypted with `safeStorage`, stored in userData, and never sent to the

renderer. Only boolean `hasKey` flags cross IPC.

  • Key links: Gemini keys at `https://aistudio.google.com/apikey`, OpenRouter keys at

`https://openrouter.ai/settings/keys`. Open via `shell.openExternal`. Automatic key provisioning is not possible; a deep link plus paste field is the simplest flow.

  • The "Test" button makes one tiny `generateText` call against the user's own key,

only when clicked. Never run it (or any AI call) yourself during verification; verify with type-check and build only.

  • Do not put pricing copy next to AI controls beyond the engine descriptions; Glaze's

own consent UI explains credits.

  • The Claude engine spawns the user's own `claude` CLI (subscription login). Never

collect Anthropic API keys, OAuth tokens, or Claude credential files for it, and never persist `CLAUDE_CODE_OAUTH_TOKEN`. Offer it to audiences known to have Claude Code; keep it in full settings, not onboarding. Detection gates the UI state (a found/not-found badge), and a missing CLI falls back to Glaze like a missing key.

Dependencies

From the app's `.glaze-sources/` (bundled Node on PATH, managed npmrc):

npm install --include=dev @ai-sdk/google @ai-sdk/openai-compatible

Both are pure JS and bundle cleanly. The SDK's bundled `ai` package accepts third-party provider models (it upgrades provider spec v2/v3 internally), so these plug straight into the `generateObject`/`generateText` re-exported by `@glaze/core/ai`.

Backend: `main/services/ai-provider.ts`

Adapt storage to the app: if it already has a JSON store helper, reuse it; otherwise keep the inline `readJson`/`writeJson` below. Everything else drops in as is.

// AI engine selection: "glaze" (built-in, credits) | "gemini" | "openrouter" (BYOK).
// Keys are safeStorage-encrypted and never leave the backend.
import { generateText, glaze, type LanguageModel } from "@glaze/core/ai";
import { app, logger, safeStorage } from "@glaze/core/backend";
import { createGoogleGenerativeAI } from "@ai-sdk/google";
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import fs from "fs/promises";
import path from "path";

export type AIProviderId = "glaze" | "gemini" | "openrouter";
export interface AISettings { provider: AIProviderId; openrouterModel: string; }
export interface AISettingsView extends AISettings { hasGeminiKey: boolean; hasOpenrouterKey: boolean; }

export const GEMINI_MODEL = "gemini-2.5-flash";
export const DEFAULT_OPENROUTER_MODEL = "openrouter/free";
const DEFAULTS: AISettings = { provider: "glaze", openrouterModel: DEFAULT_OPENROUTER_MODEL };

async function fileIn(name: string): Promise<string> {
  const dir = app.getPath("userData");
  await fs.mkdir(dir, { recursive: true });
  return path.join(dir, name);
}
async function readJson<T>(name: string, fallback: T): Promise<T> {
  try { return JSON.parse(await fs.readFile(await fileIn(name), "utf-8")) as T; }
  catch { return fallback; }
}
async function writeJson(name: string, value: unknown): Promise<void> {
  await fs.writeFile(await fileIn(name), JSON.stringify(value, null, 2), "utf-8");
}

const SETTINGS_FILE = "ai-settings.json";
const KEYS_FILE = "ai-keys.json"; // base64 of safeStorage-encrypted buffers

export async function getAISetti
Read more
@gaimsdevsoftware
Ships withglaze-coder

Build Glaze (by Raycast) desktop apps from Claude Code, using your own Claude subscription instead of Glaze's paid credits. Glaze builds Mac apps with a built-in AI agent, and that agent is what spends Glaze credits.

Stars on GitHub

Momentum

stars in total
10
Star history of GaimsDevSoftware/glaze-coder on GitHub, a chart by star-history.com

Other skills on glaze-coder.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about glaze-byok-ai.

Which coding agents can use glaze-byok-ai?
glaze-byok-ai installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.