# 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 ` | Ask for a second opinion with model picker | | `/oracle -m gpt-4o ` | Direct query to specific model | | `/oracle -f file.ts ` | 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 ` | Save an instruction to AGENTS.md | | `/remember ` | 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 ` | 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 ` | 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 ` | 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 ` | 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