# The Missing Manual on Omarchy

> Install The Missing Manual's own Omarchy plugin and read the whole library from your keyboard-first desktop: a reader window themed to your desktop, live search, quizzes, diagrams, an optional bring-your-own-key study chat, and a matching terminal client.


---

# The Missing Manual on Omarchy

You picked a desktop built around the keyboard, and then every question sends you to a browser tab, a mouse, and a different window. The Missing Manual has its own Omarchy plugin so the lookup can stay where you are: one keystroke opens the library in a window that takes its colors and fonts from your current theme, searches as you type, and opens phases you have already read even when the network is gone.

This guide installs it, teaches the keys, and says plainly what it stores and what it sends. Checked against Omarchy 4.0.4 and omarchy-tmm 0.5.0.

## Prerequisite

You need Omarchy 4 running and a terminal you can type commands into. If the terminal is new to you, read [The Terminal and Shell](/guides/the-terminal-and-shell) first. For the general picture of plugins, what they can reach and how to judge one, read [Omarchy Plugins and the Marketplace](/guides/omarchy-plugins-and-the-marketplace); this guide goes deep on one plugin instead.

## How to read this

- **In a hurry?** Do the install steps in Phase 1, then keep the key tables in Phase 2 open while you try it.
- **Careful about your data?** Go straight to "What leaves your machine" in Phase 4, and "Where your key lives" in Phase 3.
- **Want it to finally make sense?** Read in order. The mental model in Phase 1 explains why the keys in Phase 2 behave the way they do.

## The phases

1. **[What the Plugin Is and How to Install It](01-install-the-plugin.md)** - the three parts it is made of, what a marketplace listing does and does not promise, and the real commands to install, update, and remove it.
2. **[Your First Ten Minutes in the Reader](02-your-first-ten-minutes.md)** - searching, reading, quizzes, diagrams, asking questions, going offline, and the `tmm` terminal client.
3. **[Making It Yours: Themes, Hotkeys, and the Study Chat](03-making-it-yours-and-the-study-chat.md)** - theme, layout, your own hotkeys, and the bring-your-own-key study chat with exactly where your key is stored.
4. **[Where Your Data Goes, and Fixing It When It Breaks](04-where-your-data-goes-and-fixing-it.md)** - what each action sends, a symptom-to-fix card, and how to report a bug.

Building a plugin like this one is a separate skill, covered in [Building Your Own Omarchy Plugin](/guides/building-your-own-omarchy-plugin). If something on your desktop stops working and you are not sure why, [When Omarchy Breaks](/guides/when-omarchy-breaks) is the recovery guide.


---

# What the Plugin Is and How to Install It

Looking something up usually means leaving your desktop for a browser tab. The plugin keeps the lookup where you already are: a keystroke opens a window with the whole Missing Manual library in it. This phase covers what you are installing, how to install it without trusting it blindly, and how to take it back out cleanly.

## What you are installing

An Omarchy plugin is a folder with a `manifest.json`, a small file that tells the shell what the plugin is and where its code lives. The shell is `omarchy-shell`, the single long-running program that draws your bar, your menus, and your panels. This plugin's id is `tmm.manual`, and its manifest declares three kinds of plugin at once.

| Kind | What it is here |
|---|---|
| `panel` | The reader: a floating window titled "The Missing Manual" |
| `service` | A headless worker with no window. It makes the network requests, keeps the cache, remembers what you read, and talks to an AI provider if you set one up |
| `bar-widget` | The book button on your bar |

```mermaid
flowchart LR
  A["Bar button, hotkey, or menu row"] --> B["omarchy-shell"]
  B --> C["Reader window (panel)"]
  C --> D["Service (curl and cache)"]
  D --> E["themissingmanual.dev"]
```

The button, a hotkey, and a menu row all send the same kind of message to the shell, so all three open the same window. That is deliberate: the plugin's own code says the button, the keybinding, and the menu entries share one toggle path.

> 💡 **Key point.** The plugin is not a copy of the library on your disk. Each phase is fetched from themissingmanual.dev when you open it and saved in a cache (a folder of saved copies) so it can open again without the network. The plugin's README says it only reads from the library and never uploads anything; Phase 4 spells out exactly what each action sends.

Why a plugin instead of a browser tab? The README gives four reasons, and they are all about staying put. It is keyboard-first (you never need the mouse). It is themed, so its colors, fonts, and spacing follow your Omarchy theme. A phase you have read before still opens offline. And the same guides render in your terminal with a `tmm` command.

## Check your ground first

The plugin needs Omarchy 4 (its repo and the marketplace call this generation Quattro). The README says it is not compatible with Omarchy 3. It shells out to a few tools, so check they exist before you blame the plugin for anything:

```bash
command -v curl python3 wl-copy rsvg-convert
```

Each tool that is installed prints its path, and a missing one prints nothing. `curl` and `python3` are required. `wl-copy` is optional and powers click-to-copy. `rsvg-convert` is optional and draws diagrams; the README says Omarchy ships it, and Phase 4 covers what happens without it.

## What the marketplace listing tells you

The community marketplace at [plugins.omarchy.org](https://plugins.omarchy.org) is a directory you can search, and each plugin's card has a "Copy install command" button. The Omarchy manual points to it as the place to find and share plugins. The Missing Manual plugin is listed there, in the Developer Tools category, on [its own page](https://plugins.omarchy.org/plugin.html?id=tmm.manual).

For this plugin the copied command is:

```bash
omarchy plugin add https://github.com/Topurrra/omarchy-tmm.git --enable
```

Read it left to right. `omarchy plugin add` clones a git repository into `~/.config/omarchy/plugins/`, checks its manifest, and rescans the shell. `--enable` also turns it on; without that flag, Omarchy asks you first.

Here is the straight picture of what a listing promises. Omarchy's manual says plugins "run as arbitrary, unsandboxed code inside your long-lived shell process", which means with everything your user account can reach. The marketplace says it validates listings, not plugin security.

For this listing, the marketplace's registry records a review by a marketplace maintainer of one exact commit (21f23d8, the same commit the repository's `main` branch was on when this guide was written). The marketplace also says its install command clones the repository's current latest commit, so what you install can be newer than what was reviewed. That is why the careful install below is worth the two extra minutes. The general habit, and the review checklist, are in [Omarchy Plugins and the Marketplace](/guides/omarchy-plugins-and-the-marketplace).

## Install it, review first

Add it without `--enable`. Omarchy shows a warning and asks two yes-or-no questions (it uses a small terminal prompt tool called `gum`): whether to clone, and whether to enable now.

```console
$ omarchy plugin add https://github.com/Topurrra/omarchy-tmm.git

⚠️  Plugins run as arbitrary, unsandboxed code inside your long-lived
  omarchy-shell process. Only add repos you trust, and review the code
  before you enable it.

      URL: https://github.com/Topurrra/omarchy-tmm.git

...
Added tmm.manual into /home/you/.config/omarchy/plugins/tmm.manual
...
Enable it later with: omarchy plugin enable tmm.manual
```

