From 6841d93577c1c58c8b19a69ded5717bcb0c9b500 Mon Sep 17 00:00:00 2001 From: Rahul Tyagi Date: Sun, 21 Jun 2026 18:49:02 +0530 Subject: [PATCH] docs: polish README and add MkDocs site published to GitHub Pages - Rewrite README with hero, badges, and docs link - Add MkDocs-Material site under docs/ (7 pages) - Add GitHub Actions workflow to build and deploy docs to Pages - Ignore mkdocs build output (site/) --- .github/workflows/docs.yml | 57 +++++++++++++++++ .gitignore | 3 + README.md | 128 +++++++++++++++++++------------------ docs/agents.md | 71 ++++++++++++++++++++ docs/architecture.md | 66 +++++++++++++++++++ docs/commands.md | 89 ++++++++++++++++++++++++++ docs/contributing.md | 51 +++++++++++++++ docs/index.md | 32 ++++++++++ docs/installation.md | 74 +++++++++++++++++++++ docs/pets.md | 52 +++++++++++++++ mkdocs.yml | 42 ++++++++++++ 11 files changed, 604 insertions(+), 61 deletions(-) create mode 100644 .github/workflows/docs.yml create mode 100644 docs/agents.md create mode 100644 docs/architecture.md create mode 100644 docs/commands.md create mode 100644 docs/contributing.md create mode 100644 docs/index.md create mode 100644 docs/installation.md create mode 100644 docs/pets.md create mode 100644 mkdocs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..86f33d1 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,57 @@ +name: Docs + +on: + push: + branches: + - main + paths: + - docs/** + - mkdocs.yml + - .github/workflows/docs.yml + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.x + + - name: Install MkDocs Material + run: pip install mkdocs-material + + - name: Build docs + run: mkdocs build + + - name: Configure Pages + uses: actions/configure-pages@v5 + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: site + + deploy: + needs: build + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 280f0c6..bc7f266 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,6 @@ node_modules # Bun bun.lockb + +# MkDocs build output +site/ diff --git a/README.md b/README.md index 5218b45..3a73a68 100644 --- a/README.md +++ b/README.md @@ -6,39 +6,39 @@ [![CI](https://github.com/dropdevrahul/campy/actions/workflows/ci.yml/badge.svg)](https://github.com/dropdevrahul/campy/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT) [![Made with bun](https://img.shields.io/badge/made%20with-bun-black.svg)](https://bun.sh) +[![Docs](https://img.shields.io/badge/docs-github.io-blue.svg)](https://dropdevrahul.github.io/campy/) -Animated terminal pets for CLI coding agents — Claude Code, OpenCode, Pi, Gemini CLI, Codex CLI, Cursor CLI, Aider. +**Animated ASCII terminal pets for CLI coding agents.** -[Features](#features) • [Installation](#installation) • [Per-agent setup](#per-agent-setup) • [Slash Commands](#slash-commands) * [Discord](https://discord.gg/aY9Fv5ZRj) - - - - -## Demo +Claude Code · OpenCode · Pi · Gemini CLI · Codex CLI · Cursor CLI · Aider ![campy demo](./campy.gif) -## Overview +[Features](#features) • [Installation](#installation) • [Per-agent setup](#per-agent-setup) • [Slash Commands](#slash-commands) • [Docs](https://dropdevrahul.github.io/campy/) • [Discord](https://discord.gg/aY9Fv5ZRj) + + -campy brings delightful ASCII pets to your terminal sidebar. Pets animate through states, react to coding events, and display contextual speech bubbles—adding personality to your coding sessions. +--- ## Features -- **4 Pet Types**: Cat, Hamster, Ghost, and Robot -- **7 Animation States**: idle, happy, sleeping, eating, playing, excited, sad—with multi-frame animations and blinking -- **Speech Bubbles**: Context-aware messages ("Edited file!", "Thinking...", "Need a hand?") -- **Happiness System**: Feed, play, or pet your companion to increase happiness -- **Event Reactions**: Automatic responses to tool use, file edits, errors, and idle states -- **Multi-agent**: One CLI + per-agent adapters for Claude Code, OpenCode, Pi, Gemini CLI, Codex CLI, Cursor CLI, and Aider -- **MCP server**: One stdio server unlocks Gemini / Codex / Cursor at once +Your pet lives in a terminal sidebar and reacts to what you're doing. It blinks, animates through moods, and drops speech bubbles when something happens — a file gets edited, a command runs, an error fires. There are four pets to choose from (Cat, Hamster, Ghost, Robot), each with seven animation states and a layered blinking system. + +- **Four pets, seven states each** — idle, happy, sleeping, eating, playing, excited, sad, all multi-frame animated +- **Happiness system** — feed (+15), play (+20), or pet (+10) to keep your companion content +- **Speech bubbles** — context-aware messages like "Edited a file!", "Thinking…", "Need a hand?" +- **Automatic event reactions** — hooks fire on tool use, file edits, errors, and idle time +- **One CLI, every agent** — a single `campy` binary with per-agent adapters; no per-agent installs beyond a one-time `campy setup` +- **MCP server included** — one stdio server wires Gemini CLI, Codex CLI, and Cursor CLI at once +- **Zero-token for Claude Code** — hooks and the statusline are Bash scripts that run outside the model ## Installation -> **Prerequisite:** [bun](https://bun.sh) (`curl -fsSL https://bun.sh/install | bash`). The CLI is a single TypeScript file with a `#!/usr/bin/env bun` shebang — no build step. +**Prerequisite:** [bun](https://bun.sh) (`curl -fsSL https://bun.sh/install | bash`). The CLI is a single TypeScript file with a `#!/usr/bin/env bun` shebang — no build step required. -campy isn't on npm yet. Pick one of these: +campy isn't on the public npm registry yet. There are two ways to install it: -### Option 1 — install straight from GitHub (recommended) +### Option 1 — install from GitHub (recommended) ```bash # via bun @@ -48,7 +48,7 @@ bun add -g github:dropdevrahul/campy npm install -g github:dropdevrahul/campy ``` -This registers `campy` on your `$PATH`. Verify: +This registers `campy` on your `$PATH`. Verify with: ```bash campy status @@ -56,93 +56,99 @@ campy status ### Option 2 — clone and symlink +If you'd rather keep the source around to hack on it: + ```bash git clone https://github.com/dropdevrahul/campy.git ~/work/campy cd ~/work/campy && bun install chmod +x cli/campy.ts -ln -s "$PWD/cli/campy.ts" ~/.bun/bin/campy # or any dir on $PATH +ln -s "$PWD/cli/campy.ts" ~/.bun/bin/campy # or any directory on $PATH ``` -### Auto-detect & wire every agent you have installed +### Wire your agents + +After installing, run the auto-setup to detect and wire every agent on your machine: ```bash campy setup ``` -This detects which agents are installed on your machine (`~/.claude`, `~/.gemini`, `~/.codex`, `~/.cursor`, `~/.pi`, `.opencode/`, `.aider.conf.yml`) and wires each natively. Or install for one agent: +This looks for `~/.claude`, `~/.gemini`, `~/.codex`, `~/.cursor`, `~/.pi`, `.opencode/`, and `.aider.conf.yml`, and wires each natively. To install for one agent specifically: ```bash campy install claude-code # | opencode | pi | gemini | codex | cursor | aider ``` -### Render the pet +### Show the pet ```bash -campy watch # run inline in any terminal -campy attach # auto-split a side pane (tmux / zellij / wezterm / kitty) +campy watch # full-screen animated pet — run this in a side pane +campy attach # auto-split a pane (tmux / zellij / wezterm / kitty) ``` ## Per-agent setup -| Agent | Surface | Install | -|-------------|---------------------------------|---------------------------------| -| Claude Code | statusline + hooks | `campy install claude-code` | -| OpenCode | native sidebar widget | `campy install opencode` | -| Pi | native sidebar widget | `campy install pi` | -| Gemini CLI | MCP tools (inline ASCII card) | `campy install gemini` | -| Codex CLI | MCP tools (inline ASCII card) | `campy install codex` | -| Cursor CLI | MCP tools (inline ASCII card) | `campy install cursor` | -| Aider | `.git/hooks/post-commit` | `campy install aider` | +Different agents have different native surfaces. campy meets each one where it lives: -For agents with no built-in render surface, run `campy attach` in a side pane. +| Agent | Surface | Install | +|-------------|----------------------------------|---------------------------------| +| Claude Code | statusline + reactive hooks | `campy install claude-code` | +| OpenCode | native sidebar widget | `campy install opencode` | +| Pi | native sidebar widget | `campy install pi` | +| Gemini CLI | MCP tools (inline ASCII card) | `campy install gemini` | +| Codex CLI | MCP tools (inline ASCII card) | `campy install codex` | +| Cursor CLI | MCP tools (inline ASCII card) | `campy install cursor` | +| Aider | `.git/hooks/post-commit` | `campy install aider` | -### Token usage +For agents that don't have a built-in render surface, `campy attach` spawns a side pane automatically. -The Claude Code adapter is **zero-token** for normal operation. Hooks and the statusline are bash scripts run outside the model. Slash commands (`/campy:feed`, etc.) cost a small prompt when *you* invoke them. +**Claude Code note:** The adapter is zero-token during normal operation. Hooks and the statusline are Bash scripts that run outside the model. Slash commands (`/campy:feed`, etc.) cost a small prompt only when you explicitly invoke them. ## Slash Commands -The slash-command prefix depends on the host: +The prefix depends on which agent you're using: - **OpenCode / Pi**: `/pet feed`, `/pet play`, `/pet robot`, … - **Claude Code**: `/campy:feed`, `/campy:play`, `/campy:pet`, `/campy:switch ` -- **MCP agents** (Gemini / Codex / Cursor): call the tools `campy_feed`, `campy_play`, `campy_pet`, `campy_switch`, `campy_status` - -| Command | Effect | -|---------------|---------------------------------| -| `feed` | Feed your pet (+15 happiness) | -| `play` | Play with your pet (+20 happiness) | -| `pet` | Pet your pet (+10 happiness) | -| `sleep` | Put pet to sleep | -| `wake` | Wake pet | -| `status` | Show mood & happiness | -| `switch ` | `cat` \| `hamster` \| `ghost` \| `robot` | +- **MCP agents** (Gemini / Codex / Cursor): call tools `campy_feed`, `campy_play`, `campy_pet`, `campy_switch`, `campy_status` + +| Command | Effect | +|------------------|--------------------------------------| +| `feed` | Feed your pet (+15 happiness) | +| `play` | Play with your pet (+20 happiness) | +| `pet` | Pet your pet (+10 happiness) | +| `sleep` | Put the pet to sleep | +| `wake` | Wake the pet | +| `status` | Show current mood and happiness | +| `switch ` | `cat` \| `hamster` \| `ghost` \| `robot` | ## Available Pets -| Pet | States | Blinking | Emoji | -|-----|--------|----------|-------| -| Cat | 7 states | Yes (layered eyes) | 🐱 | -| Hamster | 7 states | Yes (frame-step) | 🐹 | -| Ghost | 7 states | Yes (layered eyes) | 👻 | -| Robot | 7 states | Yes (layered eyes) | 🤖 | +| Pet | Emoji | States | Blinking | +|---------|-------|--------|-----------------| +| Cat | 🐱 | 7 | Layered eyes | +| Hamster | 🐹 | 7 | Frame-step | +| Ghost | 👻 | 7 | Layered eyes | +| Robot | 🤖 | 7 | Layered eyes | + +All pets cycle through: idle, happy, sleeping, eating, playing, excited, sad. ## File Structure ``` -core/ # portable pet logic (animation, store, runtime, render) -cli/campy.ts # the campy binary (bun) +core/ # portable pet logic — animation, store, runtime, render +cli/campy.ts # the campy binary (bun, no build step) adapters/ ├── claude-code/ # hooks + statusline + slash commands ├── pi/ # in-process TUI widget ├── mcp/ # stdio MCP server (Gemini / Codex / Cursor) └── gemini/ # gemini-extension.json + GEMINI.md -.opencode/ # OpenCode plugins (re-export from core/) -.claude-plugin/ # Claude Code marketplace manifest +.opencode/ # OpenCode plugins (thin re-exports of core/) +.claude-plugin/ # Claude Code plugin marketplace manifest ghost-pet/ # legacy standalone Bash plugin (kept for back-compat) ``` -See `CLAUDE.md` for the full architecture, and `docs/superpowers/specs/2026-06-13-cli-agent-support-design.md` for the multi-agent design spec. +The full architecture is in [`CLAUDE.md`](./CLAUDE.md). The multi-agent design spec lives at `docs/superpowers/specs/2026-06-13-cli-agent-support-design.md`. ## License diff --git a/docs/agents.md b/docs/agents.md new file mode 100644 index 0000000..1f9422f --- /dev/null +++ b/docs/agents.md @@ -0,0 +1,71 @@ +# Agents + +campy supports seven agents. Each one is wired through its own native extension surface so the pet shows up where you're actually looking while you code. + +## Supported agents + +| Agent | Surface | Install command | +|-------------|----------------------------------|---------------------------------| +| Claude Code | statusline + reactive hooks | `campy install claude-code` | +| OpenCode | native sidebar widget | `campy install opencode` | +| Pi | native sidebar widget | `campy install pi` | +| Gemini CLI | MCP tools (inline ASCII card) | `campy install gemini` | +| Codex CLI | MCP tools (inline ASCII card) | `campy install codex` | +| Cursor CLI | MCP tools (inline ASCII card) | `campy install cursor` | +| Aider | `.git/hooks/post-commit` | `campy install aider` | + +For agents without a built-in render surface, `campy attach` spawns a side pane in your terminal multiplexer. + +## Claude Code + +Claude Code is wired via the plugin marketplace. The adapter installs two reactive hooks (`PostToolUse` and `Stop`) and a `SessionStart` hook, plus a statusline script. Hooks are Bash scripts that run outside the model — they call the campy CLI to mutate pet state. The statusline renders the current pet inline. + +```bash +campy install claude-code +``` + +!!! note "Zero-token operation" + Hooks and the statusline never touch the model. Slash commands (`/campy:feed`, etc.) cost a small prompt only when you invoke them explicitly. + +Available slash commands: `/campy:feed`, `/campy:play`, `/campy:pet`, `/campy:switch `. + +## OpenCode and Pi + +OpenCode and Pi both support in-process TUI widgets. campy ships a native sidebar plugin that registers at `order: 350` in the sidebar slot and reacts to OpenCode events (`file.edited`, `command.executed`, `session.error`, `session.idle`, `message.part.delta`, `tui.prompt.append`). + +```bash +campy install opencode +campy install pi +``` + +Slash commands use the `/pet` prefix: `/pet feed`, `/pet play`, `/pet cat`, etc. + +## Gemini CLI, Codex CLI, Cursor CLI + +These agents support MCP (Model Context Protocol). campy runs a stdio MCP server that watches the project directory for file edits, fires `file_edited` events automatically, and exposes five tools: + +| Tool | Effect | +|------------------|--------------------------------| +| `campy_feed` | Feed the pet (+15 happiness) | +| `campy_play` | Play with the pet (+20) | +| `campy_pet` | Pet the pet (+10) | +| `campy_switch` | Switch to a different pet | +| `campy_status` | Get current state as ASCII card | + +```bash +campy install gemini # writes ~/.gemini/extensions/campy/ +campy install codex # adds [mcp_servers.campy] to ~/.codex/config.toml +campy install cursor # updates ~/.cursor/mcp.json +``` + +The MCP server is started with `campy mcp`. + +## Aider + +Aider is wired via a `post-commit` git hook that fires `file_edited` events after each commit. + +```bash +campy install aider +``` + +Since Aider has no built-in widget surface, run `campy attach` or `campy watch` in a side pane to see the pet. diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..c347181 --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,66 @@ +# Architecture + +campy is organized as a portable `core/` library plus per-agent adapters. All pet logic — animations, state, rendering, event handling — lives in `core/`. Adapters are thin wrappers that wire `core/` into each agent's native extension surface. + +## Layout + +``` +campy/ +├── core/ # portable, host-agnostic single source of truth +│ ├── types.ts # PetState, AnimStep, AnimLayer, PetAnimations, FrameData +│ ├── frame-utils.ts # HL, pad(), mergeLayers() +│ ├── animation-engine.ts # AnimationEngine (layered timers, transitions) +│ ├── gif-engine.ts # GifEngine (linear JSON frame loop) +│ ├── pets/ # cat, hamster, ghost, robot animation data + registry +│ ├── theme.ts # STATE_COLORS, STATE_ICONS, PET_ICONS, PET_COLORS +│ ├── personality.ts # IDLE_PHRASES, PET_GREETINGS, PET_PERSONALITY +│ ├── happiness.ts # clamp, meterBar, INTERACTION_DELTA, DEFAULT_HAPPINESS +│ ├── events.ts # canonical events, reactionFor(), isCanonicalEvent() +│ ├── store.ts # state-file bus: readState, writeState, mutateState +│ ├── actions.ts # store-side actions (applyEvent/Interaction/Sleep/Wake/Switch) +│ ├── detect.ts # detectAgents() — which agents are installed +│ ├── runtime.ts # PetRuntime — host-agnostic state machine + animation +│ └── render.ts # petLines(), statusLine(), petCard(), staticSprite() +├── cli/campy.ts # the campy binary (shebang bun, no build step) +├── adapters/ +│ ├── claude-code/ # hooks + statusline + slash commands +│ ├── pi/ # in-process TUI widget +│ ├── mcp/server.ts # MCP stdio server: file-watch + campy_* tools +│ └── gemini/ # gemini-extension.json + GEMINI.md +├── .opencode/plugins/ # thin re-export shims → core/ +├── .claude-plugin/ # Claude Code marketplace manifest +├── ghost-pet/ # legacy Bash plugin (kept for back-compat) +└── assets/ # gifs/ + ascii-frames/ +``` + +## State-file bus + +All adapters communicate via a shared state file at `~/.campy/state.json` (or the path in `$CAMPY_STATE`). Short-lived hooks mutate it via the `campy` CLI; long-lived renderers (`campy watch`, the statusline) read it. Writes are atomic — a temp file is written and then renamed. + +## AnimationEngine + +`AnimationEngine` drives all animations via chained `setTimeout`s — no central clock. Each `AnimLayer` runs on its own timer. Frames carry either a fixed `duration` or a `durationRange` (randomized per cycle for organic motion). + +`setState()` plays an optional `TransitionAnim` before settling into the target state's looping layers. `resetToState()` jumps immediately without a transition. Always call `engine.destroy()` before discarding an engine — `switchPet()` does this. + +Sprites are fixed-height: every frame is run through `pad(lines, width)` to `HL` (8) rows. Frames that skip this step will misalign during compositing. + +## Claude Code adapter + +The Claude Code adapter wires three hooks: + +- `SessionStart` (one-shot) — fires on session open +- `PostToolUse` (scoped to `Edit|Write|MultiEdit|NotebookEdit|Bash`) — fires on tool use +- `Stop` — fires when the agent stops + +Each hook is a short Bash script that calls `campy event ` or `campy feed` etc. to mutate state. The statusline is a thin wrapper around `campy statusline`. + +## MCP server + +`adapters/mcp/server.ts` runs a stdio MCP server. It watches the project directory for file changes and fires `file_edited` events, and exposes five tools (`campy_feed`, `campy_play`, `campy_pet`, `campy_switch`, `campy_status`). Tool responses return the pet as an inline ASCII card. `dispatch()` is unit-tested; `runMcpServer()` wires stdio. + +## OpenCode plugins + +`.opencode/plugins/` contains two entry files (`pets.tsx` and `gif-pets.tsx`) that are unchanged from the original. All supporting modules under `lib/` and `pets/` are now thin re-export shims pointing at `core/`. `core/` is the only place where sprite data, theme, and personality are defined. + +`pets.tsx` registers in the `sidebar_content` slot at `order: 350`. `gif-pets.tsx` is an independent plugin that plays GIF-derived ASCII animations — registered at `order: 360`, toggled via `/gif on|off`. diff --git a/docs/commands.md b/docs/commands.md new file mode 100644 index 0000000..d1a5545 --- /dev/null +++ b/docs/commands.md @@ -0,0 +1,89 @@ +# Commands + +campy exposes commands through the CLI and through each agent's native slash-command or tool surface. + +## CLI commands + +The `campy` binary covers the full lifecycle: installing adapters, running the pet, sending events, and querying state. + +```bash +campy watch # full-screen animated pet (run in a side pane) +campy attach # spawn a side pane (tmux / zellij / wezterm / kitty) +campy statusline # print one status line and exit +campy status # one-shot state dump (pet, mood, happiness) + +campy setup # detect installed agents and wire each natively +campy install # pi | claude-code | opencode | gemini | codex | cursor | aider + +campy feed # feed the pet (+15 happiness) +campy play # play with the pet (+20 happiness) +campy pet # pet the pet (+10 happiness) +campy sleep # put the pet to sleep +campy wake # wake the pet + +campy switch # switch to cat | hamster | ghost | robot +campy event # fire a canonical event (see below) +campy mcp # run the MCP stdio server +``` + +## Slash commands + +The prefix depends on which agent you're using. + +### OpenCode / Pi + +``` +/pet feed +/pet play +/pet pet +/pet sleep +/pet wake +/pet status +/pet switch +``` + +### Claude Code + +``` +/campy:feed +/campy:play +/campy:pet +/campy:switch +``` + +### MCP agents (Gemini CLI, Codex CLI, Cursor CLI) + +Call these as MCP tools: + +``` +campy_feed +campy_play +campy_pet +campy_switch +campy_status +``` + +## Happiness system + +Each interaction changes the pet's happiness level (0–100): + +| Command | Happiness delta | +|----------|-----------------| +| `feed` | +15 | +| `play` | +20 | +| `pet` | +10 | + +Happiness gradually decreases over time. Keep it above 50 to keep your pet in a cheerful mood. + +## Events + +Events are fired automatically by hooks, but you can also fire them manually: + +```bash +campy event file_edited --file path/to/file.ts +campy event command_run --cmd npm +campy event error +campy event idle +``` + +Canonical event types: `file_edited`, `command_run`, `error`, `idle`, `session_start`, `session_end`. diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 0000000..558b3c4 --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,51 @@ +# Contributing + +Thanks for your interest in contributing to campy. Please read the documents at the root of the repo before opening a pull request. + +## Guidelines + +- [CONTRIBUTING.md](https://github.com/dropdevrahul/campy/blob/main/CONTRIBUTING.md) — how to set up the project, coding conventions, and the pull request process +- [CODE_OF_CONDUCT.md](https://github.com/dropdevrahul/campy/blob/main/CODE_OF_CONDUCT.md) — expected behavior in the community + +## Development setup + +```bash +git clone https://github.com/dropdevrahul/campy.git +cd campy +bun install +``` + +Run the tests: + +```bash +bun test +``` + +Typecheck: + +```bash +npm run typecheck +``` + +Run the CLI directly: + +```bash +bun cli/campy.ts status +bun cli/campy.ts watch +``` + +## Project structure + +See [Architecture](architecture.md) for how the codebase is organized. The short version: make changes in `core/` and the adapters pick them up automatically through re-export shims. + +## Adding a pet + +1. Define a `PetAnimations` object in `core/pets/.ts` +2. Register it in `PET_ANIMATIONS` in `core/pets/index.ts` +3. Add entries to `PET_ICONS` and `PET_COLORS` in `core/theme.ts` +4. Add `PET_GREETINGS` and `PET_PERSONALITY` entries in `core/personality.ts` +5. All frames must be padded to `HL` (8) rows using `pad()` from `core/frame-utils.ts` + +## Reporting issues + +Open an issue on [GitHub](https://github.com/dropdevrahul/campy/issues). Include your OS, bun version, and which agent you're using. diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..5de01eb --- /dev/null +++ b/docs/index.md @@ -0,0 +1,32 @@ +# campy + +**Animated ASCII terminal pets for CLI coding agents.** + +campy brings a small animated companion to your terminal sidebar. Your pet reacts to what you're working on — it animates through moods, blinks, and drops speech bubbles when a file is edited, a command runs, or an error fires. When things go quiet, it settles into an idle state and waits patiently. + +There are four pets to choose from (Cat, Hamster, Ghost, Robot), each with seven animation states and its own personality. A single `campy` binary handles everything; per-agent adapters wire it natively into Claude Code, OpenCode, Pi, Gemini CLI, Codex CLI, Cursor CLI, and Aider. + +## What campy is + +- A CLI tool (`campy`) that manages pet state through a shared state file (`~/.campy/state.json`) +- A set of per-agent adapters that hook into each agent's native extension surface +- A portable `core/` library that all adapters share — one source of truth for animations, state, and rendering + +## What campy is not + +campy doesn't modify your agent's context window or inject tokens into prompts. For Claude Code, hooks and the statusline are Bash scripts that run entirely outside the model. The pet reacts to events; it doesn't participate in conversations. + +## Quick start + +```bash +# Install (requires bun) +bun add -g github:dropdevrahul/campy + +# Wire every agent you have installed +campy setup + +# Run the pet in a side pane +campy watch +``` + +See [Installation](installation.md) for full setup instructions, or [Agents](agents.md) for per-agent wiring details. diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..d750eaf --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,74 @@ +# Installation + +campy requires [bun](https://bun.sh). The CLI is a single TypeScript file with a `#!/usr/bin/env bun` shebang — no build step, no compilation. + +```bash +# Install bun if you don't have it +curl -fsSL https://bun.sh/install | bash +``` + +campy isn't on the public npm registry yet, so you install it directly from GitHub. + +## Option 1 — install from GitHub (recommended) + +```bash +# via bun +bun add -g github:dropdevrahul/campy + +# or via npm +npm install -g github:dropdevrahul/campy +``` + +This registers `campy` on your `$PATH`. Verify: + +```bash +campy status +``` + +## Option 2 — clone and symlink + +If you want to keep the source around to hack on it: + +```bash +git clone https://github.com/dropdevrahul/campy.git ~/work/campy +cd ~/work/campy && bun install +chmod +x cli/campy.ts +ln -s "$PWD/cli/campy.ts" ~/.bun/bin/campy # or any directory on $PATH +``` + +## Wire your agents + +After installing the CLI, run the auto-setup to detect and wire every agent on your machine: + +```bash +campy setup +``` + +This scans for `~/.claude`, `~/.gemini`, `~/.codex`, `~/.cursor`, `~/.pi`, `.opencode/`, and `.aider.conf.yml`, and wires each agent natively. To install for one agent specifically: + +```bash +campy install claude-code # | opencode | pi | gemini | codex | cursor | aider +``` + +## Show the pet + +```bash +campy watch # full-screen animated pet — run this in a side pane +campy attach # auto-split a pane (tmux / zellij / wezterm / kitty) +``` + +`campy attach` detects your terminal multiplexer and opens a side pane automatically. If you're in a bare terminal with no multiplexer, run `campy watch` manually in a second pane. + +## Verify the install + +```bash +campy status # prints current pet, mood, and happiness level +``` + +You should see output like: + +``` +pet: cat state: idle happiness: 75 +``` + +If the command isn't found, make sure `~/.bun/bin` (or wherever you symlinked the binary) is on your `$PATH`. diff --git a/docs/pets.md b/docs/pets.md new file mode 100644 index 0000000..ea05531 --- /dev/null +++ b/docs/pets.md @@ -0,0 +1,52 @@ +# Pets + +campy ships four pets, each with its own sprite data, personality phrases, and animation style. All four share the same seven animation states and the same happiness system. + +## Available pets + +| Pet | Emoji | Switch command | +|---------|-------|-------------------------| +| Cat | 🐱 | `campy switch cat` | +| Hamster | 🐹 | `campy switch hamster` | +| Ghost | 👻 | `campy switch ghost` | +| Robot | 🤖 | `campy switch robot` | + +## Animation states + +Every pet cycles through seven states: + +| State | When it appears | +|-----------|--------------------------------------------------| +| `idle` | Default — pet is relaxed and waiting | +| `happy` | After a positive interaction or event | +| `sleeping`| After `campy sleep`, or during a long quiet stretch | +| `eating` | When `campy feed` is called | +| `playing` | When `campy play` is called | +| `excited` | High-energy events (new session, big edit burst) | +| `sad` | Errors, or when happiness drops low | + +## Animation model + +Each state is a stack of independently timed animation layers. The body layer loops on one timer; the eyes layer loops on a separate, slower timer. `mergeLayers()` composites them per-row, with non-space characters in later layers overwriting earlier ones. This is what makes the blinking look natural — the eyes animate independently of the body. + +| Pet | Blinking style | +|---------|-----------------| +| Cat | Layered eyes | +| Hamster | Frame-step | +| Ghost | Layered eyes | +| Robot | Layered eyes | + +## Adding a pet + +To add a new pet, define a `PetAnimations` object in a new file under `core/pets/.ts`, register it in `PET_ANIMATIONS` in `core/pets/index.ts`, and add entries to `PET_ICONS`, `PET_GREETINGS`, and `PET_PERSONALITY` in `core/theme.ts` and `core/personality.ts`. All frames must be run through `pad(lines, width)` to the standard height (`HL = 8` rows) — compositing breaks if frames differ in height. + +## Switching pets + +```bash +campy switch hamster # switch to hamster +campy switch robot # switch to robot +``` + +In OpenCode or Pi, use `/pet cat`, `/pet hamster`, etc. In Claude Code, use `/campy:switch `. In MCP agents, call `campy_switch` with the pet name. + +The switch is immediate and persists across sessions through the state file. diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..28a840a --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,42 @@ +site_name: campy +site_url: https://dropdevrahul.github.io/campy/ +site_description: Animated ASCII terminal pets for CLI coding agents +site_author: dropdevrahul +repo_url: https://github.com/dropdevrahul/campy +repo_name: dropdevrahul/campy + +docs_dir: docs + +theme: + name: material + features: + - navigation.tabs + - navigation.top + - search.suggest + - content.code.copy + palette: + - scheme: default + toggle: + icon: material/brightness-7 + name: Switch to dark mode + - scheme: slate + toggle: + icon: material/brightness-4 + name: Switch to light mode + +markdown_extensions: + - admonition + - pymdownx.superfences + - pymdownx.highlight: + anchor_linenums: true + - toc: + permalink: true + +nav: + - Home: index.md + - Installation: installation.md + - Agents: agents.md + - Commands: commands.md + - Pets: pets.md + - Architecture: architecture.md + - Contributing: contributing.md