prismantis
AGENTS.md324 starsChanged 5 days agoMITView on GitHub
Prismantis is a Claude Code mod that redraws assistant replies with themeable colors: tables, headings, lists, quotes, code, numbers, paths, links and mermaid diagrams. It ships as a single plugin from this repo, which is also its own marketplace. Run all of these before every commit: tsc -p . needs plugin/.claude-plugin/types/, which appears after running claude --plugin-dir plugin once. CI gates live in .github/workflows/ci.yml. Tests prove the tree; only a real render proves the look. Any change to what gets…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,700 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository6 other files it gives its agents.
- .claude/CLAUDE.mdCLAUDE.md
- add-themeSkill
- demoSkill
- drive-checkSkill
- live-checkSkill
- releaseSkill
The file
We split this AGENTS.md into the rules it gives an agent
9 rules. About 0 are common, 4 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 16
Run all of these before every commit:
- Distinctive: line 47
No code comments. The why goes in the commit message or PR description.
- Distinctive: line 48
Never copy code from other projects, including other mods.
- Very specific: line 50
Every user-visible feature ships with a sample in /prismantis demo (showcaseText in plugin/hooks/help.ts), and in the one-screen …
- Very specific: line 55
Add a dependency only when writing it ourselves is unreasonable.
- Very specific: line 80
Add the field to userConfig in plugin.json with a title, a description and a default.
- Very specific: line 81
Read it in resolveStyle in plugin/hooks/theme.ts, falling back safely on bad input.
- Distinctive: line 82
Add a row to the README options table.
- Very specific: line 83
Add a test using test(name, { options: {...} }, ...).
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md
Prismantis is a Claude Code mod that redraws assistant replies with themeable colors: tables, headings, lists, quotes, code, numbers, paths, links and mermaid diagrams. It ships as a single plugin from this repo, which is also its own marketplace.
Layout
plugin/is the Claude Code plugin and the only folder installed. Tests, scripts and docs stay outside it, so installs and the Claude directory scan never see them.claude plugin testloads only the folder it is given, sonpm --prefix scripts testruns it on a temp copy ofplugin/plustests/.plugin/hooks/register.tsxholds every hook and all code that calls$. Every otherplugin/hooks/*.ts(x)file is pure.plugin/.claude-plugin/plugin.jsonis the manifest and every user option (userConfig);plugin/types/index.d.tsis the$.prismantiscontract other mods type against.plugin/hooks/vendor/is generated bynpm --prefix scripts run build:vendor, never edited by hand. The build patches beautiful-mermaid six times: a step limit on edge routing so an unroutable edge throws and the diagram falls back to its source instead of hanging, to drop once upstream PR 66 merges, adjustable chart size, a bar chart scale measured from the axis line, with bars drawn to the half cell in half blocks so they reach exactly the gridlines at or below their value and lines passing behind them, the edge-label fix from upstream PR 157, to drop once it merges, flowchart node names that stop before an arrow's dashes, to drop once upstream issue 140 is fixed, and a rank table past its fixed 100 slots, so a flowchart more than 25 ranks deep lays out instead of failing.codex/,.codex-plugin/and.agents/plugins/marketplace.jsonare the Codex plugin and its marketplace, generated from the Claude Code source bynpm --prefix scripts run build:codex, never edited by hand: the hint fromHINTandFIGURE_HINT,$prismantisfromshowcaseText, the.tmThemefiles fromPRESETSthroughPRISM_COLORS. PRs leave them alone. The release commit regenerates them, and CI checks them only whileplugin.jsonholds a version with no tag yet.opencode/is the OpenCode plugin, generated by the samebuild:codexfromscripts/opencode/server.ts(session note,/prismantisdemo) andscripts/opencode/tui.ts(figure renderer,/prismantis-themes), with themes fromPRESETS. Same rules ascodex/.@opentui/coreis resolved by OpenCode at runtime and stays external.
Verify
Run all of these before every commit:
claude plugin validate plugin
npm --prefix scripts test
tsc -p .tsc -p . needs plugin/.claude-plugin/types/, which appears after running claude --plugin-dir plugin once. CI gates live in .github/workflows/ci.yml.
Tests prove the tree; only a real render proves the look. Any change to what gets drawn needs a live-check render of /prismantis demo (and /prismantis when the help changed), looked at before the PR opens and attached to it.
Render and performance regressions:
npm --prefix scripts run snapshot # demo.md drawn in 3 themes vs tests/snapshots, color and structure
npm --prefix scripts run bench:check # timings vs docs/bench-baseline.json (x1.6, normalized by a calibration loop) and node counts (+10%)CI gates snapshots and node counts but only prints timings (bench:check -- --no-time), because the calibration ratio differs between an M-series laptop and a Linux runner. Run the full check locally before a release. After an intended visual change run snapshot:update and review the diff; after an intended speed or size change run npm --prefix scripts run bench -- --update.
CI also fails when a file's cognitive complexity grows: the sum of how far each function goes past 15, as Biome measures it. Split the function instead. When a change lowers it, run npm --prefix scripts run complexity:update so the lower number becomes the new limit.
Claude Code refuses any tree over 20000 nodes and silently draws its own text, so a node-count rise lowers that ceiling (about 500 highlighted code lines, 1000 table rows).
Rules
SCOPE.md says what fits in prismantis and what to ask about first. Check a change against it before writing code.
Code:
- No code comments. The why goes in the commit message or PR description.
- Never copy code from other projects, including other mods. Read them to learn the API, then write our own.
- Full customization is the product. When someone asks to hide, toggle or customize part of the drawing, the answer is yes unless there is a concrete reason to object (security, a mod-API limit, a real cost); treat such issues as accepted. Otherwise add no feature flags or config knobs. The exception is looks: a feature with more than one plausible look ships its top 3 or 4 styles behind one option (like
taskStyle,promptStyle), the maintainer picks the default, every style is a step in/prismantis setup, and each style has a real screenshot in the README next to the option. - Every user-visible feature ships with a sample in
/prismantis demo(showcaseTextinplugin/hooks/help.ts), and in the one-screen/prismantishelp (helpText) when it fits. Extend the help tests intests/regressions.test.tsxso dropping the sample fails.
Dependencies and licenses:
- Bundled code and copied palettes must be MIT. Check the license at the source repo, not a port or fork: GitHub's
license.spdx_idmisses licenses declared only in a README (Gruvbox), and ports can relicense (Tokyo Night's Neovim port is Apache-2.0, the original VS Code theme is MIT). - Add a dependency only when writing it ourselves is unreasonable. Use its latest release, prefer well-starred maintained projects, and record it in plugin/THIRD_PARTY_NOTICES.md. The bundled runtime dependencies today are beautiful-mermaid and Prism. esbuild is build-time only.
- Two external programs can run: the HTML table copy and PNG image copy actions run macOS's built-in
osascript, Windows' built-inpowershell.exe, or an installed and running CopyQ on Linux (HTML only), and LaTeX math runs RaTeX'sratex-render, installed by the person and off until they setlatex. Nothing else runs. - Plugin names cannot start with
claude-,anthropic-orcc-plugin-, and must not use other products' trademarks (no "Codex" in names). - Feature and fix PRs leave
docs/CHANGELOG.mdand the version alone, and say what changes for the user in the PR description's "What changes for the user" section. The release commit writes the version's CHANGELOG section from those, so parallel PRs never conflict over it.
Mod API facts that bite
$cannot cross an import. Any function that takes$must be declared inplugin/hooks/register.tsx.claude plugin validatedoes not catch this;claude plugin testdoes ("hooks module did not load").- A render hook may not write
$.state. Schedule work with$.clock.after(0, ...)and write from there;read($, atom)in the render subscribes and redraws when the value lands. - The built-in
Markdownelement has no theming props, which is why we parse and draw markdown ourselves. TextPropshas color, background, bold, italic, underline, strikethrough, dimColor and inverse. There is no font size on any surface.Imagedraws only in terminals with the kitty graphics protocol (kitty, Ghostty); elsewhere it shows itsalttext.- Installed (user-tier) plugins cannot change the system prompt: the built-in
sec-defaultplugin skips theirprompt.compose,prompt.sectionandprompt.contexthooks. Add model-only context throughprompt.submitinstead. Tests do not runsec-default, so prove prompt changes in a liveclaude --debugsession. userConfigvalues are flat primitives. Astringfield withoptionsbecomes a picker in/config.- Hooks run without Node: no
require, no bare package imports, no dynamicimport(). Vendor libraries as one ESM file. - The authoritative API is the
.d.tsClaude Code lays inplugin/.claude-plugin/types/afterclaude --plugin-dir plugin. Grep it before guessing a prop or event.
Test-kit gotchas
ui.find({ text: 'x' })matches substrings, so it returns the parent line. Anchor it:text: /^x$/.- A test whose plugin calls
next(e)needs an engine stand-in:on('ui.render', ($, e) => <Text>engine</Text>), returning a tree, notnull. - Loop visual tests over
['terminal', 'desktop'] as const.
Adding an option
- Add the field to
userConfiginplugin.jsonwith atitle, adescriptionand adefault. - Read it in
resolveStyleinplugin/hooks/theme.ts, falling back safely on bad input. - Add a row to the README options table.
- Add a test using
test(name, { options: {...} }, ...).
Skills
| Skill | When |
.claude/skills/add-theme | adding or renaming a color preset |
.claude/skills/demo | printing the demo reply to eyeball every feature |
.claude/skills/live-check | seeing a change render in a real session |
.claude/skills/drive-check | pressing keys in a pane or button before merging, in a throwaway config |
.claude/skills/release | cutting a version |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