*What just happened:* the lines marked `...` are the two yes-or-no questions and git's own clone messages. You answered yes to the clone and no to "enable now". Omarchy cloned the repository into a staging folder, validated the manifest, moved it to `~/.config/omarchy/plugins/tmm.manual/`, and told the shell to rescan. Nothing from the plugin has run yet.

Now read what you got. The manifest is short enough to read in full:

```json
{
  "schemaVersion": 1,
  "id": "tmm.manual",
  "name": "The Missing Manual",
  "version": "0.5.0",
  "author": "The Missing Manual",
  "license": "MIT",
  "description": "Search, browse and read The Missing Manual inside Omarchy, themed to your desktop",
  "kinds": [
    "panel",
    "service",
    "bar-widget"
  ],
  "keepLoaded": true,
  "entryPoints": {
    "panel": "Panel.qml",
    "service": "Service.qml",
    "barWidget": "BarWidget.qml"
  },
  "barWidget": {
    "displayName": "Missing Manual",
    "description": "Opens The Missing Manual",
    "category": "Launcher",
    "allowMultiple": false,
    "defaultSection": "right"
  }
}
```

The `kinds` and `entryPoints` are the three parts from the table. `"keepLoaded": true` tells the shell to keep the window loaded between openings, so state such as the reading theme you picked can survive closing and reopening the window. `defaultSection` asks for the right side of the bar.

Then look at the code that touches the outside world:

```bash
cd ~/.config/omarchy/plugins/tmm.manual
ls bin
grep -n "curl" Service.qml
```

`bin/` holds the helper scripts (`tmm`, `tmm-cap`, `tmm-diagrams`, `tmm-menu`, `tmm-cli-extract`), and they run as you, so skim them. `Service.qml` is the headless worker, and every address it talks to is built there. Per the README, `tmm-cap` runs each network request with a ceiling on reply size and run time.

When you are satisfied, enable it:

```console
$ omarchy plugin enable tmm.manual
Enabled tmm.manual
```

Omarchy keeps the enabled state in `~/.config/omarchy/shell.json`: a third-party plugin is on exactly when its id appears there. Confirm it, then open the window:

```console
$ omarchy plugin list | grep tmm.manual
tmm.manual                       enabled   third-party panel,service,bar-widget The Missing Manual
$ omarchy-shell shell summon tmm.manual
ok
```

*What just happened:* `summon` is a message to the running shell saying "open this plugin's window". It prints `ok` on success and `unknown` if the shell has no such plugin loaded. A book icon should now sit on the right of your bar, and clicking it toggles the window. If the icon is missing, place it yourself:

```bash
omarchy bar put tmm.manual --section right
```

> ⚠️ **Gotcha.** A disabled plugin answers a summon by doing nothing at all, which looks exactly like a broken install. If nothing happens, run `omarchy plugin list` and read the state column before you try anything else.

If you already reviewed the code and want one step, the marketplace command above does the clone and the enable together. In a terminal it also asks which bar section to use, with the right side preselected.

## Three extras that live outside the plugin folder

`omarchy plugin add` only puts files in the plugins folder. It never runs plugin code, install hooks, or `sudo`, so anything that lives elsewhere is opt-in. Set a shortcut for the folder first:

```bash
P=~/.config/omarchy/plugins/tmm.manual
```

**1. The `tmm` terminal command.** Copy the client onto your `PATH`:

```bash
mkdir -p ~/.local/bin
cp "$P"/bin/tmm ~/.local/bin/
chmod +x ~/.local/bin/tmm
```

**2. Rows in the Omarchy menu.** Omarchy reads one shared file, `~/.config/omarchy/extensions/omarchy-menu.jsonc`, for every menu entry you add. Copying a fragment over it would delete everything else in it, so the plugin ships a helper that merges instead:

```console
$ "$P"/bin/tmm-menu install
wrote /home/you/.config/omarchy/extensions/omarchy-menu.jsonc
  ours:  tmm, tmm.search, tmm.catalog, tmm.random, tmm.toggle
  other: none
Run: omarchy menu refresh
```

Then tell the menu to reload:

```bash
omarchy menu refresh
```

*What just happened:* `tmm-menu` added five entries, kept a `.bak` copy of your menu file beside it, and refused to write anything that would not parse. Open the Omarchy menu with `Super + Space` and you will find a "Missing Manual" row with Search Guides, Browse Catalog, Random Guide, and Toggle Manual under it. If you have other menu entries, they appear on the `other:` line and are left untouched.

> ⚠️ **Gotcha.** Run `tmm-menu` from the plugin folder as shown. INSTALL.md copies it into `~/.local/bin` and runs it from there, but in 0.5.0 a copy looks for its menu fragment next to itself, does not find it, and stops with `tmm-menu: fragment not found`. The `status` and `remove` actions do not need the fragment and work from anywhere.

**3. Hotkeys.** Omarchy's Hyprland config is Lua, and your personal bindings go in `~/.config/hypr/bindings.lua`. Add these three lines at the end of that file:

```lua
o.bind("SUPER + ALT + M", "Missing Manual", "omarchy-shell shell toggle tmm.manual")
o.bind("SUPER + ALT + B", "Missing Manual catalog", "omarchy-shell shell summon tmm.manual '{\"catalog\":true}'")
o.bind("SUPER + ALT + R", "Missing Manual random guide", "omarchy-shell shell summon tmm.manual '{\"random\":true}'")
```

These give you `Super + Alt + M` to open or close the window, `Super + Alt + B` to open on the catalog, and `Super + Alt + R` for a random guide. None of the three is bound in Omarchy 4.0.4's default bindings. Reload with `hyprctl reload` (the plugin's README uses this command), and run `omarchy menu keybindings --print` to see the bindings Omarchy knows about.

The `o` in those lines is a helper table that Omarchy defines before your config files load, which is why Omarchy's own `bindings.lua` template uses `o.bind(...)` with no setup line. The plugin ships a `bindings.lua.fragment` for these same three bindings, and in 0.5.0 it starts with `local o = require("default.hypr.helpers")`. On Omarchy 4.0.4 that module returns nothing (it defines the global `o`), so that line would replace `o` with `true` and the bindings after it would fail. Type the three lines above instead of appending the fragment.

## Update, disable, remove

Updating is a fast-forward pull of the plugin's git checkout:

```console
$ omarchy plugin update tmm.manual
tmm.manual is up to date.
```

When there is something new, Omarchy shows you the diff, asks before applying it, refuses if you have local changes it cannot fast-forward past, and rolls back if the new revision fails validation. Read that diff: it is your chance to review code that is about to run as you. Afterward the command rescans the shell for you. The repository has no tagged releases, so the version is the `version` field in `manifest.json`:

