Back to the catalog

llm-wiki — action_menu knowledge bundle

Bundle OKF 1.0 · 7 conceitos · olispeedy/kitty-action-menu

Open source Repository Open in the app JSON README (API)

About

# llm-wiki — action_menu knowledge bundle

An [Open Knowledge Format](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
bundle of curated knowledge about the `action_menu` kitty kitten: how it's built,
the kitty-API gotchas learned the hard way, reusable playbooks, and the reasoning
behind past decisions. Written to be useful to both humans and coding agents.

For behavioral rules on _how to work in this repo_, see
[`/AGENTS.md`](/AGENTS.md). This bundle holds the _why_ and the _experience_.

## Kitten

- [action_menu architecture](/llm-wiki/kitten/architecture.md) - how the kitten is split across the overlay UI and the boss process.

## Gotchas

- [State is not available at menu-draw time](/llm-wiki/gotchas/state-at-draw-time.md) - why context-aware entry greying can't be done reliably.
- [Bundled Python has no pip packages](/llm-wiki/gotchas/bundled-python-no-pip.md) - use kitty's own APIs, not PyPI (the wcwidth lesson).
- [allow_remote_control adds a cr

Details

Kind
OKF bundles
Topic
AI, RAG & memory
Publisher
olispeedy
Origin
okf_github
Category
dados
Version
1.0
Stars
1
Last push
2026-07-27T08:19:57Z
Repository state
ativo
Language
Python
License
GPL-3.0
Added
2026-09-08 22:08:51
Updated
2026-09-08 22:08:51
Origin id
olispeedy/kitty-action-menu:llm-wiki/index.md

README

# kitty-action-menu

[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](LICENSE)
![Platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS-lightgrey.svg)
![kitty](https://img.shields.io/badge/kitty-terminal-black.svg)
![Python](https://img.shields.io/badge/python-3.x-3776ab.svg)
[![GitHub stars](https://img.shields.io/github/stars/olispeedy/kitty-action-menu?style=flat)](https://github.com/olispeedy/kitty-action-menu/stargazers)
[![GitHub issues](https://img.shields.io/github/issues/olispeedy/kitty-action-menu)](https://github.com/olispeedy/kitty-action-menu/issues)
[![Last commit](https://img.shields.io/github/last-commit/olispeedy/kitty-action-menu)](https://github.com/olispeedy/kitty-action-menu/commits/main)

A pop-up action menu kitten for the [kitty terminal emulator](https://github.com/kovidgoyal/kitty).
It shows an overlay list of handy actions — copy selection, copy link/path,
paste, new tab, split, close — driven entirely by kitty's kitten API. It can be
opened by a right-click, but just as well by a keyboard shortcut or any other
kitty mapping.

<img src="assets/action_menu.png" alt="The action menu rendered in kitty" width="420">

## Motivation

Other graphical terminals — [Konsole](https://konsole.kde.org/),
[GNOME Terminal](https://help.gnome.org/users/gnome-terminal/stable/), and
[Windows Terminal](https://github.com/microsoft/terminal), etc. — pop up a
context menu on right-click. Coming to kitty, that familiar gesture was
missing. A _true_ context-sensitive menu (entries that change depending on what
is under the cursor) turns out to be tricky in kitty, but having a small set of
useful default actions one click (or keypress) away is already a nice
quality-of-life win.

So this kitten is deliberately **not** dynamic: it isn't a real context menu, it
just _looks_ a bit like one. The entries are a fixed list of the actions I found
useful for myself. It's easy to edit that list (see the `MENU` table in
`config/user/action_menu.py`) to fit your own workflow.

## Install

Copy the kitten into your kitty config directory:

```sh
cp config/user/action_menu.py ~/.config/kitty/action_menu.py
```

Then bind right-click in `~/.config/kitty/kitty.conf`:

```conf
mouse_map right press ungrabbed kitten action_menu.py
```

Reload the config (`ctrl+shift+f5` on Linux, `cmd+ctrl+,` on macOS) and
right-click in a window.

To troubleshoot, append the optional `--debug-action-menu` flag to the binding
(see [Testing & debugging](#testing--debugging)).

## Requirements

- [kitty](https://github.com/kovidgoyal/kitty) (uses its bundled Python and kitten API)

## Testing & debugging

The kitten accepts an optional `--debug-action-menu` flag that makes it emit
trace output. Add it to your binding while troubleshooting:

```conf
mouse_map right press ungrabbed kitten action_menu.py --debug-action-menu
```

To see that output you have to launch kitty **from another terminal**, so its
stdout/stderr is visible:

```sh
# from any other terminal (e.g. macOS Terminal.app, or another kitty window)
kitty
```

Then right-click in the new kitty window and pick menu entries. You'll see
lines like:

```
debug[actionmenu]: --- Kitten action_menu started ---
debug[actionmenu]: Args: ['action_menu.py', '--debug-action-menu']
debug[actionmenu]: on_mouse_event(): type=EventType.PRESS buttons=1 cell=(13,4) pixel=(109,77)
debug[actionmenu]: on_mouse_event(): type=EventType.RELEASE buttons=1 cell=(13,4) pixel=(109,77)
print[actionmenu]: handle_result: answer=3 target=1, dbg_enabled: False, forced: True
print[actionmenu]: menu entry: Paste from Clipboard (paste_clip), dbg_enabled: False, forced: True
print[actionmenu]: sel_before='' selection_nonempty=False, dbg_enabled: False, forced: True
print[actionmenu]: schedule_remote(): called ('action', '--match=id:1', 'paste_from_clipboard'), dbg_enabled: False, forced: True
```

Reading the output:

- `debug[actionmenu]:` — messages routed through kitty's `debug()` (UI/event
  logic inside the overlay).
- `print[actionmenu]:` — messages forced to stdout (`force_print=True`), used in
  `handle_result` and scheduled callbacks so they show up even when a launcher
  swallows `debug()`.
- `on_mouse_event()` lines show the raw event `type`, `buttons` bitmask, and the
  `cell`/`pixel` coordinates of the click — useful for diagnosing hit-testing.
- `handle_result: answer=N` is the 0-based index of the chosen `MENU` entry;
  `answer=8` here is _Cancel_.
- `sel_before=` / `selection_nonempty=` shows the active selection captured
  before the action ran (relevant for _Copy Selection_).
- `schedule_remote(): called (...)` / `combined action:` shows the actual kitty
  remote-control call or `boss.combine(...)` invocation dispatched for the entry.

Tips:

- If nothing appears, confirm the binding actually passes `--debug-action-menu`
  and that you launched kitty from a terminal (not via the app icon).
- A `WARNING: ... glCopyImageSubData` line from kitty is unrelated to this
  kitten — it's a GPU/OpenGL notice and can be ignored.
- `tests/test_mouse.py` is a standalone kitten that just echoes raw mouse/key
  events — handy for checking coordinates and event types in isolation. Bind it
  to a key in `kitty.conf` to run it (it can't be launched from a `mouse_map`),
  then press the key and click around; Esc quits:

  ```conf
  map kitty_mod+t kitten tests/test_mouse.py
  ```

  (`kitty_mod` defaults to `ctrl+shift` unless you've changed it.)

## Documentation

In-depth design notes, kitty-API gotchas, and how-tos live in the
[**`llm-wiki/`**](llm-wiki/index.md) knowledge bundle — an
[Open Knowledge Format](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
corpus written to be useful to both humans and coding agents. It renders here on
GitHub (mermaid diagrams included).

## Repository layout

| Path                         | Purpose                                               |
| ---------------------------- | ----------------------------------------------------- |
| `config/user/action_menu.py` | The kitten (mirrors the `~/.config/kitty/` layout)    |
| `llm-wiki/`                  | OKF knowledge bundle: design, gotchas, how-tos        |
| `tests/`                     | Standalone kittens for probing mouse/key events       |
| `assets/`                    | Screenshots and other media                           |
| `.archive/`                  | Earlier AI-generated code/doc variants, for reference |
| `AGENTS.md`                  | Instructions for AI agents working on this repo       |

## Ideas / roadmap

- **User-configurable menu entries.** Right now the `MENU` list is hard-coded in
  `action_menu.py`. It would be nicer to define entries in a config file (or in
  `kitty.conf`) so users don't have to edit the source. A more ambitious version
  would let you _build_ the menu interactively — pick which actions to include
  from a chooser, similar to kitty's built-in **command palette** kitten
  (`kitten @ ...` / the `show_command_palette` action) — and persist the
  selection.
- **Per-entry enable/disable based on state** (e.g. grey out _Copy Selection_
  when there is no selection). This was attempted but **doesn't work reliably**:
  the menu is drawn in a separate overlay process before an action is chosen, and
  trustworthy selection / link / path state is only available later in
  `handle_result()`. The renderer supports a `disabled` flag, but there's no
  dependable way to compute it at draw time — see
  [the llm-wiki gotcha](llm-wiki/gotchas/state-at-draw-time.md) for the details. It would likely need upstream kitty support to pass the
  click-target window state into the kitten.

## A note on AI assistance

This kitten was developed with the help of AI coding assistants, but every
feature was **tested by hand** in a real kitty session before being committed.
The AI-generated variants that didn't make the cut are kept in
[`.archive/`](.archive/) for reference.

## License

GPL v3. See [LICENSE](LICENSE).

More