diff --git a/Formula/README.md b/Formula/README.md index da06024..b316193 100644 --- a/Formula/README.md +++ b/Formula/README.md @@ -29,12 +29,14 @@ inside `Formula/` in that tap repo. 1. **Create the tap repo** — `interesting-vibe-coding/homebrew-paws` on GitHub. Copy `paws.rb` and `paws-games.rb` into its `Formula/` directory. -2. **Tag releases** — create a `v0.3.0` tag in both repos: - - `interesting-vibe-coding/paws` - - `interesting-vibe-coding/paws-games` -3. **Fill in sha256** — download each tarball and run `shasum -a 256 `, - then paste the hash into the corresponding formula's `sha256` field. -4. **Push the tap repo** — once formulae have valid sha256 values, the stable - `brew install paws` path is live. +2. **Tags** — `v0.3.1` has been created in `interesting-vibe-coding/paws`. + The release workflow (`.github/workflows/release.yml`) triggers on `v*` tag + pushes and will produce pre-built binaries attached to the GitHub Release. + `paws-games` still needs its own tag once that repo is ready. +3. **sha256** — both formulae already have sha256 values filled in. + If the release workflow rebuilds and re-uploads tarballs the hashes may need + to be re-verified with `shasum -a 256 `. +4. **Push the tap repo** — once the tap repo exists and formulae are copied in, + the stable `brew install paws` path is live. Until steps 1–4 are done, only `--HEAD` installs work. diff --git a/README.md b/README.md index 0525ce9..ba8a106 100644 --- a/README.md +++ b/README.md @@ -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) [![Built for Kaku](https://img.shields.io/badge/Built_for-Kaku-blue)](https://github.com/tw93/kaku) [![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](https://img.shields.io/badge/Works_with-Kaku_%26_WezTerm-blue)](https://wezfurlong.org/wezterm/) [![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. @@ -50,7 +50,9 @@ cargo install --git https://github.com/interesting-vibe-coding/paws-games --bin cargo install --git https://github.com/interesting-vibe-coding/paws-games --bin tetris ``` -Then add [`lua/paws.lua`](lua/paws.lua) to your `~/.config/kaku/kaku.lua` (before `return config`) and wire hooks for your agent (see [`hooks/`](hooks/) for reference configs). Reload Kaku (CMD+Shift+R). +Then add [`lua/paws.lua`](lua/paws.lua) to your terminal config (before `return config`) and wire hooks for your agent (see [`hooks/`](hooks/) for reference configs). +- **Kaku:** `~/.config/kaku/kaku.lua` — reload with CMD+Shift+R +- **WezTerm:** `~/.config/wezterm/wezterm.lua` — auto-reloads on save ## Games diff --git a/README.zh.md b/README.zh.md index 2dc4da5..954a725 100644 --- a/README.zh.md +++ b/README.zh.md @@ -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) [![Built for Kaku](https://img.shields.io/badge/Built_for-Kaku-blue)](https://github.com/tw93/kaku) [![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](https://img.shields.io/badge/Works_with-Kaku_%26_WezTerm-blue)](https://wezfurlong.org/wezterm/) [![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 工作时尽情玩,需要你时一眼就看到。 @@ -50,7 +50,9 @@ cargo install --git https://github.com/interesting-vibe-coding/paws-games --bin cargo install --git https://github.com/interesting-vibe-coding/paws-games --bin tetris ``` -然后将 [`lua/paws.lua`](lua/paws.lua) 添加到 `~/.config/kaku/kaku.lua`(`return config` 之前),并为你的 Agent 配置 hooks(参考 [`hooks/`](hooks/) 目录)。重载 Kaku(CMD+Shift+R)。 +然后将 [`lua/paws.lua`](lua/paws.lua) 添加到终端配置中(`return config` 之前),并为你的 Agent 配置 hooks(参考 [`hooks/`](hooks/) 目录)。 +- **Kaku:** `~/.config/kaku/kaku.lua` — 重载需按 CMD+Shift+R +- **WezTerm:** `~/.config/wezterm/wezterm.lua` — 保存后自动重载 ## 游戏 diff --git a/docs/kaku-notes.md b/docs/kaku-notes.md index cd497a6..f052ebc 100644 --- a/docs/kaku-notes.md +++ b/docs/kaku-notes.md @@ -1,8 +1,22 @@ -# Kaku integration notes +# Kaku & WezTerm integration notes -Hard-won facts about Kaku (a WezTerm fork) relevant to Paws. Read before touching +Hard-won facts about Kaku and WezTerm relevant to Paws. Read before touching the Lua, to avoid re-discovering these. +## WezTerm compatibility + +`lua/paws.lua` uses only **standard WezTerm Lua APIs** — every call +(`wezterm.mux`, `wezterm.GLOBAL`, `wezterm.action_callback`, `window:mux_window():spawn_tab`, etc.) +works identically in WezTerm. No code changes are needed. + +| Difference | Kaku | WezTerm | +|-----------|------|---------| +| Config path | `~/.config/kaku/kaku.lua` | `~/.config/wezterm/wezterm.lua` | +| Auto-reload on save | ✗ — must press **CMD+Shift+R** | ✓ automatic | +| CMD+SHIFT+G | Taken (lazygit) | Free — but Paws uses CMD+G anyway | + +The WezTerm install is identical to Kaku: paste `lua/paws.lua` into your config before `return config`. + ## Keybindings - **No auto-reload.** Kaku does not reload `kaku.lua` on save. Press **CMD+Shift+R** after every edit, or changes won't take effect. diff --git a/lua/paws.lua b/lua/paws.lua index 063fbfe..9b40aad 100644 --- a/lua/paws.lua +++ b/lua/paws.lua @@ -1,5 +1,6 @@ --- Paws 🐾 — native Kaku/WezTerm integration. --- Add this to ~/.config/kaku/kaku.lua (before `return config`). +-- Paws 🐾 — native Kaku / WezTerm integration. +-- Add this to ~/.config/kaku/kaku.lua (Kaku) or ~/.config/wezterm/wezterm.lua (WezTerm), +-- before `return config`. No code changes needed — all APIs are standard WezTerm. -- Everything runs in-process: no external scripts, no temp files, no `kaku cli`. -- -- The game lives in its OWN TAB (full-window, never disturbs your panes). diff --git a/skills/paws-install/SKILL.md b/skills/paws-install/SKILL.md index a431963..56d5bbe 100644 --- a/skills/paws-install/SKILL.md +++ b/skills/paws-install/SKILL.md @@ -1,6 +1,6 @@ --- name: paws-install -description: Install Paws 🐾 (terminal companion for AI coding agents) into the user's Kaku terminal and their agent (Kiro CLI, Claude Code, or Codex CLI). Use this when the user asks to install, set up, or wire up Paws. Performs the Kaku Lua merge, game install, and agent hook wiring — all idempotently. +description: Install Paws 🐾 (terminal companion for AI coding agents) into the user's Kaku or WezTerm terminal and their agent (Kiro CLI, Claude Code, or Codex CLI). Use this when the user asks to install, set up, or wire up Paws. Performs the Lua merge, game install, and agent hook wiring — all idempotently. --- # Installing Paws 🐾 @@ -11,8 +11,12 @@ You are installing Paws for the user. Work from a local clone of this repo ## 0. Preconditions -- Confirm the terminal is **Kaku** (`which kaku`). If not, tell the user Paws - currently requires Kaku and stop. +- Confirm the terminal is **Kaku** (`which kaku`) or **WezTerm** (`which wezterm`). + Both are supported — the same `lua/paws.lua` works in both without modification. + If neither is installed, ask the user to install one first and stop. +- Determine the terminal type — it affects the config path in Step 2: + - Kaku: `~/.config/kaku/kaku.lua` + - WezTerm: `~/.config/wezterm/wezterm.lua` - 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. @@ -44,18 +48,22 @@ Any games not installed now can be installed later directly from the in-app game picker (uninstalled entries show "⤓ install" and run the install command on Enter). -## 2. Merge the Lua into the Kaku config +## 2. Merge the Lua into the terminal config -The Kaku config is `~/.config/kaku/kaku.lua` (it returns a `config` table at the -end). The snippet to insert is `lua/paws.lua` from this repo. +The terminal config returns a `config` table at the end. The snippet to insert is +`lua/paws.lua` from this repo — it works identically in Kaku and WezTerm. -- If `kaku.lua` already contains `Paws 🐾` (the marker comment), skip — already installed. +- **Kaku:** config is at `~/.config/kaku/kaku.lua` +- **WezTerm:** config is at `~/.config/wezterm/wezterm.lua` + +Steps: +- If the config already contains `Paws 🐾` (the marker comment), skip — already installed. - Otherwise insert the **body** of `lua/paws.lua` (everything except its `local wezterm = require 'wezterm'` line, which the config already has) **immediately before** the final `return config` line. - Ensure `config.keys` exists before the insert: if the config never sets it, add `config.keys = config.keys or {}` at the top of the inserted block. -- Syntax-check afterward: `luac -p ~/.config/kaku/kaku.lua` (if `luac` exists). +- Syntax-check afterward: `luac -p ` (if `luac` exists). ## 3. Wire the agent's state signals (for the status HUD) @@ -192,16 +200,19 @@ chmod +x /hooks/kiro/paws-pause.sh ## 5. Finish -Tell the user to **reload Kaku (CMD+Shift+R)** — Kaku does NOT auto-reload — then: +- **Kaku users:** Press **CMD+Shift+R** to reload — Kaku does NOT auto-reload on save. +- **WezTerm users:** Config reloads automatically on save — no action needed. + +Then: - **CMD+G** — opens the game tab (a centered menu: games · 🎲 Random · ⚙ Settings); after that it toggles agent ↔ game. - **CMD+SHIFT+P** — close the game tab and re-open the menu. - **CMD+H** — open the Paws repo in your browser (to file an issue / say hi). -(Don't use CMD+SHIFT+G — Kaku already binds it to lazygit.) +(Kaku users: don't use CMD+SHIFT+G — Kaku already binds it to lazygit.) ## Verify -- `luac -p ~/.config/kaku/kaku.lua` passes (if luac is available). +- `luac -p ` passes (if luac is available). - `paws --list` shows at least one installed game. - The hook paths in the agent config are absolute and the scripts are executable. - Quick smoke test (Claude Code / Codex): pipe mock JSON to the hook and check diff --git a/src/main.rs b/src/main.rs index 874b600..08e3309 100644 --- a/src/main.rs +++ b/src/main.rs @@ -340,37 +340,36 @@ fn pick_game_menu(games: &[Game]) -> io::Result> { install_sel = (install_sel + 1) % games.len(); } KeyCode::Esc | KeyCode::Char('q') => screen = Screen::Menu, - KeyCode::Enter | KeyCode::Char(' ') => { - if !installed[install_sel] { - let game = &games[install_sel]; - disable_raw_mode()?; - io::stdout().execute(LeaveAlternateScreen)?; - - println!("\n Installing {}…", game.name); - println!(" $ {}\n", game.install); - - let status = std::process::Command::new("sh") - .arg("-c") - .arg(&game.install) - .status(); - - match status { - Ok(s) if s.success() => println!("\n ✓ {} installed!", game.name), - Ok(s) => { - println!("\n ✗ Install failed (exit {})", s.code().unwrap_or(-1)) - } - Err(e) => println!("\n ✗ Install error: {e}"), + KeyCode::Enter | KeyCode::Char(' ') if !installed[install_sel] => { + let game = &games[install_sel]; + disable_raw_mode()?; + io::stdout().execute(LeaveAlternateScreen)?; + + println!("\n Installing {}…", game.name); + println!(" $ {}\n", game.install); + + let status = std::process::Command::new("sh") + .arg("-c") + .arg(&game.install) + .status(); + + match status { + Ok(s) if s.success() => println!("\n ✓ {} installed!", game.name), + Ok(s) => { + println!("\n ✗ Install failed (exit {})", s.code().unwrap_or(-1)) } - print!(" Press Enter to continue…"); - let _ = io::stdout().flush(); - let _ = io::stdin().lock().read_line(&mut String::new()); - - enable_raw_mode()?; - io::stdout().execute(EnterAlternateScreen)?; - terminal = Terminal::new(CrosstermBackend::new(io::stdout()))?; - installed = games.iter().map(|g| is_installed(&g.cmd)).collect(); + Err(e) => println!("\n ✗ Install error: {e}"), } + print!(" Press Enter to continue…"); + let _ = io::stdout().flush(); + let _ = io::stdin().lock().read_line(&mut String::new()); + + enable_raw_mode()?; + io::stdout().execute(EnterAlternateScreen)?; + terminal = Terminal::new(CrosstermBackend::new(io::stdout()))?; + installed = games.iter().map(|g| is_installed(&g.cmd)).collect(); } + KeyCode::Enter | KeyCode::Char(' ') => {} _ => {} }, Screen::Menu => match key.code {