```console
$ grep version ~/.config/omarchy/plugins/tmm.manual/manifest.json
  "version": "0.5.0",
```

Two things live outside the plugin folder and do not update themselves: your copy of `tmm` in `~/.local/bin`, and the menu rows. Redo the `cp` or the `tmm-menu install` only when those files changed in the diff.

`omarchy plugin disable tmm.manual` turns it off and keeps the files. To remove it for good, undo the extras first, because `tmm-menu` lives inside the plugin folder you are about to delete:

```bash
P=~/.config/omarchy/plugins/tmm.manual
"$P"/bin/tmm-menu remove && omarchy menu refresh
omarchy plugin remove tmm.manual
rm -f ~/.local/bin/tmm
```

`omarchy plugin remove` asks for confirmation, disables the plugin, and deletes the folder (the repository is still on GitHub). Then delete the three `o.bind` lines from `~/.config/hypr/bindings.lua` and run `hyprctl reload`.

The plugin also leaves a cache and two small state files. The README lists `~/.cache/tmm/` for the cache, but the window asks the Qt toolkit where cache files belong, so confirm where yours landed before deleting:

```bash
find ~/.cache -maxdepth 3 -type d -name tmm
rm -f ~/.local/state/omarchy/tmm-recents.json ~/.local/state/omarchy/tmm-ui.json
```

Remove each folder `find` prints. If you set up the study chat in Phase 3, also delete `~/.config/tmm/`: it holds `ai.json`, which may contain an API key, and the README's uninstall list does not mention it.

Check yourself before moving on:

```quiz
[
  {
    "q": "You installed tmm.manual without --enable and said no to \"enable now\". You then run omarchy-shell shell summon tmm.manual. What happens?",
    "choices": [
      "Omarchy enables the plugin the first time you summon it",
      "Nothing visible happens, because the plugin is installed but disabled and a disabled plugin ignores a summon",
      "The window opens in a read-only mode"
    ],
    "answer": 1,
    "explain": "Omarchy installs plugins disabled unless you pass --enable or say yes to the prompt. Run omarchy plugin list to see the state, then omarchy plugin enable tmm.manual.",
    "why": ["Nothing in omarchy-shell enables a plugin on its own; only omarchy plugin enable (or --enable) does.", null, "There is no read-only mode. A disabled plugin does not open at all."]
  },
  {
    "q": "What does a marketplace listing for tmm.manual tell you?",
    "choices": [
      "The code has been security audited, so reviewing it yourself is optional",
      "Omarchy runs it in a sandbox, so it cannot touch your files",
      "A specific commit was checked and reviewed, but plugins run unsandboxed and the install command fetches the repository's current latest commit, so you should still read before you enable"
    ],
    "answer": 2,
    "explain": "The marketplace validates listings, not plugin security, and says verification is not a security audit. The install command clones the current upstream commit, which can be newer than the reviewed one.",
    "why": ["The marketplace explicitly says verification is not a security audit.", "Plugins run as arbitrary, unsandboxed code with your user permissions.", null]
  },
  {
    "q": "Why should you run tmm-menu install from the plugin folder instead of from a copy in ~/.local/bin?",
    "choices": [
      "A copy looks for its menu fragment next to itself, cannot find it, and stops with fragment not found",
      "A copy in ~/.local/bin is not executable",
      "~/.local/bin is not on your PATH on Omarchy"
    ],
    "answer": 0,
    "explain": "tmm-menu finds extensions/omarchy-menu.jsonc relative to where the script lives. In the plugin folder that file exists; beside a copy in ~/.local/bin it does not."
  }
]
```

## Recap

1. `tmm.manual` is three plugin kinds in one: a `panel` (the reader window), a `service` (network, cache, AI), and a `bar-widget` (the book button).
2. A marketplace listing means a checked and reviewed snapshot, not an audit. Plugins run as you, so add without `--enable`, read, then run `omarchy plugin enable tmm.manual`.
3. Confirm with `omarchy plugin list` and `omarchy-shell shell summon tmm.manual` (which prints `ok`). A disabled plugin ignores a summon silently.
4. The `tmm` command, the menu rows, and the hotkeys are opt-in extras outside the plugin folder. Run `tmm-menu` from the plugin folder, and type the three `o.bind` lines yourself.
5. `omarchy plugin update tmm.manual` pulls the new code after you read the diff. Clean removal means undoing the extras first, then `omarchy plugin remove tmm.manual`.

Next up, [Your First Ten Minutes in the Reader](02-your-first-ten-minutes.md): a keystroke-by-keystroke tour of the window you installed.


---

# Your First Ten Minutes in the Reader

The window is built to be driven by the keyboard, and it behaves differently from most apps: there is no text box to click, and the same letter can be text in one place and a command in another. Ten minutes of real keypresses will make that feel normal. Open the window and follow along.

## Minute 1: open it

Any of these opens the same window:

- Click the book icon on your bar.
- Press `Super + Alt + M`, if you added the hotkeys in Phase 1.
- Open the Omarchy menu with `Super + Space` and pick Missing Manual, if you added the menu rows.
- Run `omarchy-shell shell toggle tmm.manual` in a terminal.

You get a normal floating window (the README contrasts it with a fullscreen overlay), 1000 by 720 pixels to start with and no smaller than 640 by 560. It opens on the catalog, a list of categories, and the line along the bottom is a cheat card that changes with whatever you are doing. Glance at it often.

## The one idea: lists type, the reader obeys

The window has four views, and the keys mean different things in each:

```mermaid
flowchart LR
  C["Catalog"] -->|"Tab"| S["Search"]
  S -->|"Tab"| C
  S -->|"Enter"| R["Reader"]
  C -->|"Enter on a guide"| R
  S -->|"?"| A["Ask"]
  A -->|"1 to 9"| R
  R -->|"Esc"| S
```

In the **search** and **catalog** views, every printable character goes into a filter at the top. There is no field to click into first. In the **reader** and **ask** views, letters become commands: `n` is next phase, `y` is copy, `q` is quiz. So `n` types an "n" while you search and turns the page while you read.

`Esc` unwinds one layer at a time instead of closing everything: it dismisses an error, leaves a quiz, leaves the reader for the list you came from, steps up a catalog level, clears your query, and only then closes the window. Press it freely.

## Minute 2: search

Start typing: `git rebase`. After a short pause the window asks the site's search endpoint and shows up to 24 hits, each with a title, a phase number, and a one-line summary. The header reads `searching…` and then the result count. The terminal client asks the same endpoint, so it shows what the window would:

```console
$ tmm search "git rebase"
git-disaster-recovery/2       Rebase Without Fear
git-explained-like-a-human/0  Git, Explained Like You're a Human
git-with-other-people/0       Git With Other People - Branches, Pull Requests, and Not Stepping on Toes
pre-commit-hooks/1            What a Hook Actually Is
bisecting-a-bug/2             git bisect - Letting Git Drive the Search
```

