Imported from Zidane786/slate (
AGENTS.md). Install upstream withnpx skills add Zidane786/slate. Copyright stays with the author.
AGENTS.md — working on the Slate repo
This repo is Slate, a Claude Code (and GitHub Copilot CLI) plugin: plan ideas into plain-language tickets on a kanban board inside a project, then build them one ticket at a time with tests, review, the user's own check, and the commit/PR recorded on the ticket — always with a human in the loop.
CLAUDE.md is an exact copy of this file for Claude Code. Edit both together.
1. Read first
| Need | Read |
|---|---|
| What Slate is, every decision | docs/specs/2026-09-26-slate-design.md |
| How a release was built (contracts) | docs/plans/*-build-plan.md (newest last) |
| User-facing overview | README.md, plugins/slate/README.md |
Every board.py command, "use it when…" |
plugins/slate/reference/commands.md |
| What changed per version | plugins/slate/CHANGELOG.md |
| How to test on a machine by hand | TEST.md |
| Rejected designs kept for reference | docs/archive/ |
2. Layout
.claude-plugin/marketplace.json marketplace "slate" → plugins/slate
plugins/slate/ the installed plugin (only this folder ships)
.claude-plugin/plugin.json name + VERSION (source of truth for the plugin version)
skills/<name>/SKILL.md /slate:init plan work review status sync upgrade
assets/board/ copied into each project's kanban/ by init/upgrade
board.py the ONLY writer of tickets.json (CLI + serve API)
index.html the board page (one file, no deps)
README.md board docs copied into projects
hooks/ hooks.json, run.sh / run.cmd (python launchers), guard_tickets.py, session_start.py
templates/ SLATE.md, CLAUDE.md, AGENTS.md, plan-doc.md for projects
reference/commands.md shared command reference all skills link
upgrades/<version>.md per-release "What's new" + upgrade steps
CHANGELOG.md README.md
tests/ pytest suite (+ fixtures/board-demo for the UI)
.github/workflows/test.yml CI: Windows/macOS/Linux × Python 3.9/3.13
.github/workflows/release.yml publishes vX.Y.Z releases from the CHANGELOG on merge
scripts/release_notes.py prints a version's release notes from the CHANGELOG
TEST.md hands-on test guide for any machine
docs/ specs, build plans, archive
3. Rules that must hold in every change
- Standard library only, Python 3.9+, in everything that ships (board.py, hooks). No
pip dependencies.
index.htmlloads nothing from the internet. - Works on Windows, macOS, Linux, over SSH and in tmux. Every Python entry point (board.py,
hooks, scripts) reconfigures stdout/stderr to UTF-8; every text read/write and subprocess call
names
encoding="utf-8"(tests/test_portability.pyenforces both). UTF-8 +\nfor every file write, pathlib, noshell=True, no POSIX-only calls without a Windows path. Hooks go throughhooks/run.sh(finds python3 / python / py -3); on Windows, Copilot CLI runs each hook'spowershellcommand, which goes throughhooks/run.cmd(py -3 / python / python3). board.pyis the only thing that changestickets.json. Every write validates the whole board, takes the write lock, writes atomically. The guard hook blocks direct edits; don't weaken it.- Every error/refusal is actionable:
error: <ID> <field>: …thenfix: <exact command>orask the user: …. A test asserts this for every refusal path. - Backwards compatible. Existing boards must keep loading. Schema changes are additive and go
through
migrate(bumpSCHEMA_VERSIONonly when needed). - Human in the loop, always. Skills do one ticket per request, ask before choices, never merge, never force-push. The unlock needs the user's approval (Claude Code's card in Manual / Accept edits / Auto; Copilot CLI's card in every interactive mode; typed code in a terminal otherwise); one unlock = one edit.
- Tickets are for non-technical readers (summary, story, picture, "done when", "try it yourself"); technical notes stay collapsed.
- Product text never mentions other internal projects (e.g. "Forge"). Slate is generic.
- Claude Code and GitHub Copilot CLI, one plugin. Copilot CLI loads the same
.claude-plugin/manifest, skills and Claude-formathooks.json. Hook code must work for both: Copilot sends apply_patch text for edits, nopermission_mode,tool_result(nottool_response), hides exit-2 stderr (refuse with JSON whenCOPILOT_CLIis set) and needs{"additionalContext"}at session start. Every hook has apowershellcommand (Windows Copilot).tests/test_copilot.pypins all of this. VS Code Copilot Chat isn't supported yet; don't add half-support.
4. Develop and test
uv run --with pytest pytest -q # full suite (≈960 tests)
uv run --python 3.9 --with pytest pytest -q # oldest supported Python
claude plugin validate --strict .
claude plugin validate --strict plugins/slate
- Write tests first for every change: happy path + every refusal. UI changes: static checks in
tests/test_index_static.pyplus a real-browser check (Playwright) againsttests/fixtures/board-demo, in live (board.py serve) and view-only mode. - Live-test skills in a throwaway repo:
claude --plugin-dir plugins/slate. - CI (
.github/workflows/test.yml) runs on every PR and push tomain, but the full suite runs only when one of these changed:plugins/**,tests/**,scripts/**,.github/workflows/**,.claude-plugin/**,.gitattributes. Docs-only changes (README, TEST.md, CLAUDE.md, AGENTS.md, SECURITY.md,docs/**) pass in seconds with "no code changed". A manual run always runs everything. Keep this list and the workflow's list in step. tests/test_docs_consistency.pyfails if a skill/doc mentions a command that doesn't exist, or a skill doesn't link the reference — keep it green.
5. Keeping docs in step (do this in the SAME change as the feature)
Every feature, fix or behaviour change updates all that apply, before it's considered done:
-
plugins/slate/reference/commands.md— new/changed commands and flags, "use it when…". - Skills (
plugins/slate/skills/*/SKILL.md) that should use or mention it. -
plugins/slate/templates/SLATE.mdif projects need to know or configure it. -
plugins/slate/assets/board/README.md(copied into projects) for board/CLI changes. -
README.mdandplugins/slate/README.mdfor anything user-visible. -
plugins/slate/CHANGELOG.md— plain-words entry under the next version. -
plugins/slate/upgrades/<next-version>.md— "What's new" line + upgrade step if existing projects need anything (settings, .gitignore, SLATE.md, migrate, questions). -
TEST.md— add or adjust the hands-on check for the feature (and the expected result). - Spec (
docs/specs/…) for new decisions or commands. - Tests — unit tests, docs-consistency, and UI static checks as relevant.
- This file and
AGENTS.mdif the rules, layout or workflow changed.
6. Releasing a version
Every PR that changes plugins/** is a release. CI (scripts/check_version_bump.py) fails
unless it bumps the version above main's and adds that version's CHANGELOG section; there is no
"Unreleased" section. Claude Code only updates installed plugins when the version changes, so an
unversioned change would never reach users. Docs-only PRs outside plugins/ need no bump.
Each CHANGELOG section lists only what changed since the previous version; a released
version's section is frozen (the same CI check fails if it changes). New changes go under the
new version.
- Bump the version in all of:
plugins/slate/.claude-plugin/plugin.json,board.py(SLATE_VERSION, header line),index.html(slate-versionmeta),templates/SLATE.md(first line), andSCHEMA_VERSION+migrateif the schema changed. - Finish
CHANGELOG.mdandupgrades/<version>.md(What's new first, then steps). The CHANGELOG section for the version is## X.Y.Z — YYYY-MM-DDwith the headings Highlights, Added, Changed, Fixed, Security, Removed, Upgrade notes (leave out empty ones).tests/test_release_notes.pyenforces this; preview the notes withpython3 scripts/release_notes.py. - Full suite on 3.13 and 3.9,
claude plugin validate --strict,TEST.mdlevels 3–4 on at least one machine, CI green on all three OSes. - Branch
feat/<version>, draft PR with summary, verification and follow-ups; merge only when the user says so. Default branch ismain, protected by a ruleset: no direct pushes (PR required), all 6 CI checks must pass, no force-push or deletion, no bypass. Merged branches are deleted automatically. - Releases are automatic: when a merge to
maincarries a new version inplugin.json,.github/workflows/release.ymltagsvX.Y.Zand publishes a GitHub Release with that CHANGELOG section. Don't create release tags by hand (tagsv*are protected).
7. Commits
Small, focused commits: <area>: <what changed> with a short body listing verification. Never
commit generated files (__pycache__, .pytest_cache, .DS_Store — see .gitignore).
