Skip to content

Latest commit

 

History

History
230 lines (177 loc) · 11.6 KB

File metadata and controls

230 lines (177 loc) · 11.6 KB

The GitBot library: folder schema

How a published bot is stored in the library repo — gitbot-hq/Library — and why each part is shaped the way it is.

A published bot has to satisfy two different readers at once:

  • The discover page, which needs enough copy and artwork to render a card and a detail panel.
  • The gitbot harness, which needs a real bot definition — the standing job, the agent, the permission mode — so that "Install" produces a working bot rather than a plausible-looking one.

One folder carries both.


Layout

One bot per folder, under bots/. The folder name is the bot's slug and is the stable key for everything else.

bots/
  pr-guardian/
    bot.json           required — all structured fields
    instructions.md    required — the bot's standing job, in prose
    setup.md           optional — machine preparation, only if genuinely needed

Nothing else goes in the folder. No images: the mascot is generated from body + color, and the author avatar is derived from the GitHub handle. No licence file either — the repository's root LICENSE is MIT and covers every bot, so there is no per-bot licence to declare and no licence field in bot.json. That is deliberate: someone browsing the discover page should not have to check the terms bot by bot before installing one.

At the repo root, index.json is generated by CI and is the only file the app fetches. Contributors never edit it, which keeps concurrent pull requests from conflicting on the same file.

Why the slug, not the name

The current detail panel looks a bot up with DETAILS[bot.name] and renders {bot && details && ...} — so when the two lists disagree by a single character, the card still looks right and the panel opens blank. Keying on a slug that is also the folder name removes the ability for the two halves to drift: they are the same directory entry.

Why instructions live in Markdown, not in JSON

The instructions are the bot. They are a few hundred words of prose that you, as the reviewer, have to actually read — that is the entire substance of the review. In JSON they arrive as one escaped line with \n in it, which is unreadable in a diff. In a .md file the pull request shows them as paragraphs. CI inlines them into index.json at merge, so the app still gets one file.


bot.json

{
  "$schema": "../../schema/bot.schema.json",
  "slug": "pr-guardian",
  "name": "PR Guardian",
  "description": "Reviews pull requests for risks before you merge.",
  "category": "Code review",
  "about": "A thoughtful second pair of eyes for your next pull request. Get a focused review that helps you understand what changed and where to look closer.",
  "features": [
    "Spot potential bugs and edge cases",
    "Understand risky changes in context",
    "Get clear, actionable review suggestions"
  ],
  "examplePrompt": "Review my current changes. Focus on bugs, edge cases, and anything I should address before merging.",
  "author": { "github": "mayachen", "name": "Maya Chen" },
  "mascot": { "body": "bear", "color": "brand-sun", "activity": "thinking" },
  "emoji": "🔍",
  "agent": "claude-code",
  "permissionMode": "ask-permissions"
}

Display fields

Field Required Shown as Limit
slug yes never shown; folder name and lookup key ^[a-z0-9]+(-[a-z0-9]+)*$
name yes card title, detail heading ≤ 24 chars, unique across the library
description yes the one line on the card ≤ 80 chars, one sentence, no trailing period needed
category yes eyebrow above the detail title from the fixed list below
about yes the "About this bot" paragraph 120–400 chars, 2–3 sentences
features yes checkmark bullets exactly 3, ≤ 60 chars each
examplePrompt yes the quoted prompt with the copy button ≤ 200 chars, written as a user would type it
author yes name beside the avatar see below
mascot no silhouette and brand colour defaults to ghost / brand-sun / idle

All seven of the first group are required by the schema, which is the point: today a missing about or features leaves the card looking correct and the panel blank. A required field turns that silent runtime blank into a loud CI failure on the pull request, before you ever look at it.

category is a closed list so the discover page can group and filter. Start with: Code review, Developer workflow, Releases, Maintenance, Repository care, Code exploration, Testing, Documentation. Adding a category is a maintainer decision, made in the schema — not something a contributor can do by typing a new string.

author

"author": { "github": "mayachen", "name": "Maya Chen" }

github is the handle; the avatar is https://avatars.githubusercontent.com/mayachen and is derived at index time, never stored. CI checks the handle matches the pull request author, so a contributor cannot publish under someone else's name.

verified is deliberately not a field in bot.json. It lives in a root-level verified.json that only maintainers can change (CODEOWNERS). A badge that a contributor can grant themselves is not a badge.

mascot