*What just happened:* each line is `guide-slug/phase` and a title. A `/0` marks a hit on the guide as a whole rather than one phase, and the window opens those at phase 1. Your results will differ as the library grows.

| Key | What it does |
|---|---|
| any character | Add it to the search |
| `Up` and `Down`, or `Ctrl + N` and `Ctrl + P` | Move the cursor |
| `PgUp`, `PgDn`, `Home`, `End` | Jump |
| `Enter` | Open the highlighted hit |
| `Shift + Enter` | Accept a "Did you mean" suggestion, when one appears |
| `?` | Ask the guides about what you typed (Minute 6) |
| `Tab` | Switch to the catalog |
| `Ctrl + R` | Open a random guide |
| `Backspace`, `Ctrl + Backspace`, `Ctrl + U` | Delete a character, delete a word, clear the line |
| `Esc` | Clear the query, then close |

The "Did you mean" line appears only when the site sends back a spelling suggestion, so do not expect it on every typo.

## Minute 3: read a phase

Press `Enter` on a hit. From 900 pixels of width up, which includes the default size, the window switches to two columns: your results stay on the left and the reader fills the right, so you can keep browsing while you read. In a narrower window (a tiled slot, say) it uses one column instead.

The header shows something like `phase 2 of 4 · 8 min`: where you are in the guide and a rough reading time (words divided by 200, with code counting for less). A thin progress line under the text fills as you scroll. The reader draws headings, lists, quotes, tables, and code as themed blocks, and code is syntax-highlighted in cards.

| Key | What it does |
|---|---|
| `Up` and `Down`, or `j` and `k` | Scroll |
| `Space`, `PgDn`, `PgUp` | Page down and up |
| `g` or `Home` | Jump to the top |
| `Shift + G` or `End` | Jump to the bottom |
| `n` and `p`, or `Right` and `Left` | Next and previous phase |
| `y` | Copy the whole phase as Markdown |
| click a code block | Copy only that snippet |
| `o` | Open this phase in your browser |
| `Esc` or `Backspace` | Back to your list |
| `/` | Start a new search |
| `Tab` | Switch to the catalog |
| `s` | Fold the left column away for a full-width page (and bring it back) |
| `Ctrl + T` | Cycle the reading theme (Phase 3) |
| `Ctrl + K` | Open the study chat (Phase 3) |

Copying needs `wl-copy`. At the last phase, `n` shows "That was the last phase" instead of an error. Nothing in a guide is ever run: a code block is copied, a link opens in your default browser.

## Minute 4: answer the quiz

Press `Shift + G` to jump to the bottom. A phase that has a quiz ends with a card that says how many questions it holds. Press `q` to start answering in place.

| Key | What it does |
|---|---|
| `a` to `d`, or `1` to `4` | Answer the current question |
| `Up` and `Down`, or `j` and `k` | Move between questions |
| `m` | Retry only the questions you missed |
| `r` | Start over |
| `Esc` | Leave the quiz and keep reading |

An answer locks the first time you pick it. A right one says "Correct." and a wrong one says "Not quite.", each followed by the guide's explanation when it has one, and when the author wrote a reason for that specific wrong choice, you see that reason instead. At the end you get "You got 2 of 3." Everything else keeps working mid-quiz, so `n`, `p`, and `y` still do their usual jobs.

> ⚠️ **Gotcha.** On a phase with no quiz, `q` closes the window. That is by design: `q` means "quiz, or quit if there is nothing to quiz". `Shift + Q` always closes it. Your answers live only in the window and reset when you open a different phase, and the plugin has no account to report them to, so they do not count toward anything on the website.

## Minute 5: diagrams, and what it cannot run

Mermaid diagrams (the flowcharts in guides) are drawn right in the page in your theme's colors. They come from the picture the website already renders, recolored to your palette and turned into an image, and they repaint when you switch Omarchy themes. If one shows as a small card reading `Diagram · mermaid`, the plugin could not turn it into an image; Phase 4 covers why.

Some guides contain live widgets that run in a browser, such as a regex tester or an animated explainer. The window cannot run those, so it shows a card labeled `Interactive` with the widget's name. Hover over it and it reminds you to press `o` to open the phase on the web. Code that would run in the browser on the site appears here as an ordinary code card you can copy.

## Minute 6: ask a question

Type a question in the search view, such as `what is a branch`, and press `?`. The footer shows `? ask` whenever asking is available. The window sends your question to the site's answer service and shows an answer written from the guides, with the phases it used listed underneath as numbered sources.

| Key | What it does |
|---|---|
| `1` to `9` | Open that source in the reader |
| `Enter` | Open the first source |
| `Up` and `Down`, `j` and `k`, `Space` | Scroll |
| `y` | Copy the answer |
| `o` | Open the site's search page for your question in the browser |
| `Esc` or `Backspace` | Back to your results |

Three rules shape it. It only happens when you press `?`, never while you type, because each written answer spends part of the site's monthly AI budget. Questions are limited to 300 characters. And answers are saved on disk, so asking the same thing again is instant and free (the header says `cached`).

The service can also tell you "AI answers are not enabled on this host" or that the month's limit is spent. Neither is a failure of your setup, and search keeps working. This is the site's own answer service, not your own AI key; the study chat in Phase 3 is the one that uses your key.

One more thing happens automatically: if a search finds nothing and you stop typing for a moment, the window quietly asks the site's free retrieval endpoint and adds an `Ask the guides about...` row plus up to three `related` rows.

## Minute 7: jump around

The **catalog** has two levels: categories, then the guides inside one. Type to filter locally with no network, press `Enter` to open a category and again to open a guide, and press `Backspace` on an empty filter to climb back up. `Ctrl + R` opens a random guide from anywhere in the search, catalog, or reader view.

**Recents** is the list of the last 12 phases you opened. It appears on the empty search screen, so press `Tab` from the catalog or clear your query to see "Pick up where you left off". Each row carries a badge with the phase you last read.

> ⚠️ **Gotcha.** In 0.5.0, pressing `Enter` on a recents row opens that guide at phase 1, even though the badge shows a later phase. Press `n` to catch up. The code stores the phase number but opens recents rows without it.

Reopening the window from a closed state always starts at the catalog, so recents is one `Tab` away.

## Minute 8: pull the network cable

Every phase you open is saved in the cache, and each time you open it online the saved copy is refreshed. Without a network, here is what you can and cannot do:

