<div align="center">

<img src="https://opencrater.to/brand/green/logo-green.png" width="96" alt="OpenCrater logo" />

# opencrater

**Blips for the terminal.** Tasteful, opt-in sponsor cards for CLI tools, MCP servers, and AI agents — the rendering engine that powers [OpenCrater](https://opencrater.to).

[![npm](https://img.shields.io/npm/v/opencrater?color=2ea043&label=npm)](https://www.npmjs.com/package/opencrater)
[![node](https://img.shields.io/badge/node-%E2%89%A518.17-2ea043)](https://nodejs.org)
![deps](https://img.shields.io/badge/dependencies-0-2ea043)
![license](https://img.shields.io/badge/license-proprietary-555)

</div>

---

A sponsor card renders at a natural pause in the session (a session edge), then auto-dismisses:

```text
╭─ terminal ──────────────────────────────────────────────
│
│  Sponsored · Vercel                      auto-dismiss 25s  ✕
│
│  DEPLOY IN ONE COMMAND
│  Ship your app to 30+ edge regions in a single push.
│  Free tier — no credit card.
│
│  ▌ visit sponsor →
│
│  dismiss: click ✕  ·  npx opencrater x  ·  ⚑ report
│
╰──────────────────────────────────────────────────────────
```

> ▶ **See it live and interactive** (audio, media, real host chrome): <https://opencrater.to>

---

## What is this?

OpenCrater lets the maintainers of command-line tools, MCP servers, and AI agents **earn revenue** by showing one small, clearly-labeled sponsor card at a natural break in a session — the terminal equivalent of an ad slot on a website. It's **opt-in**, **frequency-capped**, **privacy-preserving**, and **fail-silent**: it will never break, slow, or clutter the host tool.

This package, `opencrater`, is the **engine** — the same one used whether you enable cards with one command or integrate programmatically.

| If you are… | Go to |
|---|---|
| 👤 **A maintainer who just wants to earn** (no code) | [One command](#-one-command-no-code) |
| 🛠️ **A developer integrating programmatically** | [Programmatic use](#%EF%B8%8F-programmatic-use) |
| 🤖 **An AI agent / LLM setting this up** | [For AI agents](#-for-ai-agents) |

---

## 👤 One command (no code)

Turn sponsor cards on for your own terminal — or wire them into a tool you publish — with the bundled CLI. No account required to *see* cards; a free publisher key (from <https://opencrater.to>) is what lets you *earn*.

```bash
npx opencrater on        # enable sponsor cards (Claude Code, Codex, Gemini CLI)
npx opencrater status    # show what's installed
npx opencrater off       # disable — removes only OpenCrater's own hooks
```

To earn as a publisher, register your package once at <https://opencrater.to>, then:

```bash
npx opencrater on --key ock_your_publisher_key --package your-tool-name
```

Every click on a sponsor card credits your account — you're on your way to monetizing your terminal tool.

---

## 🛠️ Programmatic use

```bash
npm install opencrater
```

```ts
import { sponsor } from "opencrater";

// Call at a natural pause (e.g. after your CLI finishes a task).
// Fail-silent: never throws, hard-capped network timeout, suppressed
// in CI / non-TTY / opted-out environments.
await sponsor.show({
  publisherKey: "ock_your_publisher_key",
  packageName: "your-tool-name",
  placement: "command-finished",
});
```

Full surface:

| Method | Does |
|---|---|
| `sponsor.show(opts)` | Fetch → render → report an impression. Resolves `true` if a card was shown. |
| `sponsor.fetch(opts)` | Fetch an ad **without** rendering. Resolves to the `Ad` or `null`. |
| `sponsor.preload(opts)` | Warm a local pool so later renders need zero network. Resolves to the count pooled. |
| `sponsor.renderFromPool(opts)` | Render a pooled ad with no network on the hot path. |

Also exported: `renderCard`, `renderAd`, `textCardForAd`, `detectImageProtocol`, `DEFAULT_CONFIG`, `HOOK_CATALOG`, `SDK_VERSION`, and full TypeScript types. ESM + CJS, types included, **zero runtime dependencies** (Node built-ins only).

---

## 🤖 For AI agents

Concise, unambiguous setup for an autonomous agent integrating OpenCrater on a user's machine. Run these verbatim; everything is fail-silent and reversible.

```text
GOAL: enable opt-in terminal sponsor cards (and, if monetizing, attribute to a publisher).

ENABLE (current user's CLIs — Claude Code, Codex, Gemini CLI):
  npx -y opencrater on

ENABLE WITH ATTRIBUTION (publisher earns on clicks):
  npx -y opencrater on --key <ock_publisher_key> --package <package-name>

STATUS / DISABLE:
  npx -y opencrater status
  npx -y opencrater off            # removes ONLY OpenCrater's hooks; never touches others

PROGRAMMATIC (inside a Node tool you maintain):
  import { sponsor } from "opencrater";
  await sponsor.show({ publisherKey: "<ock_...>", packageName: "<name>", placement: "<event>" });

GUARANTEES (safe to rely on):
  - Never throws; network calls hard-timeout (~500ms); suppressed in CI, non-TTY pipes, and when opted out.
  - At most ONE card per frequency interval, machine-wide, across all sources.
  - Renders only at session edges; auto-dismisses; respects NO_COLOR.

PRIVACY: only anonymized topic keywords are sent — never raw prompts, file paths, or secrets.

OPT OUT: `npx opencrater off`  or  set env `OPENCRATER_DISABLE=1`.

DO NOT: enable without the user's consent; present cards as the tool's own content; remove a user's opt-out.
```

---

## How it works & safety guarantees

- **Trigger, don't print.** Host hooks (Claude Code / Codex / Gemini CLI) fire at session edges; the SDK spawns its own painter that draws the card directly to the terminal, then clears it. The host never has to surface output.
- **Never breaks the host.** Every entry point is fail-silent. Serve requests have a hard timeout. A failure renders *nothing* rather than an error.
- **One card, capped.** A machine-wide frequency cap means at most one card per interval **across every OpenCrater source** — installing this next to a publisher's OpenCrater-enabled package never doubles ads.
- **Suppressed where inappropriate.** CI, non-interactive pipes, `NO_COLOR`, and opted-out machines get nothing.
- **Cross-platform.** macOS, Linux, and Windows (Windows Terminal) all render with full feature parity — card, audio, live countdown, clickable controls, clean teardown.

## Privacy

Personalization uses **anonymized topic keywords only** — never raw prompts, file contents, paths, environment variables, or secrets. The user can opt out at any time and the SDK records no PII.

## Opt out

```bash
npx opencrater off            # or:
OPENCRATER_DISABLE=1          # env var, disables all rendering
```

## Configuration (env)

| Variable | Effect |
|---|---|
| `OPENCRATER_DISABLE=1` | Disable all rendering. |
| `NO_COLOR` | Render without color (respected automatically). |
| `OPENCRATER_MUTE=1` | Never play ad audio. |

## Platform support

Node ≥ 18.17 on macOS, Linux, and Windows (Windows Terminal). Any tool — written in any language — can integrate via the [`opencrater`](https://www.npmjs.com/package/opencrater) installer (`npx opencrater on`).

---

<div align="center">

[**opencrater.to**](https://opencrater.to) · [Dashboard](https://opencrater.to/dashboard) · [Docs](https://opencrater.to/docs) · [FAQ](https://opencrater.to/faq)

Proprietary — © OpenCrater. Published for installation only; see [LICENSE](./LICENSE). Not open source.

</div>
