Airglow SDKOpen SDK beta docs
Extension-owned runtimeOpen SDK beta
airglow.*Must match runtime

SDK API Reference

The TypeScript-level contract for the open beta SDK and the current runtime behavior behind each method.

Global Declaration

The browser runtime injects globalThis.airglow before app code runs. Invited app developers should include the declaration file from airglow-apps/airglow.d.ts in local app workspaces.

SDK surfacets
interface AirglowFetchResponse<T = any> {
  status: number;
  ok: boolean;
  json(): Promise<T>;
  text(): Promise<string>;
}

interface AirglowWindowOptions {
  width?: number;
  height?: number;
  popup?: boolean;
}

interface AirglowRedirectRule {
  domains: string[];
  target: string;
}

interface AirglowError extends Error {
  name: "AirglowError";
  code?: string;
  status?: number;
  requestId?: string;
  details?: any;
}

interface Airglow {
  sdkVersion: "0.1.0-beta.1";

  fetch<T = any>(
    url: string,
    opts?: RequestInit & { includeCookies?: boolean },
  ): Promise<AirglowFetchResponse<T>>;

  storage: {
    get<T = any>(key: string): Promise<T | undefined>;
    set(key: string, value: any): Promise<void>;
    delete(key: string): Promise<void>;
    list(): Promise<string[]>;
  };

  log: {
    info(message: string, data?: any): Promise<void>;
    warn(message: string, data?: any): Promise<void>;
    error(message: string, data?: any): Promise<void>;
  };

  rpc<T = any>(functionName: string, payload?: any): Promise<T>;

  identity: {
    getRedirectURL(): Promise<string>;
    launchWebAuthFlow(url: string): Promise<string>;
  };

  openWindow(url: string, opts?: AirglowWindowOptions): Promise<void>;
  openWindowAndWaitClose(url: string, opts?: AirglowWindowOptions): Promise<void>;

  platform: {
    registerRedirects(rules: AirglowRedirectRule[]): Promise<void>;
    allowIframes(domains: string[], initiators?: string[]): Promise<void>;
  };
}

declare const airglow: Airglow;

airglow.fetch

ModeCookiesCORSRequirementUse for
Native fetchBrowser defaultEnforcedNoneSame-origin or normal web requests from app code.
airglow.fetch(url)NoBypassed by service worker fetchURL must be reachable by extension/server runtimeThird-party APIs without user session cookies.
airglow.fetch(url, { includeCookies: true })YesRuns in target page contextMatching host_permissionsAuthenticated browser-session requests to a site the user is logged into.
CORS-free API callts
const res = await airglow.fetch("https://api.example.com/items", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({ limit: 10 }),
});

if (!res.ok) {
  await airglow.log.warn("API failed", { status: res.status });
}

const data = await res.json();

Cookie mode is permissioned

includeCookies: true is rejected unless the app manifest has a matching host_permissions entry. The extension may create a background tab on the target origin if no matching tab is already open.

airglow.storage

Storage is app-scoped in chrome.storage.local with the airglow:app:{appId}: prefix. UI, userscripts, and startup share the same app namespace.

App-scoped statets
await airglow.storage.set("draft", { title: "Release notes" });
const draft = await airglow.storage.get<{ title: string }>("draft");
await airglow.storage.delete("draft");
const keys = await airglow.storage.list();

Client settings use storage.get

For keys declared in manifest secrets, airglow.storage.get(key) reads the user secret first and the dev secret fallback second. This is the current beta behavior and should be renamed or documented carefully before wider release.

airglow.log

Use SDK logs for app-observable events and recoverable failures. The SDK also captures uncaught errors and unhandled promise rejections and forwards them as error logs.

Structured app logsts
await airglow.log.info("import_started", { count: rows.length });
await airglow.log.warn("rate_limit_retry", { attempt, waitMs });
await airglow.log.error("import_failed", { reason: error.message });

airglow.rpc

airglow.rpc(name, payload) calls POST /api/apps/:appId/rpc/:name on the app server. Server functions should be used for server secrets, shared provider keys, OAuth exchange, and rate-limited model calls.

Client and serverts
// airglow-apps/hn-tagger/server/tag.ts
export default async function tag(payload: { titles: string[] }) {
  const apiKey = process.env.ANTHROPIC_API_KEY;
  if (!apiKey) {
    throw new Error("ANTHROPIC_API_KEY is not configured");
  }

  return {
    titles: payload.titles,
    generatedAt: new Date().toISOString(),
  };
}

// userscripts/hn.ts or ui/App.tsx
const result = await airglow.rpc("tag", { titles });

RPC error behavior

Transport failures and HTTP 4xx/5xx responses reject with AirglowError. The error can include code, status, requestId, and details. Server functions that intentionally return { error } with HTTP 200 are still returned as normal values.

Identity, Windows, Platform

APIPurposeNotes
airglow.identity.getRedirectURL()Return Chrome extension OAuth redirect URL.Use when building OAuth authorization URLs.
airglow.identity.launchWebAuthFlow(url)Open auth popup and resolve with final redirect URL.Rejects if the user closes the popup.
airglow.openWindow(url, opts)Open a centered Chrome popup or normal window.Use instead of window.open from userscripts.
airglow.openWindowAndWaitClose(url, opts)Open a window and wait until it closes.Useful for OAuth or external review flows.
airglow.platform.registerRedirects(rules)Register app-owned redirect rules.Call from idempotent startup code.
airglow.platform.allowIframes(domains, initiators?)Allow selected iframe domains by relaxing response headers.Privileged beta capability. Keep the domain list narrow.