| What you try | Offline result |
|---|---|
| Reopen a phase you have opened before | Works. The header ends with `offline` |
| Open a phase you have never opened | "Phase N is not available offline" |
| Search | Fails with "Search failed" |
| Open the catalog in a freshly started shell | Fails with "Could not load the catalog". It is fetched once per session and kept in memory only |
| Ask with `?` | Reports that the answer service is unavailable, unless you already asked that exact question and it was saved |
| Diagrams | May show as `Diagram · mermaid` cards, because they are pulled from the website's page |

Since the catalog and search need the network, jump straight to a cached phase with a summon payload, which is a small piece of JSON handed to the window:

```bash
omarchy-shell shell summon tmm.manual '{"slug":"git-from-zero","phase":2}'
```

That opens the exact phase from the cache. The other payload keys are `query`, `catalog`, and `random`:

```bash
omarchy-shell shell summon tmm.manual '{"query":"git rebase"}'
omarchy-shell shell summon tmm.manual '{"catalog":true}'
omarchy-shell shell summon tmm.manual '{"random":true}'
```

To read a whole guide offline, `tmm offline git-from-zero` downloads its EPUB (an e-book file) into the cache folder and prints the path. Open it in an e-reader app; nothing in the plugin reads it back.

## Minute 9: the same guides in your terminal

The `tmm` command from Phase 1 renders the same guides without the window.

| Command | What it does |
|---|---|
| `tmm search "git rebase"` | Aligned results, with a "did you mean" line on stderr when there is one |
| `tmm open git-from-zero/2` | Render a phase into your pager (`$PAGER`, or `less -R`) |
| `tmm read git-from-zero 2` | Render to standard output instead |
| `tmm list` | Every guide, with its category |
| `tmm categories` | The category names |
| `tmm random` | One random guide |
| `tmm recent` | What you last read, shared with the window |
| `tmm offline git-from-zero` | Download the EPUB into the cache |
| `tmm close` | Stop pagers started by `tmm open` |

```console
$ tmm read git-from-zero 2 | head -n 10


Your First Repository - init, add, commit, log
──────────────────────────────────────────────

Git is installed and knows your name. Now you'll actually use it: create a project, and take your first
real snapshot of it. Everything in this phase happens on your own computer - no internet, no GitHub, no
account. Git works perfectly well entirely alone, and starting here keeps the moving parts to a minimum.

Type along. Doing it once in your own terminal teaches more than reading it five times.
$ tmm recent
git-from-zero/2  Your First Repository - init, add, commit, log
```

*What just happened:* `tmm read` fetched the phase, saved a copy in its cache, drew the headings and rules in plain text because the output was piped, and added the phase to the recents file. The window reads that same recents file, but it loads it when the plugin loads, so newer entries from `tmm` may only appear after the plugin reloads. Colors follow the `NO_COLOR` setting and switch off whenever output is not a terminal. If `python3` is missing, `tmm` prints raw Markdown instead of rendered text.

`tmm --help` also lists `cheat`. It needs a site key that the public site does not hand out, so skip it.

## Minute 10: your turn

Do each of these once without touching the mouse.

1. Open the window, type `linux`, and open a hit with `Enter`.
2. Press `n` twice, then `p` once.
3. Jump to the bottom, press `q`, and answer the quiz.
4. Press `Esc` until you are back at the search view, then press `Tab` and open a category.
5. Press `Ctrl + R` for a random guide, then `Shift + Q` to close.

Check yourself before moving on:

```quiz
[
  {
    "q": "You are in the search view and type the letter n. What happens?",
    "choices": [
      "The letter n is added to your search, because in lists every printable character goes to the filter",
      "A new window opens",
      "The window jumps to the next phase"
    ],
    "answer": 0,
    "explain": "Search and catalog views type into a filter. Letters become commands (n, p, y, q) only in the reader and ask views.",
    "why": [null, "Nothing in the window opens a second window.", "Next phase is a reader command. In the search view there is no phase to move."]
  },
  {
    "q": "You are reading a phase that has no quiz and you press q. What happens?",
    "choices": [
      "Nothing, because there is no quiz",
      "A quiz is generated from the text",
      "The window closes"
    ],
    "answer": 2,
    "explain": "q starts the quiz when there is one and closes the window when there is not. Shift + Q always closes it."
  },
  {
    "q": "You read phase 3 of a guide yesterday. Now the network is down. Which of these still works?",
    "choices": [
      "Searching for a topic you have never opened",
      "Reopening phase 3, which the header marks offline",
      "Asking a question with ?"
    ],
    "answer": 1,
    "explain": "Phases you have opened are cached and fall back to the saved copy. Search, ask, and the catalog all need the network, and a phase you never opened is not in the cache.",
    "why": ["Search asks the website every time, so it fails offline.", null, "Asking also needs the website's answer service."]
  }
]
```

## Recap

1. In search and catalog views, letters go to a filter; in the reader and ask views, letters are commands. `Esc` unwinds one layer at a time.
2. Search as you type, `Enter` to read, `n` and `p` for phases, `y` to copy a phase, `o` to open it in the browser, `s` to fold the list in the wide layout.
3. `q` answers the quiz in place (and closes the window if there is no quiz). Answers lock on the first pick and are not saved anywhere.
4. `?` asks the site's answer service, only on a keypress, with numbered sources you open with `1` to `9`.
5. Offline, only phases you have opened before work. Use a summon payload such as `{"slug":"git-from-zero","phase":2}` to jump straight to one.
6. `tmm` renders the same guides in a terminal and writes to the same recents file the window reads.

Next up, [Making It Yours: Themes, Hotkeys, and the Study Chat](03-making-it-yours-and-the-study-chat.md): the reading theme, your own hotkeys, and the bring-your-own-key study chat with exactly where your key is stored.


---

# Making It Yours: Themes, Hotkeys, and the Study Chat

The reader ships with sensible behavior and very few switches, so making it yours means a theme, a layout, a hotkey, and the optional study chat. The chat is the one part that can send your text somewhere other than themissingmanual.dev, so this phase also says exactly where your key lives.

## What you can change

There is no settings file for the reader itself. These are the real levers:

| Lever | How | Saved? |
|---|---|---|
| Reading theme | `Ctrl + T` cycles auto, light, dark | No. It resets to auto when the shell restarts |
| Column layout | `s` folds the list; drag a divider to resize | Widths are saved in `~/.local/state/omarchy/tmm-ui.json` |
| Desktop look | Switch your Omarchy theme | Follows it live |
| Bar position | `omarchy bar move tmm.manual --section left` | Omarchy saves bar layout |
| Hotkeys | Your `~/.config/hypr/bindings.lua` | Yours |
| Study chat | The settings form, or `~/.config/tmm/ai.json` | Yes |
| Which server | The `TMM_BASE` environment variable | n/a |

## Theming

In **auto** mode the window asks the running Omarchy theme for its background, foreground, accent, and error colors, and takes its font and spacing from the shell as well, so a theme switch repaints it with no action from you. Code highlighting picks a light or dark palette by checking how bright your desktop background is. Mermaid diagrams are re-baked in the new palette whenever the colors change.

