---
title: Custom Render Rules (turn your own regex matches into inline badges)
---

# Custom Render Rules (turn your own regex matches into inline badges)

## What it is

**Custom Render Rules** let you define your own rules for how Omniscio draws
conversation text. Each rule is a **regular expression**; wherever it matches the
text of a message — both an agent's output **and** your own messages — that piece
of text is replaced with a small inline **badge** instead of plain words. A badge
can have a color, an optional icon, an optional label built from the match, and
an optional clickable link.

The idea is to make the things you care about jump out of a wall of text. For
example, turn every `PR #1234` into a clickable badge that opens the pull request,
turn `TODO` into an amber flag, or turn a ticket id like `JIRA-42` into a link to
your tracker.

You manage the rules in **Settings → Sessions → Custom Render Rules**.

## Where to find it

The rules are managed in **Settings → Sessions → Custom Render Rules**, and that section is the only place they live: it lists your rules in order, carries the master on/off toggle at the top, and provides the **Add rule** button along with the live preview where a pattern is tested against a sample line before it is saved. Nothing needs enabling anywhere else — once a rule is saved it applies to every conversation you open.

## How it behaves

### How to add a rule

1. Open **Settings → Sessions → Custom Render Rules**.
2. Click **Add rule** and fill in:
   - **Pattern** — the regular expression to look for (e.g. `PR #(\d+)`). This is
     required.
   - **Flags** (optional) — regex flags, limited to a safe set: `i`
     (case-insensitive), `m` (multiline), `s` (dot matches newlines), `u`
     (unicode). The global flag is applied for you — you don't add `g`.
   - **Tone** — the badge color (see below).
   - **Icon** (optional) — a small glyph shown before the label (see below).
   - **Label** (optional) — the text the badge shows (see *Label & link
     templates*). Leave blank to show the matched text as-is.
   - **Link** (optional) — an `http`/`https` URL to open when the badge is
     clicked (see *Label & link templates*).
3. Use the built-in **"test it" preview** — type a sample line and Omniscio shows
   exactly how the badge (and its resolved link) will look before you save.
4. Save. From then on, matching text in every conversation renders as your badge.

You can **add, edit, reorder, toggle, and delete** rules at any time. Order
matters: at each spot in the text, the **first rule (top-down) that matches
wins**, so put more specific rules above more general ones. Toggling a single
rule off (its checkbox) keeps it in the list but stops it rendering.

There is also a **master toggle** at the top of the section: turning it off
disables **all** custom rendering at once without deleting any of your rules;
turning it back on restores them.

### Badge options

#### Tone (color)

Pick one of six semantic tones, so a badge reads the same as the rest of the app:

`neutral` · `accent` · `success` · `warning` · `danger` · `info`

#### Icon

An optional small icon shown before the label. The set is a curated list (kept
short on purpose so a badge never pulls a huge icon library into the app):

`tag` · `check-circle` · `x-circle` · `alert-circle` · `alert-triangle` ·
`info` · `git-pull-request` · `git-merge` · `git-branch` · `rocket` · `flag` ·
`star` · `zap` · `bug` · `clock` · `shield` · `link` · `circle-dot`

#### Label & link templates

Both the **label** and the **link** are *templates* that can pull pieces out of
the regex match using `$` placeholders:

- `$0` — the **whole match**.
- `$1` … `$9` — the **capture groups** (the parts of your pattern in parentheses).
- `$$` — a literal `$`.

Examples, using the pattern `PR #(\d+)`:

- **Label** `PR $1` on a match of `PR #1234` shows a badge reading **PR 1234**.
- **Link** `https://github.com/me/repo/pull/$1` makes that badge open pull
  request 1234.
- Leave the label blank and the badge just shows the matched text (`PR #1234`).
- Leave the link blank and the badge is non-clickable (just a visual marker).

A link is only made clickable if the finished template resolves to an
`http`/`https` address; anything else is ignored (the badge still shows, it just
isn't a link). Clicking a badge link opens it with Omniscio's normal external-link
opener, exactly like any other link in a message.

### Safety guarantees

Because chat text can come from an AI, Omniscio renders these badges defensively:

- **No raw HTML.** A badge is a real Omniscio UI component, not injected markup —
  a rule can't smuggle HTML or scripts into a message.
- **`http`/`https` links only.** Any other scheme (`javascript:`, `file:`, …) is
  refused, so a link can never run code or reach the local machine.
- **Bad or dangerous regexes can't break the app.** A pattern that fails to
  compile is skipped, never thrown; a **zero-width** match (one that matches
  "nothing") is stepped over so it can't loop forever; and both the amount of text
  scanned per message and the number of badges per text node are capped, so a
  greedy or pathological rule can't wedge a message.
- **Code and links are left alone.** Matching runs on the parsed message
  structure *after* Markdown is understood, and deliberately **skips code blocks,
  inline code, and existing links** — so your rules never rewrite a code sample
  and never nest a badge inside a link, and they can't break bold text, headings,
  or other Markdown.
- **Zero cost when unused.** If you have no rules (or the master toggle is off),
  the message-render path is exactly what it always was — nothing extra runs and
  there is no performance cost.

The rules run entirely on your device as part of drawing the message; nothing is
sent anywhere, and there is no AI/token cost.

## For agents

### Where it lives

- Setting keys: `customRenderRules` (the list of rules) and
  `customRenderRulesEnabled` (the master toggle) — see
  [settings-reference.md](settings-reference.md).
- Shape + validation: [custom-render-rules-settings.ts](../../src/shared/types/settings/custom-render-rules-settings.ts)
  (tones, icon whitelist, template fields, and the size caps) and its IPC schema
  [custom-render-rules-settings.ts](../../src/shared/ipc-schemas/settings/custom-render-rules-settings.ts).
- Settings UI: [CustomRenderRulesSettings.tsx](../../src/renderer/src/features/settings/sections/session/CustomRenderRulesSettings.tsx)
  (add/edit/reorder/toggle/delete + the live "test it" preview).
- Matching engine (pure, unit-testable): [custom-render-rules.ts](../../src/renderer/src/lib/custom-render-rules.ts)
  — compiles rules, applies the `$`-templates, splits text into text + badge
  segments, and holds the `http`/`https`, zero-width, and cap guards.
- Render integration: [rehype-custom-render-rules.ts](../../src/renderer/src/lib/rehype-custom-render-rules.ts)
  — a rehype pass that runs inside the lazy Markdown chunk and skips `code`/`pre`/`a`
  nodes; the badge component is [AmcRenderRuleBadge.tsx](../../src/renderer/src/components/ui/AmcRenderRuleBadge.tsx);
  the compiled rules reach it via [useCompiledRenderRules.ts](../../src/renderer/src/hooks/useCompiledRenderRules.ts).
- Rulebook + invariants: `.claude/memory/contracts/custom-render-rules-contract.md`.

## Related

How the rest of a message renders around your badges — the prose, the tool activity, the code — is on the [Agent message display](agent-message-display.md) page, and [Mermaid diagrams](mermaid-diagrams.md) is the other automatic, safe transform applied to chat text. Because the rules are stored as ordinary settings, they are also listed with every other one on the [Settings reference](settings-reference.md) page.

- [agent-message-display.md](agent-message-display.md) — how the rest of an
  agent's message (prose, tool activity) renders around your badges.
- [mermaid-diagrams.md](mermaid-diagrams.md) — another safe, automatic transform
  of chat text (fenced diagrams into pictures).
- [settings-reference.md](settings-reference.md) — the full list of settings,
  including `customRenderRules` and `customRenderRulesEnabled`.