"mascot": { "body": "bear", "color": "brand-sun", "activity": "thinking" }
  • body — one of the 18 silhouettes in gitbot's mascot artwork: bear, belly, birdy, birdy-3, bunny, burdy2, cat, cloud, doggy, fire, flower, ghost, heart, moon, rectangle, star, triangle, tulip.
  • color — a token name from gitbot's brand palette: brand-sun, brand-candy, brand-ember, brand-leaf, brand-sky, brand-honey. Not a hex value and not var(--brand-sun). The index maps the token to the CSS variable, so themes stay coherent and no off-brand colour gets in.
  • activity — the resting expression: idle, reading, listening, thinking, working, success, error, sleeping. This field is easy to forget when listing "the eight fields", but both the card and the detail hero pass it to MarketplaceMascot. Default idle.

Defaults mean a bot with no mascot block renders — as the same yellow ghost as every other bot that skipped it. So CI treats a missing mascot as a warning on the pull request, not a failure: it does not break the page, it just makes the library look monotonous. A gentle nudge in review is the right pressure.

Caveat worth knowing: facePlacement in gitbot's mascot registry has tuned coordinates for 13 of the 18 bodies. ghost, cloud, birdy, burdy2 and rectangle fall back to default placement. They are used in the shipped design and look fine — this is a note for whoever adds new artwork, not a restriction on contributors.

Behaviour fields

These are what makes the installed bot real, and they mirror the Bot type in gitbot's src/bot-store.ts exactly.

Field Required Notes
agent yes claude-code, opencode or codex. codex supports no tool fence and no per-call approval — a bot that depends on either cannot use it.
permissionMode yes ask-permissions, auto-approve or plan. Library default is ask-permissions; reviewers and explainers should be plan.
emoji yes single emoji, used wherever the mascot is not rendered
model no required when agent is opencode, as provider/model
allowedTools no a fence: if set, these are the only tools the bot may use
disallowedTools no not enforced on codex

auto-approve in a published bot deserves scrutiny in review — it is someone else's machine that acts without asking. Pair it with an allowedTools fence or send it back.


instructions.md

The whole file is the bot's standing job. No frontmatter, no title heading — the text is used verbatim as instructions, and gitbot wraps it in its own frame ("You are name, an agent with one standing job…", see gitbot's src/bot-prompt.ts).

That framing dictates how it must be written: imperative, addressed to the agent, and complete enough to start from a bare "hi" as the first message. gitbot's bot authoring prompt §2 covers this in full and is the reference for contributors.

One extra rule for published bots that does not apply to private ones: no paths, usernames, repo names or machine details from the author's computer. This text runs on strangers' machines.

This replaces prompt synthesis

Worth calling out for whoever wires the install path up: today gitbot's marketplace-bot-details.tsx builds instructions on the fly out of the name, description and feature bullets. That was a reasonable placeholder for eight hardcoded demos, but it means the installed bot's actual behaviour is a side effect of marketing copy. Once bots come from the library, install should use instructions from the index and nothing else.


setup.md

Optional, and usually absent. Present only when the job is impossible without something installed or configured on the machine — gh authenticated, ffmpeg on PATH.

The stakes are asymmetric and worth restating: a bot with setup instructions refuses all work until a setup run reports SETUP_COMPLETE. An unnecessary or unachievable setup step does not degrade the bot, it disables it, on every machine that installs it. In a library that is shared with strangers, an empty setup.md is very often the correct answer.

Write each step as a condition plus the check that proves it — "gh is installed and authenticated; confirm with gh auth status" — not as a command for one operating system. Anything only a human can do (a password, a licence, a paid plan) is written as "ask the user for X and wait": the setup run is an ordinary conversation and can ask.

Do not mention the SETUP_COMPLETE / SETUP_FAILED markers in the file. gitbot supplies them.


index.json, and what CI enforces

CI runs on every pull request and regenerates index.json on merge to main. The validator fails the pull request when:

  • a required field is missing or empty — the blank-panel bug, caught at source;
  • slug does not equal the folder name, or collides with another bot;
  • name collides with another bot (the UI keys on it in places, and two identical cards is a bad browsing experience regardless);
  • features is not exactly 3 entries, or any length limit is exceeded;
  • category, mascot.body, mascot.color, mascot.activity, agent or permissionMode is outside its enum;
  • agent is opencode and model is absent;
  • instructions.md is missing, empty, or over ~600 words;
  • author.github does not match the pull request author;
  • the pull request touches more than one bot folder, or edits index.json or verified.json;
  • the bot folder contains anything other than bot.json, instructions.md and setup.md — a licence file included, since the root MIT licence is the only one;
  • the diff contains an absolute home-directory path or anything shaped like a credential.

Everything above is mechanical. What CI cannot judge — and what your review is actually for — is whether the instructions do what the description claims, and whether the permission mode is justified by the job.

An entry in the generated index is the flattened bot: every field from bot.json, plus instructions and setupInstructions inlined from the Markdown files, plus the derived authorPhoto and the resolved colour variable, plus verified from verified.json.