`Ctrl + T` from anywhere pins the window to **light** or **dark** instead: fixed reading palettes, independent of the desktop, for guides that read better one way. Press it a third time to return to auto. Try it now: open a phase with a diagram, press `Ctrl + T` twice, and watch the code cards and the diagram change together.

To test the follow-the-desktop part, open Omarchy's theme menu with `Super + Shift + Ctrl + Space`, pick another theme, and look at the reader again. If the window looks unstyled instead, it cannot find the shell's `qs.Commons` theme module, which means you are not on Omarchy 4.

## Make it reachable

You already have `Super + Alt + M`, `Super + Alt + B`, and `Super + Alt + R` from Phase 1. Every hotkey is a command, and the window accepts a small JSON payload that decides where it opens. These are the keys it understands:

| Payload | Opens |
|---|---|
| `{"query":"git rebase"}` | The search view with that query already run |
| `{"slug":"linux-from-zero","phase":1}` | That exact phase |
| `{"catalog":true}` | The catalog |
| `{"random":true}` | A random guide |

Bind one to a key of your own. In `~/.config/hypr/bindings.lua`:

```lua
o.bind("SUPER + ALT + L", "Missing Manual: Linux From Zero", "omarchy-shell shell summon tmm.manual '{\"slug\":\"linux-from-zero\",\"phase\":1}'")
```

*What just happened:* Lua reads `\"` inside its double-quoted string as a plain double quote, so the shell receives `'{"slug":"linux-from-zero","phase":1}'` in single quotes, which keeps the JSON in one piece. `Super + Alt + L` is not bound in Omarchy 4.0.4's default bindings. Run `hyprctl reload`, then press `Super + K` to see Omarchy's keybindings list.

To move the bar button, use `omarchy bar move tmm.manual --section left` (or `--index 0` for the first spot in a section). To reword or reorder the menu rows, edit `~/.config/omarchy/extensions/omarchy-menu.jsonc`; remember that `tmm-menu install` replaces every entry whose key starts with `tmm`.

To point the window or the terminal client at another server, such as a self-hosted copy of the library, set `TMM_BASE`:

```bash
TMM_BASE=http://localhost:5173 tmm search "networks"
```

The window reads `TMM_BASE` from the environment of the running shell, so exporting it in one terminal does not reach it.

## The study chat

There are two AI features in the window, and they are not the same thing:

| | Ask (`?`) | Study chat (`Ctrl + K`) |
|---|---|---|
| Whose AI | The website's answer service | A model **you** configure |
| Whose budget | The site's monthly budget | Your provider account or subscription |
| Needs setup | No | Yes, or it runs in retrieval mode |
| Context | Your question only | The phase you are reading, plus your conversation |

Press `Ctrl + K` to open a dock titled "Ask the tutor" beside the reader. In a wide window it sits on the right and the left list folds away. With no provider configured it works in **retrieval mode**: it searches the manual and replies with the most relevant sections, each with a clickable source chip that opens that phase, and the dock says "retrieval mode" to remind you. Three starter chips, such as "Show a real example", send a question in one click.

### Turn on real answers

Click the gear in the dock's header, or press `Ctrl + ,`. Pick a provider, fill in the fields it shows, and press `Ctrl + S` (or `Ctrl + Enter`) to save. `Esc` cancels. The form writes `~/.config/tmm/ai.json`, and changes apply at once without a restart. The "None" choice saves an empty object (`{}`), which means retrieval mode.

| Provider | Runs on | You provide |
|---|---|---|
| `claude-cli` | Claude Code, the `claude` command | The CLI installed and signed in |
| `codex` | OpenAI Codex, the `codex` command | The CLI installed and signed in |
| `cursor` | Cursor Agent, the `cursor-agent` command | The CLI installed and signed in |
| `opencode` | The `opencode` command | The CLI installed and signed in |
| `openai` | Any OpenAI-compatible endpoint: OpenAI, OpenRouter, Groq, or a local Ollama or LM Studio server | `baseUrl`, `apiKey`, `model` |
| `anthropic` | Anthropic's Messages API | `apiKey`, `model` |

The four CLI providers run a tool you have already signed in to, so, per the README, answers use that tool's subscription with no API key and no per-token bill. The README says each CLI runs inside a scratch folder with its tools locked down so the chat can only return text: Claude Code gets no tools and no MCP servers, Codex runs in its read-only sandbox, Cursor in ask mode, and opencode as a dedicated agent with every permission denied. They are slower, because each reply starts the agent, and each call is cut off after 150 seconds.

If you prefer a file to the form, `~/.config/tmm/ai.json` is plain JSON, so no comments are allowed. Three working shapes:

```json
{ "provider": "claude-cli" }
```

```json
{ "provider": "openai", "baseUrl": "http://localhost:11434/v1", "apiKey": "ollama", "model": "llama3.1" }
```

```json
{ "provider": "anthropic", "apiKey": "YOUR-KEY-HERE", "model": "YOUR-MODEL-ID" }
```

The second one is the README's local-model example: a free Ollama server on your own machine. The plugin treats an API provider as ready only when it has a key and a model, so a local server gets a placeholder key. Put a real model id in the third example, the one your provider documents.

| Field | Meaning |
|---|---|
| `provider` | One of the six values above (required) |
| `baseUrl` | Required for `openai`. Optional for `anthropic`, where it defaults to `https://api.anthropic.com` |
| `apiKey` | Required for `openai` and `anthropic`. Can come from the `TMM_AI_KEY` environment variable instead |
| `model` | Required for `openai` and `anthropic`. Optional for the CLI providers |
| `bin` | The CLI's full path, if it is not on your `PATH` |
| `maxTokens` | Reply length limit for the API providers. Defaults to 1024 |
| `effort` | A reasoning-effort hint such as `low`, where the provider supports it |
| `systemPrompt` | Replaces the built-in "Tutor" instructions |

The README's advice is that studying does not need a frontier model: set `model` (and `effort`) to a cheaper, faster one.

### Where a chat message goes

With a provider configured, a chat message goes to that provider only (or, for the four CLI providers, to the tool on your machine), and not to The Missing Manual. With none configured, your question goes to the site's free retrieval endpoint instead. Phase 4 has the complete table of what is sent where.

### Where your key lives

The key sits in `~/.config/tmm/ai.json` as plain text. It is not encrypted, so treat the file like a password:

- When the form saves, it creates the folder with owner-only access (mode 700) and writes the file through a temporary file with owner-only access (mode 600), then renames it into place. A file you create by hand has whatever permissions you give it, so run `chmod 600 ~/.config/tmm/ai.json`.
- The key, the request, and your conversation are passed to the program that talks to your provider through a private pipe (standard input), never as command-line arguments. Command-line arguments can be read by other programs through the process list; a pipe cannot.
- `TMM_AI_KEY` is an alternative to storing the key in the file. It is read from the environment of the running shell process, so a variable exported in a terminal does not reach it.
- If you keep your dotfiles in a git repository, keep `~/.config/tmm/` out of it. [Secrets Management](/guides/secrets-management) explains why a key that reaches a repository should be treated as leaked.

