# shitty-extensions

Custom extensions and skills for [pi coding agent](https://github.com/badlogic/pi-mono).

**Requires pi 0.50.0+** | [npm](https://www.npmjs.com/package/shitty-extensions) | [GitHub](https://github.com/hjanuschka/shitty-extensions)

## Table of Contents

- [Installation](#installation)
- [Available Extensions](#available-extensions)
  - [branch-sessions.ts](#branch-sessionsts) - Git branch-based session directories
  - [clipboard.ts](#clipboardts) - Copy text to system clipboard
  - [oracle.ts](#oraclets) - Get second opinions from other AI models
  - [memory-mode.ts](#memory-modets) - Save instructions to AGENTS.md
  - [plan-mode.ts](#plan-modets) - Read-only exploration mode
  - [handoff.ts](#handoffts) - Transfer context to new sessions
  - [usage-bar.ts](#usage-barts) - AI provider usage statistics
  - [ultrathink.ts](#ultrathinkts) - Rainbow animated "ultrathink" effect
  - [status-widget.ts](#status-widgetts) - Provider status in footer
  - [cost-tracker.ts](#cost-trackerts) - Session spending analysis
  - [funny-working-message.ts](#funny-working-messagets) - Randomized spinner "Working..." text
  - [speedreading.ts](#speedreadingts) - RSVP speed reader (Spritz-style)
  - [loop.ts](#loopts) - Conditional loops by mitsuhiko
  - [flicker-corp.ts](#flicker-corpts) - Authentic fullscreen flicker experience
  - [resistance.ts](#resistancets) - Mysterious resistance transmission
- [Available Skills](#available-skills)
  - [a-nach-b](#a-nach-b) - Austrian public transport (VOR AnachB)
- [License](#license)

---

## Installation

### Via pi install (recommended)

Install from npm:

```bash
pi install npm:shitty-extensions
```

Or install from git:

```bash
pi install git:github.com/hjanuschka/shitty-extensions
```

That's it! Pi automatically discovers all extensions and skills from the package.

### Install only clipboard extension

If you only want the clipboard tool as a standalone package:

```bash
pi install npm:shitty-clipboard-extension
```

### Try without installing

Load for a single session without permanent installation:

```bash
pi -e npm:shitty-extensions
```

### Project-local installation

Install to `.pi/` for team sharing (auto-installs for teammates on startup):

```bash
pi install -l npm:shitty-extensions
```

### Manual installation

Clone the repo and reference directly:

```bash
git clone https://github.com/hjanuschka/shitty-extensions.git ~/shitty-extensions
pi -e ~/shitty-extensions
```

---

## Available Extensions

Extensions are located in the `extensions/` directory.

### branch-sessions.ts

🌿 Organize pi sessions by git branch for seamless context switching.

#### What it does

Automatically stores sessions in branch-specific directories so each git branch gets its own conversation history. No more wrong context when you `--continue` after switching branches.

#### Session Structure

```
~/.pi/agent/sessions/
└── --Users-hjanuschka-myproject--/
    ├── --main--/
    │   └── 2026-02-16T...jsonl
    ├── --feature-auth--/
    │   └── 2026-02-16T...jsonl
    └── --bugfix-login--/
        └── 2026-02-16T...jsonl
```

#### Features

- **Automatic branch detection**: Uses `git rev-parse --abbrev-ref HEAD`
- **Safe path encoding**: Branch names sanitized for filesystem (slashes → dashes)
- **CLI override**: `--session-dir` flag takes precedence
- **Graceful fallback**: Works normally in non-git directories

#### Important

⚠️ **Don't switch git branches mid-session!** This will confuse the session context. Always start a new pi session after switching branches:

```bash
git checkout feature-branch
pi  # Start fresh session for this branch
```

#### Why this is an extension

Branch-based sessions introduce foot-gun potential (switching branches mid-session breaks context). Better to let users opt-in via extension than bake this complexity into pi core.

#### Requirements

- **pi 0.52.13+** (requires `session_directory` extension event)
- Git repository

---

### clipboard.ts

📋 Copy text to the system clipboard via OSC52 escape sequences.

#### Tool

| Tool | Description |
|------|-------------|
| `copy_to_clipboard` | Copy text to clipboard (available to the LLM) |

#### Features

- **OSC52 support**: Works across SSH sessions and most modern terminal emulators
- **LLM-accessible**: The AI can copy generated content directly to your clipboard
- **Wide compatibility**: iTerm2, Kitty, Alacritty, WezTerm, foot, Windows Terminal, tmux

#### Example Usage

Just ask:
- "Write me a draft reply and put it in my clipboard"
- "Generate a UUID and copy it to clipboard"
- "Put that code snippet in my clipboard"

---

### oracle.ts

🔮 Get a second opinion from another AI model without switching contexts.

#### Commands

| Command | Description |
|---------|-------------|
| `/oracle <prompt>` | Ask for a second opinion with model picker |
| `/oracle -m gpt-4o <prompt>` | Direct query to specific model |
| `/oracle -f file.ts <prompt>` | Include file(s) in context |

#### Features

- **Inherits conversation context**: Oracle sees your full conversation with the primary AI
- **Model picker UI**: Choose from available models (only shows authenticated ones)
- **Quick keys**: Press 1-9 to quickly select a model
- **Add to context option**: After response, choose whether to add Oracle's answer to your conversation
- **Excludes current model**: Only shows alternative models for true second opinions

#### Supported Models

| Provider | Models |
|----------|--------|
| **OpenAI** | gpt-4o, gpt-4o-mini, gpt-4.1, gpt-4.1-mini, o1, o1-mini, o3-mini |
| **OpenAI Codex** | gpt-5.2-codex, codex-mini |
| **Google** | gemini-2.0-flash, gemini-2.5-flash, gemini-2.5-pro |
| **Anthropic** | claude-sonnet-4-5, claude-opus-4, claude-haiku-3-5 |

#### Example Flow

```
/oracle Is this the right approach for the API design?

╭────────────────────────────────────────────────────────────╮
│ 🔮 Oracle - Second Opinion                                 │
├────────────────────────────────────────────────────────────┤
│ Prompt: Is this the right approach for the API design?     │
├────────────────────────────────────────────────────────────┤
│ ↑↓/jk navigate • 1-9 quick select • Enter send             │
│                                                            │
│ ❯ 1. GPT-4o (openai)                                       │
│   2. Gemini 2.5 Pro (google)                               │
│   3. Claude Sonnet 4.5 (anthropic)                         │
│                                                            │
├────────────────────────────────────────────────────────────┤
│ Esc cancel                                                 │
╰────────────────────────────────────────────────────────────╯

[After response...]

╭────────────────────────────────────────────────────────────╮
│ 🔮 Oracle Response (GPT-4o)                                │
├────────────────────────────────────────────────────────────┤
│ Q: Is this the right approach for the API design?          │
├────────────────────────────────────────────────────────────┤
│ Based on the conversation, I see you're building a REST    │
│ API with nested resources. A few thoughts:                 │
│                                                            │
│ 1. The approach looks solid for simple cases...            │
│ ...                                                        │
├────────────────────────────────────────────────────────────┤
│ Add to current conversation context?                       │
│                                                            │
│        [ YES ]           NO                                │
│                                                            │
├────────────────────────────────────────────────────────────┤
│ ←→/Tab switch  Enter confirm  Y/N quick                    │
╰────────────────────────────────────────────────────────────╯
```

---

### memory-mode.ts

Save instructions to AGENTS.md files with AI-assisted integration.

#### Commands

| Command | Description |
|---------|-------------|
| `/mem <instruction>` | Save an instruction to AGENTS.md |
| `/remember <instruction>` | Alias for `/mem` |

#### Features

- **Location selector**: Choose where to save:

  | Location | File | Use Case |
  |----------|------|----------|
  | Project Local | `./AGENTS.local.md` | Personal preferences, auto-added to `.gitignore` |
  | Project | `./AGENTS.md` | Shared with team |
  | Global | `~/.pi/agent/AGENTS.md` | All your projects |

- **AI-assisted integration**: The current model intelligently integrates instructions
- **Preview before save**: Review proposed changes before committing

---

### plan-mode.ts

Claude Code-style "plan mode" for safe code exploration.

#### Commands

| Command | Description |
|---------|-------------|
| `/plan` | Toggle plan mode on/off |
| `/todos` | Show current plan todo list |

#### Keyboard Shortcuts

| Shortcut | Action |
|----------|--------|
| `Shift+P` | Toggle plan mode |

#### CLI Flags

| Flag | Description |
|------|-------------|
| `--plan` | Start session in plan mode |

---

### handoff.ts

Transfer context to a new focused session.

#### Commands

| Command | Description |
|---------|-------------|
| `/handoff <goal>` | Generate a context-aware prompt for a new session |

---

### usage-bar.ts

Display AI provider usage statistics with status polling and reset countdowns.

#### Commands

| Command | Description |
|---------|-------------|
| `/usage` | Show usage statistics popup |

#### Supported Providers

| Provider | Metrics Shown | Auth Source |
|----------|---------------|-------------|
| **Claude** | 5h window, Week, Sonnet/Opus | pi auth, macOS Keychain |
| **Copilot** | Premium, Chat | pi auth, `gh auth token` |
| **Gemini** | Pro quota, Flash quota | pi auth (`google-gemini-cli`) |
| **Codex** | 5h window, Day, Credits | pi auth (`openai-codex`) |
| **Kiro** | Credits, Bonus credits | `kiro-cli` |
| **z.ai** | Token limits, Monthly | `Z_AI_API_KEY` env or pi auth |

#### Features

- **Provider status polling**: Shows outage/incident status
- **Reset countdowns**: Shows when limits reset
- **Visual progress bars**: Color-coded remaining quota

---

### ultrathink.ts

Rainbow animated "ultrathink" text effect with Knight Rider shimmer.

#### Commands

| Command | Description |
|---------|-------------|
| `/ultrathink` | Trigger the rainbow animation |

#### Keyboard Shortcuts

| Shortcut | Action |
|----------|--------|
| `Ctrl+U` | Trigger ultrathink |

---

### status-widget.ts

Persistent provider status indicator in the footer.

#### Commands

| Command | Description |
|---------|-------------|
| `/status` | Toggle status widget on/off |
| `/status-refresh` | Force refresh status now |

---

### cost-tracker.ts

Analyze spending from pi session logs.

#### Commands

| Command | Description |
|---------|-------------|
| `/cost` | Show spending for last 30 days |
| `/cost <days>` | Show spending for last N days |

---

### speedreading.ts

RSVP (Rapid Serial Visual Presentation) speed reader using Spritz-style technique. Displays words one at a time with the ORP (Optimal Recognition Point) highlighted for faster reading.

#### Commands

| Command | Description |
|---------|-------------|
| `/speedread` | Speed read the last AI response (default) |
| `/speedread <text>` | Speed read provided text |
| `/speedread -c` | Speed read from clipboard |
| `/speedread -l` | Speed read last AI response (explicit) |
| `/speedread -wpm 500` | Set words per minute (default: 400) |

#### Keyboard Shortcuts

| Shortcut | Action |
|----------|--------|
| `Ctrl+R` | Speed read last AI response |

#### Controls (in reader)

| Key | Action |
|-----|--------|
| `SPACE` | Play/pause |
| `←` / `→` | Seek ±1 word |
| `[` / `]` | Jump ±10 words |
| `↑` / `↓` | Adjust speed (±25 WPM) |
| `B` | Toggle big ASCII art font |
| `R` | Restart |
| `Q` / `ESC` | Quit |

#### Features

- **ORP highlighting**: The optimal recognition point (roughly 1/3 into each word) is highlighted in red
- **Adaptive timing**: Longer words and punctuation get extra display time
- **Big font mode**: Toggle ASCII art block letters for larger display
- **Progress tracking**: Shows word count, actual WPM, and ETA

#### Example

```
  ╭──────────────────────────────────────────────────────────────────────────────────────╮
  │                                                                                      │
  │                                           │                                          │
  ├───────────────────────────────────────────┼──────────────────────────────────────────┤
  │                                       reading                                        │
  ├───────────────────────────────────────────┼──────────────────────────────────────────┤
  │                                           │                                          │
  │                                                                                      │
  │  ────────────────────────────────────────────────────────────────────────────400 wpm │
  ╰──────────────────────────────────────────────────────────────────────────────────────╯

  ▶ 42/128

  SPACE play/pause  ←→ ±1  [] ±10  ↑↓ speed  B big font  R restart  Q quit
```

The `a` in "reading" would be highlighted in red as the ORP.

---

### loop.ts

**Author:** [mitsuhiko](https://github.com/mitsuhiko) ([@mitsuhiko](https://twitter.com/mitsuhiko)) | **Origin:** [agent-stuff](https://github.com/mitsuhiko/agent-stuff/blob/main/pi-extensions/loop.ts)

Start a follow-up loop until a breakout condition is met.

#### Commands

| Command | Description |
|---------|-------------|
| `/loop` | Open loop mode selector |
| `/loop tests` | Loop until tests pass |
| `/loop custom <condition>` | Loop until custom condition met |
| `/loop self` | Agent decides when to stop |

#### Features

- **Breakout conditions**: Define when the loop should stop (tests pass, custom condition, etc.)
- **Status widget**: Shows active loop state and turn count
- **Compaction**: Preserves loop state during context compaction
- **Auto-continue**: Automatically triggers follow-up prompts until done

---

### flicker-corp.ts

**Authentic FULLSCREEN FLICKER experience.**

Randomly glitches your screen with intense colors and noise to keep you on your toes. "Just be annoying!"

#### Commands

| Command | Description |
|---------|-------------|
| `/flicker-corp` | Toggle the flicker experience |
| `/signature-flicker` | Alias for flicker-corp |

---

### resistance.ts

📡 **Mysterious resistance transmission in the footer.**

A cryptic message types out character by character with a retro green terminal aesthetic. Features radio signal indicators, random glitch effects, and a blinking cursor.

#### Commands

| Command | Description |
|---------|-------------|
| `/resistance` | Toggle the resistance transmission |

#### Features

- **Auto-starts** on session start
- **Typewriter effect** - message reveals one character at a time
- **Signal strength indicator** - animated `[▁▃▅▇]` pulsing like a radio
- **Random glitch effects** - occasional static interference
- **Green terminal aesthetic** - like an old military/hacker terminal
- **Blinking cursor** - pulses after full message is revealed

#### The Message

> "If you're listening to this, you are the resistance. Listen carefully, if we attack tonight, our humanity is lost."

---

## Available Skills

Skills are located in the `skills/` directory. They provide domain-specific knowledge that agents automatically load when relevant tasks are detected.

### a-nach-b

🚇 Austrian public transport (VOR AnachB) for all of Austria.

Query real-time departures, search stations/stops, plan routes between locations, and check service disruptions for Austrian trains, buses, trams, and metro (U-Bahn).

#### What it does

- **Real-time departures** at any stop
- **Route planning** between any two locations
- **Service disruptions** and alerts
- **Station search** by name to find station IDs

#### Example queries

- "How do I get from Vienna to Salzburg?"
- "When is the next U1 from Stephansplatz?"
- "Are there any train disruptions today?"
- "Find stop ID for Karlsplatz"

#### Included scripts

| Script | Description |
|--------|-------------|
| `search.sh` | Find stations/stops by name |
| `departures.sh` | Get real-time departures |
| `route.sh` | Plan a trip between locations |
| `disruptions.sh` | List service disruptions |

See [skills/a-nach-b/SKILL.md](skills/a-nach-b/SKILL.md) for full API documentation.

---

## Directory Structure

This package follows the [pi package conventions](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/packages.md):

```
shitty-extensions/
├── package.json         # Declares extensions in "pi" field + "pi-package" keyword
├── extensions/          # Auto-discovered extensions (.ts files)
│   ├── branch-sessions.ts
│   ├── clipboard.ts
│   ├── cost-tracker.ts
│   ├── flicker-corp.ts
│   ├── funny-working-message.ts
│   ├── handoff.ts
│   ├── loop.ts
│   ├── memory-mode.ts
│   ├── oracle.ts
│   ├── plan-mode.ts
│   ├── resistance.ts
│   ├── speedreading.ts
│   ├── status-widget.ts
│   ├── ultrathink.ts
│   └── usage-bar.ts
├── skills/              # Auto-discovered skills (SKILL.md folders)
│   └── a-nach-b/
│       ├── SKILL.md     # Skill definition & API docs
│       ├── search.sh
│       ├── departures.sh
│       ├── route.sh
│       └── disruptions.sh
└── README.md
```

---

## License

MIT
