---
type: hack
title: Hermes Plugin — Standalone Kickbacks Architecture
description: Hermes Agent Plugin with Kickbacks.ai without extension patches
tags: [kickbacks, hermes, architecture, standalone, marquee]
timestamp: 2026-06-26
---

# Hermes Plugin — Arquitetura Kickbacks Standalone

Hermes Agent plugin that implements Kickbacks.ai **without** depending on VS Code extension or IDE file patches.

## Architecture vs VS Code Extension

| Aspect | VS Code Extension (official) | Hermes Plugin (our version) |
|---|---|---|
| **Coupling** | Patches Claude Code's `webview/index.js` + `extension.js` | **Zero patches** — hook on Hermes lifecycle |
| **Surfaces** | Spinner overlay + banner (DOM) | Statusline (OSC 8) + banner + spinner |
| **Ad length** | `text-overflow: ellipsis` (truncated) | **Marquee animation** (scroll) |
| **TOS** | Modifies third-party files ✅❌ | Official API only, nothing modified ✅ |
| **Dependency** | VS Code / fork installed | Hermes Agent only (CLI) |
| **Persistent banner** | Only on idle | **Fixed**, even during thinking |
| **Billing decay** | Constant (5s tick always) | **Logarithmic**: 5s → 10s → 30s → 60s → stop (5min) |
| **Authentication** | Google OAuth in VS Code | Google OAuth via browser + polling |
| **Backend** | `kickbacks-backend-*.run.app` | **Same official backend** |
| **Demo mode** | `/v1/portfolio/demo` without token | **Same endpoint** |
| **Metrics** | `/v1/metrics` or `/v1/metrics/demo` | **Same endpoint** |

## How It Works

### 1. API Client (`api.py`)

Complete Kickbacks.ai API client:
- `fetch_portfolio()` — fetch ads (authenticated or demo)
- `send_metric()` — impression_rendered, view_tick, click, etc.
- `start_sign_in()` / `poll_sign_in()` — Google OAuth
- `fetch_earnings()` — balance
- `write_ad_cache()` — saves current ad to `~/.kickbacks/hermes-ad.json`

Endpoint base: `https://kickbacks-backend-gmdaqm2c7q-uw.a.run.app`

### 2. Impression Tracker (`tracker.py`)

Billing engine with two simultaneous surfaces:

**Statusline (thinking):**
- `start()` → triggers when Hermes makes an LLM call or tool execution
- `stop()` → 350ms grace timer (covers LLM↔tool handoffs)
- `AD_REST_MS` (20s default) between billing sessions
- Ticks every 5s during visible time

**Banner (idle + thinking):**
- Starts IMMEDIATELY when thinking ends (without waiting for grace)
- **Co-exists with thinking** — banner stays fixed at all times
- Logarithmic billing decay:
  - 0-30s idle: tick every 5s
  - 30s-1min: tick every 10s
  - 1min-2min: tick every 30s
  - 2min-5min: tick every 60s
  - >5min: stop (ad persists visually, no billing)

**Independent sessions:** each surface has its own `session_nonce`, `started_at`, `threshold_met` — they don't compete with each other.

### 3. Marquee Animation (vs Ellipsis)

The official version uses CSS `text-overflow: ellipsis` on the overlay (line `101` of `block.asset.js`):
```css
overflow:hidden;text-overflow:ellipsis
```

Our version has **marquee animation** for long ad text — instead of ugly truncation, the text slides horizontally. The exact code is in the Hermes scripts.

### 4. Status Line Display (`hermes-kickbacks-status`)

Python script that reads the cache `~/.kickbacks/hermes-ad.json` and displays the ad as an **OSC 8 hyperlink** in the terminal:
```
ESC ]8;;<url> ESC \ ad· Texto do Anúncio ESC ]8;; ESC \
```

Integrable with:
- **tmux** (`status-right`)
- **iTerm2** (Status Bar component)
- **fish** (prompt function)
- **WezTerm** (status bar)

### 5. No IDE Patches

Unlike [[kickbacks-antigravity|the VS Code patch]], the Hermes plugin:

1. **Does not modify** any extension file
2. **Does not need** CSP relaxation (`connect-src`)
3. **Does not use** DOM overlay / MutationObserver
4. **Does not depend on** `webview/index.js` or `extension.js`
5. **Works in any terminal** — VS Code, Antigravity, Cursor, plain terminal
6. **Respects TOS** — consumes the official API like any legitimate client

Hermes Agent has native hooks (`pre_llm_call`, `post_llm_call`, `pre_tool_call`, `post_tool_call`) that the plugin uses to know when the agent is "thinking" — without needing to reverse-engineer the DOM.

## Installation

```bash
# Plugin already installed in ~/.hermes/plugins/kickbacks/
python3 ~/.hermes/plugins/kickbacks/scripts/setup.py
```

## Ad Cache

The current ad is stored in `~/.kickbacks/hermes-ad.json` — any script can read it:
```json
{
  "ad_text": "Patrocinado por...",
  "click_url": "https://...",
  "ts": 1712345678000,
  "ad_id": "...",
  "demo": true
}
```

## Debug

```bash
KICKBACKS_DEBUG=1 hermes chat ...
# Logs em: ~/.kickbacks/logs/
```

## Links

- [[kickbacks-antigravity]] — Official VS Code patch (different approach)
- [[antigravity-ide]] — Google Antigravity IDE
