Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "paws"
version = "0.3.1"
version = "0.4.0"
edition = "2021"

[dependencies]
Expand Down
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ English | [中文](README.zh.md)

# 🐾 Paws

[![CI](https://github.com/interesting-vibe-coding/paws/actions/workflows/ci.yml/badge.svg)](https://github.com/interesting-vibe-coding/paws/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Works with Kaku, WezTerm & iTerm2](https://img.shields.io/badge/Works_with-Kaku_%7C_WezTerm_%7C_iTerm2-blue)](https://github.com/interesting-vibe-coding/paws/blob/main/docs/iterm2-setup.md) [![Made with Lua & Rust](https://img.shields.io/badge/Made_with-Lua_&_Rust-orange)]() [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/interesting-vibe-coding/paws/pulls) [![GitHub Stars](https://img.shields.io/github/stars/interesting-vibe-coding/paws?style=flat&color=yellow)](https://github.com/interesting-vibe-coding/paws/stargazers)
[![CI](https://github.com/interesting-vibe-coding/paws/actions/workflows/ci.yml/badge.svg)](https://github.com/interesting-vibe-coding/paws/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Works with Kaku, WezTerm, iTerm2 & tmux](https://img.shields.io/badge/Works_with-Kaku_%7C_WezTerm_%7C_iTerm2_%7C_tmux-blue)](https://github.com/interesting-vibe-coding/paws#install) [![Made with Lua & Rust](https://img.shields.io/badge/Made_with-Lua_&_Rust-orange)]() [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/interesting-vibe-coding/paws/pulls) [![GitHub Stars](https://img.shields.io/github/stars/interesting-vibe-coding/paws?style=flat&color=yellow)](https://github.com/interesting-vibe-coding/paws/stargazers)

Play games while your AI agent works. A status HUD tells you when to come back.

Expand Down Expand Up @@ -53,7 +53,8 @@ cargo install --git https://github.com/interesting-vibe-coding/paws-games --bin
Then wire the terminal integration and hooks for your agent (see [`hooks/`](hooks/) for reference configs).
- **Kaku:** add [`lua/paws.lua`](lua/paws.lua) to `~/.config/kaku/kaku.lua` before `return config` — reload with CMD+Shift+R
- **WezTerm:** add [`lua/paws.lua`](lua/paws.lua) to `~/.config/wezterm/wezterm.lua` — auto-reloads on save
- **iTerm2:** copy [`iterm2/paws.py`](iterm2/paws.py) to `~/.config/iterm2/scripts/AutoLaunch/` and bind 3 keys — see [docs/iterm2-setup.md](docs/iterm2-setup.md)
- **iTerm2:** copy [`iterm2/paws.py`](iterm2/paws.py) to `~/.config/iterm2/scripts/AutoLaunch/` and bind 3 keys — see [setup guide](docs/iterm2-setup.md)
- **tmux:** copy [`tmux/`](tmux/) scripts to `~/.config/paws/` and add 2 lines to `~/.tmux.conf` — see [setup guide](docs/tmux-setup.md)

## Games

Expand All @@ -65,9 +66,18 @@ Then wire the terminal integration and hooks for your agent (see [`hooks/`](hook

Don't see enough? Open **⤓ Install games** in the picker to browse the catalog and install more in place. The catalog is the [paws-games](https://github.com/interesting-vibe-coding/paws-games) plugin library — anyone can contribute a game.

## Terminals

| Terminal | Integration | Keys |
|----------|-------------|------|
| [Kaku](https://github.com/tw93/kaku) | `lua/paws.lua` → Lua config | CMD+G / CMD+SHIFT+P |
| [WezTerm](https://wezfurlong.org/wezterm/) | `lua/paws.lua` → Lua config | CMD+G / CMD+SHIFT+P |
| [iTerm2](https://iterm2.com) | `iterm2/paws.py` → AutoLaunch script | CMD+G / CMD+SHIFT+P — [setup](docs/iterm2-setup.md) |
| tmux | `tmux/*.sh` → shell scripts | Prefix+g / Prefix+G — [setup](docs/tmux-setup.md) |

## How it works

Agent hooks write session state to `/tmp/paws-sessions/` → Kaku Lua handles CMD+G (spawns/toggles a tab) → the `paws` host runs the chosen game in a PTY and renders the HUD on the top row. Games are standalone binaries discovered via a [registry](registry.toml).
Agent hooks write session state to `/tmp/paws-sessions/` → the terminal integration handles the key binding (spawns/toggles a window) → the `paws` host runs the chosen game in a PTY and renders the HUD on the top row. Games are standalone binaries discovered via a [registry](registry.toml).

For architecture details, see [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).

Expand Down
5 changes: 3 additions & 2 deletions README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# 🐾 Paws

[![CI](https://github.com/interesting-vibe-coding/paws/actions/workflows/ci.yml/badge.svg)](https://github.com/interesting-vibe-coding/paws/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Works with Kaku, WezTerm & iTerm2](https://img.shields.io/badge/Works_with-Kaku_%7C_WezTerm_%7C_iTerm2-blue)](https://github.com/interesting-vibe-coding/paws/blob/main/docs/iterm2-setup.md) [![Made with Lua & Rust](https://img.shields.io/badge/Made_with-Lua_&_Rust-orange)]() [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/interesting-vibe-coding/paws/pulls) [![GitHub Stars](https://img.shields.io/github/stars/interesting-vibe-coding/paws?style=flat&color=yellow)](https://github.com/interesting-vibe-coding/paws/stargazers)
[![CI](https://github.com/interesting-vibe-coding/paws/actions/workflows/ci.yml/badge.svg)](https://github.com/interesting-vibe-coding/paws/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Works with Kaku, WezTerm, iTerm2 & tmux](https://img.shields.io/badge/Works_with-Kaku_%7C_WezTerm_%7C_iTerm2_%7C_tmux-blue)](https://github.com/interesting-vibe-coding/paws#install) [![Made with Lua & Rust](https://img.shields.io/badge/Made_with-Lua_&_Rust-orange)]() [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/interesting-vibe-coding/paws/pulls) [![GitHub Stars](https://img.shields.io/github/stars/interesting-vibe-coding/paws?style=flat&color=yellow)](https://github.com/interesting-vibe-coding/paws/stargazers)

Agent 工作时尽情玩,需要你时一眼就看到。

Expand Down Expand Up @@ -53,7 +53,8 @@ cargo install --git https://github.com/interesting-vibe-coding/paws-games --bin
然后配置终端集成,并为你的 Agent 配置 hooks(参考 [`hooks/`](hooks/) 目录)。
- **Kaku:** 将 [`lua/paws.lua`](lua/paws.lua) 添加到 `~/.config/kaku/kaku.lua` 的 `return config` 之前 — 重载需按 CMD+Shift+R
- **WezTerm:** 将 [`lua/paws.lua`](lua/paws.lua) 添加到 `~/.config/wezterm/wezterm.lua` — 保存后自动重载
- **iTerm2:** 将 [`iterm2/paws.py`](iterm2/paws.py) 复制到 `~/.config/iterm2/scripts/AutoLaunch/`,然后绑定 3 个快捷键 — 详见 [docs/iterm2-setup.md](docs/iterm2-setup.md)
- **iTerm2:** 将 [`iterm2/paws.py`](iterm2/paws.py) 复制到 `~/.config/iterm2/scripts/AutoLaunch/`,绑定 3 个快捷键 — 详见[安装指南](docs/iterm2-setup.md)
- **tmux:** 将 [`tmux/`](tmux/) 脚本复制到 `~/.config/paws/`,在 `~/.tmux.conf` 加 2 行 — 详见[安装指南](docs/tmux-setup.md)

## 游戏

Expand Down
78 changes: 78 additions & 0 deletions docs/tmux-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Paws × tmux setup

Paws works in any terminal that runs tmux. The integration is two shell scripts
that handle the window-create/toggle behavior — no dependencies beyond tmux itself.

## What you get

| Key | Action |
|-----|--------|
| **Prefix+g** | First press: open the game picker in a new window. After that: toggle agent ↔ game. |
| **Prefix+G** | Close the game window and re-open the picker. |

> **Prefix** is `Ctrl+B` by default. If you've rebound it, use your custom prefix.

## Install

### 1. Copy the scripts

```bash
mkdir -p ~/.config/paws
cp tmux/paws-toggle.sh ~/.config/paws/tmux-toggle.sh
cp tmux/paws-picker.sh ~/.config/paws/tmux-picker.sh
cp tmux/paws.conf ~/.config/paws/paws.conf
chmod +x ~/.config/paws/tmux-toggle.sh ~/.config/paws/tmux-picker.sh
```

### 2. Add keybindings to your tmux config

**Option A — source the provided config file:**

```bash
echo 'source-file ~/.config/paws/paws.conf' >> ~/.tmux.conf
```

**Option B — copy the two lines directly into `~/.tmux.conf`:**

```
bind-key g run-shell "$HOME/.config/paws/tmux-toggle.sh"
bind-key G run-shell "$HOME/.config/paws/tmux-picker.sh"
```

### 3. Reload tmux config

```bash
tmux source-file ~/.tmux.conf
```

Or press `Prefix+:` and type `source-file ~/.tmux.conf`.

### 4. Done

Press **Prefix+g** — the game picker opens in a new tmux window named `paws`.
The HUD on the top row shows your agent sessions. Press **Prefix+g** again to
toggle back to your previous window.

## How it works

`tmux-toggle.sh` queries the current window list with `tmux list-windows` to
find a window named `paws`. If one doesn't exist it spawns a new window running
`paws` via a login shell (so `~/.cargo/bin` is on PATH). If you're already on
the paws window it calls `tmux last-window` to jump back. Otherwise it switches
to the paws window.

No external state file — tmux's own window list is the source of truth.

## Troubleshooting

**`paws: command not found`**
The scripts use a login shell (`$SHELL -l`) so `~/.cargo/bin` should be on
PATH. If it's still missing, run `cargo install --path .` from the paws repo
and try again.

**Prefix+g conflicts with an existing binding**
Change `g` / `G` to any free key in `paws.conf` (or the lines in `~/.tmux.conf`).

**Game opens in a small pane instead of full window**
Make sure you're not inside a split pane when pressing Prefix+g. The script
creates a new *window* (full screen), not a pane split.
29 changes: 26 additions & 3 deletions skills/paws-install/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ You are installing Paws for the user. Work from a local clone of this repo
## 0. Preconditions

- Confirm the terminal is **Kaku** (`which kaku`), **WezTerm** (`which wezterm`),
or **iTerm2** (`ls /Applications/iTerm.app`). All three are supported.
If none is installed, ask the user to install one first and stop.
**iTerm2** (`ls /Applications/iTerm.app`), or **tmux** (`which tmux`). All four
are supported. If none is installed, ask the user to install one first and stop.
- Determine the terminal type — it affects Step 2:
- Kaku: `~/.config/kaku/kaku.lua` (Lua config)
- WezTerm: `~/.config/wezterm/wezterm.lua` (Lua config)
- iTerm2: Python script + manual key bindings (see Step 2b)
- iTerm2: Python AutoLaunch script + manual key bindings (see Step 2b)
- tmux: two shell scripts + two lines in `~/.tmux.conf` (see Step 2c)
- Note the repo root (absolute path) — you'll need it for hook paths.
**All hook paths in config files must be absolute** — `~` is not expanded
by any of the three agents.
Expand Down Expand Up @@ -84,6 +85,28 @@ Then tell the user to:

Full details: [docs/iterm2-setup.md](../../docs/iterm2-setup.md)

## 2c. Install the tmux scripts (tmux only)

Skip this step if the user is on Kaku, WezTerm, or iTerm2.

```bash
mkdir -p ~/.config/paws
cp <REPO>/tmux/paws-toggle.sh ~/.config/paws/tmux-toggle.sh
cp <REPO>/tmux/paws-picker.sh ~/.config/paws/tmux-picker.sh
cp <REPO>/tmux/paws.conf ~/.config/paws/paws.conf
chmod +x ~/.config/paws/tmux-toggle.sh ~/.config/paws/tmux-picker.sh
```

Add to `~/.tmux.conf`:
```
source-file ~/.config/paws/paws.conf
```

Then reload: `tmux source-file ~/.tmux.conf`

Keybindings: **Prefix+g** (toggle), **Prefix+G** (reopen picker).
Full details: [docs/tmux-setup.md](../../docs/tmux-setup.md)

## 3. Wire the agent's state signals (for the status HUD)

Paws ships two hook scripts that write session state to `/tmp/paws-sessions/<id>`
Expand Down
13 changes: 13 additions & 0 deletions tmux/paws-picker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# Paws 🐾 tmux picker — close the game window and reopen the picker.
# Bind to your prefix key:
# bind-key P run-shell "~/.config/paws/tmux-picker.sh"

PAWS_WIN=$(tmux list-windows -F '#{window_index}:#{window_name}' \
| awk -F: '$2=="paws"{print $1}')

if [ -n "$PAWS_WIN" ]; then
tmux kill-window -t "$PAWS_WIN"
fi

tmux new-window -n paws "${SHELL:-/bin/zsh} -l -c paws"
21 changes: 21 additions & 0 deletions tmux/paws-toggle.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash
# Paws 🐾 tmux toggle — bind to your prefix key:
# bind-key g run-shell "~/.config/paws/tmux-toggle.sh"
#
# Press Prefix+g:
# - No paws window exists → create one and switch to it
# - Already on the paws window → jump back to previous window
# - On another window → switch to the paws window

PAWS_WIN=$(tmux list-windows -F '#{window_index}:#{window_name}' \
| awk -F: '$2=="paws"{print $1}')
CURRENT=$(tmux display-message -p '#{window_name}')

if [ -z "$PAWS_WIN" ]; then
# Spawn a new login-shell window so ~/.cargo/bin is on PATH
tmux new-window -n paws "${SHELL:-/bin/zsh} -l -c paws"
elif [ "$CURRENT" = "paws" ]; then
tmux last-window
else
tmux select-window -t "$PAWS_WIN"
fi
12 changes: 12 additions & 0 deletions tmux/paws.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Paws 🐾 tmux keybindings
# Source this from your ~/.tmux.conf:
# source-file ~/.config/paws/paws.conf
#
# Or copy these lines directly into your ~/.tmux.conf.
# Replace $HOME with the absolute path to your home directory if needed.

# Prefix+g — open game picker / toggle between agent and game
bind-key g run-shell "$HOME/.config/paws/tmux-toggle.sh"

# Prefix+G — close the game window and reopen the picker
bind-key G run-shell "$HOME/.config/paws/tmux-picker.sh"
Loading