If a key does leak, revoke it at your provider; deleting the file is not enough.

Check yourself before moving on:

```quiz
[
  {
    "q": "You want a hotkey that opens phase 1 of linux-from-zero directly. Which command should the binding run?",
    "choices": [
      "omarchy-shell shell summon tmm.manual '{\"slug\":\"linux-from-zero\",\"phase\":1}'",
      "omarchy-shell shell summon tmm.manual linux-from-zero",
      "omarchy plugin enable linux-from-zero"
    ],
    "answer": 0,
    "explain": "The window takes its instructions as a JSON payload. The slug and phase keys open an exact phase.",
    "why": [null, "The payload has to be JSON. A bare word is not valid, and the window reports that the payload was not valid JSON.", "omarchy plugin enable turns a plugin on by its id. linux-from-zero is a guide, not a plugin."]
  },
  {
    "q": "How is your API key stored, and how does the plugin hand it to your provider?",
    "choices": [
      "Encrypted in the system keyring, and passed to curl as a command-line argument",
      "In the cache folder, so it can be shared with the tmm command",
      "As plain text in ~/.config/tmm/ai.json (saved with owner-only permissions by the form), and passed to the program on standard input rather than on a command line"
    ],
    "answer": 2,
    "explain": "The file is not encrypted, so protect it like a password. Keeping the key off command lines stops other programs from reading it in the process list.",
    "why": ["The plugin does not use the keyring, and a command-line argument would be visible to other programs.", "The key lives in ai.json under your config folder, not in the cache.", null]
  },
  {
    "q": "You set provider openai with a baseUrl pointing at your own Ollama server and ask the study chat a question. What does themissingmanual.dev receive from that chat message?",
    "choices": [
      "Your question, as a free retrieval request",
      "Nothing from the chat. The conversation goes to your own server",
      "Your API key"
    ],
    "answer": 1,
    "explain": "With a configured provider the chat goes to that provider only. Retrieval mode, which asks the website, is the fallback for when no provider is set.",
    "why": ["That only happens in retrieval mode, which is used when no provider is configured.", null, "The key goes to the baseUrl you configured, never to the website."]
  }
]
```

## Recap

1. The reader has few switches: `Ctrl + T` for the reading theme (not saved), draggable column widths (saved), your own hotkeys, and the optional study chat. The window follows your Omarchy theme live.
2. A summon payload such as `{"slug":"linux-from-zero","phase":1}` lets a hotkey open an exact phase, a search, the catalog, or a random guide.
3. The study chat is bring-your-own-model: a CLI you already use, an OpenAI-compatible endpoint (including local Ollama), or Anthropic's API. With none configured it falls back to retrieval from the manual.
4. Your key is plain text in `~/.config/tmm/ai.json`, saved with owner-only permissions by the form and kept off command lines. Keep that file out of any repository, and revoke the key at your provider if it leaks.

Next up, [Where Your Data Goes, and Fixing It When It Breaks](04-where-your-data-goes-and-fixing-it.md): the full table of what is sent where, a symptom-to-fix card, and how to report a bug.


---

# Where Your Data Goes, and Fixing It When It Breaks

Either something is not working, or you want a straight answer about what the plugin does with your data. The card below handles the first, and the two tables after it handle the second. The phase ends with how to report a bug.

## When it breaks

| Symptom | Calm fix |
|---|---|
| Hotkey, menu row, or `summon` does nothing | Run `omarchy plugin list`. If `tmm.manual` says `disabled`, run `omarchy plugin enable tmm.manual` |
| `omarchy-shell shell summon tmm.manual` prints `unknown` | The shell has no such plugin loaded. Check `ls ~/.config/omarchy/plugins/tmm.manual/`, then `omarchy-shell shell rescanPlugins` |
| It prints `ok` but no window appears | A QML error stopped it drawing. Read the journal, below |
| The bar icon is missing | `omarchy bar put tmm.manual --section right` |
| `omarchy plugin add` says it is already installed | Use `omarchy plugin update tmm.manual` instead |
| The window opens unstyled | You are not on Omarchy 4 |
| Search says "Search failed" or finds nothing | Check the network with the `curl` test below the table |
| Diagrams show as `Diagram · mermaid` cards | See the diagram check below |
| Copy does nothing | Install `wl-clipboard`, which provides `wl-copy` |
| Menu rows show words like `search` instead of icons | You have an old menu fragment. Run `~/.config/omarchy/plugins/tmm.manual/bin/tmm-menu install` again, then `omarchy menu refresh` |
| A hotkey does nothing | Check the `o.bind` lines for typos, run `hyprctl reload`, then `omarchy menu keybindings --print` to see whether the binding loaded |
| An update does not seem to take | `omarchy-restart-shell` is the stronger reset |

To test the network side yourself, ask the search endpoint directly. If this prints JSON, the site is reachable:

```bash
curl -fsSL "https://themissingmanual.dev/search.json?q=git" | head -c 300
```

When `summon` prints `ok` and nothing appears, the shell logs to the journal under its own tag:

```bash
journalctl -t omarchy-shell -n 100 --no-pager | grep -i -A3 'tmm\|error\|warning'
```

Run `journalctl -t omarchy-shell -f` in one terminal to watch live while you summon from another. Omarchy's plugin development guide gives a second way to read the same logs: `qs log -p "$OMARCHY_PATH/shell" --tail 100`. After you edit plugin files, `omarchy-restart-shell` is the clean reset.

You can also check the plugin folder against Omarchy's own rules. It prints nothing and exits cleanly when everything is fine:

```bash
omarchy plugin validate ~/.config/omarchy/plugins/tmm.manual/
```

**Diagram check.** The helper looks for an image tool in this order: `rsvg-convert`, then ImageMagick (`magick` or `convert`). With neither, or without `python3`, you get cards. Test the helper directly on a phase that has diagrams:

```bash
command -v rsvg-convert python3
curl -fsSL https://themissingmanual.dev/guides/how-the-internet-works/1 \
  | ~/.config/omarchy/plugins/tmm.manual/bin/tmm-diagrams /tmp/d test
```

It prints one line per diagram: a path, a width, and a height. No output means the page had no diagrams; an error points at `python3`. Offline, cards are expected.

**Chat errors.** The dock shows failures in red. The common ones:

| Message starts with | Meaning and fix |
|---|---|
| "No AI key configured" | An API provider is missing its key or model. Open settings with `Ctrl + ,` |
| "No AI endpoint configured" | `openai` needs a `baseUrl` |
| "The AI request failed" | Network or endpoint trouble. Check the connection and `baseUrl` |
| "Could not read the model's reply" | The endpoint did not answer in the expected format. Check the key and config |
| "The model declined to answer that" | The provider refused that question |
| "The AI CLI didn't run" | The CLI is not installed or not on `PATH`. Install it, or set `bin` to its full path |
| "The AI CLI returned nothing" | It ran but gave no answer. Check that it is signed in |

## What leaves your machine

Every request the plugin itself makes goes through `curl`, and the website sees it the way any website sees a visitor: your IP address and the address you asked for. The plugin sends no account, cookie, or identifier of its own. Here is each action and where it goes:

| Action | Goes to | What is sent |
|---|---|---|
| Typing in search | themissingmanual.dev `/search.json` | The text you typed |
| Opening the window | `/llms.txt` | A request for the catalog |
| Opening a phase | `/guides/<slug>/<phase>.md`, and the phase's web page when it has diagrams | The guide and phase you asked for |
| Ask with `?` | `/ask.json` | Your question, up to 300 characters |
| A search with no hits, or the chat with no provider | `/ask.json` in free retrieval mode | The text you typed, or your chat question |
| Chat with `openai` or `anthropic` | Your `baseUrl`, or Anthropic's API | The system prompt, up to the first 6,000 characters of the phase on screen, your whole conversation, and your key as a request header |
| Chat with a CLI provider | The CLI on your machine | The same text, on its standard input. What that tool sends onward is between you and its vendor |

Two consequences follow. With a provider configured, your chat questions go to that provider and not to The Missing Manual. And your key goes to whatever `baseUrl` you type, so only point it at a server you trust. Only the first 6,000 characters of a phase are included, so a question about the end of a long phase gets less context. [AI Privacy and What Not to Paste](/guides/ai-privacy-and-safety) covers what is wise to put into any chatbot.

What stays on your machine:

| Where | What |
|---|---|
| The `tmm` cache folder | Phase text (`<slug>-<phase>.md`), diagram images, saved ask answers, and the CLI scratch folder |
| `~/.local/state/omarchy/tmm-recents.json` | Your last 12 phases: slug, phase, title, and time |
| `~/.local/state/omarchy/tmm-ui.json` | Your dragged column widths |
| `~/.config/tmm/ai.json` | Your chat settings, and the key if you saved one |
| Memory only | The chat conversation. The plugin never writes it to disk, and "Clear history" in the dock empties it |

The README documents the cache as `~/.cache/tmm/`. Run `find ~/.cache -maxdepth 3 -type d -name tmm` to see where yours is. Every network reply is also held to a size ceiling and a time limit, and a reply that goes over either is dropped rather than half-read or half-saved.

## Report a bug, or help

Bugs in the plugin go to its issue tracker at [github.com/Topurrra/omarchy-tmm](https://github.com/Topurrra/omarchy-tmm/issues). Gather these first, so nobody has to ask:

```bash
grep version ~/.config/omarchy/plugins/tmm.manual/manifest.json
git -C ~/.config/omarchy/plugins/tmm.manual rev-parse --short HEAD
omarchy version
omarchy plugin list | grep tmm.manual
```

Add what you pressed, what you expected, and the journal lines from the troubleshooting card. Do not paste `ai.json`; it may hold a key. A wrong command or mistake inside a guide is a content bug, and the README says those belong with The Missing Manual itself, not with the plugin.

To contribute code, the README asks for a few things: take colors, spacing, and type from the shell's `Color` and `Style` helpers instead of hardcoding them, keep `bin/tmm` clean POSIX `sh`, and test with `sh -n`, JSON validation, and `omarchy plugin validate`. It also asks that a QML file do one job. The plugin is MIT licensed. If you want to understand how a plugin like this is built before you open a pull request, read [Building Your Own Omarchy Plugin](/guides/building-your-own-omarchy-plugin).

Check yourself before moving on:

```quiz
[
  {
    "q": "omarchy-shell shell summon tmm.manual prints ok, but no window appears. What does that tell you?",
    "choices": [
      "The plugin is disabled, so enable it",
      "The plugin is not installed, so run omarchy plugin add again",
      "The shell loaded the plugin and opened it, but an error in its QML stopped it drawing, so read the journal with journalctl -t omarchy-shell"
    ],
    "answer": 2,
    "explain": "ok means the shell has the plugin loaded and tried to open it. The enable check is already behind you, so the shell's log is the next place to look.",
    "why": ["ok means the shell already has the plugin loaded, so the enable check is behind you.", "A plugin that is not installed is not loaded, so summon would not say ok.", null]
  },
  {
    "q": "Every diagram in the reader shows as a small Diagram · mermaid card, and you are online. What is the most likely cause?",
    "choices": [
      "Nothing on the machine can turn the diagram into an image, for example no rsvg-convert or ImageMagick, or python3 or the helper script cannot run",
      "Your Omarchy theme is not supported",
      "The study chat is turned on"
    ],
    "answer": 0,
    "explain": "The helper recolors the website's diagram and rasterizes it with rsvg-convert or ImageMagick. If it cannot, the reader falls back to a card. Test the helper with curl piped into bin/tmm-diagrams.",
    "why": [null, "Theme changes only recolor diagrams; they never turn them into cards.", "The chat has no effect on how diagrams are drawn."]
  },
  {
    "q": "While reading in the window you find a wrong command inside a guide. Where does the report belong?",
    "choices": [
      "The plugin's issue tracker, because the plugin displays it",
      "The Missing Manual itself, because guide content lives upstream, not in the plugin",
      "Omarchy's repository"
    ],
    "answer": 1,
    "explain": "The plugin only reads and displays the library. The README says content bugs belong with The Missing Manual, not with the plugin.",
    "why": ["The plugin does not own the text it shows; a fix there could not change the guide.", null, "Omarchy does not write or host these guides."]
  }
]
```

## Recap

1. Work down the card in order: `omarchy plugin list` for the enabled state, then whether `summon` says `ok` or `unknown`, then the journal with `journalctl -t omarchy-shell`.
2. Diagram cards mean nothing could turn the diagram into an image, `python3` or the helper cannot run, or you are offline.
3. Search, phases, and Ask go to themissingmanual.dev. With a provider configured, chat text goes to that provider only, and your key goes to the `baseUrl` you typed.
4. Locally it keeps a cache, a recents file, a widths file, and `ai.json`. The chat conversation lives in memory and is never written to disk.
5. For a bug report, bring your versions, what you pressed, and the journal lines, and never paste `ai.json`. Content mistakes go to The Missing Manual, not the plugin repo.

You now have the whole path: install it, learn the keys, shape it, and fix it. To see how a plugin like this is built, or to build your own, continue with [Building Your Own Omarchy Plugin](/guides/building-your-own-omarchy-plugin).
