A modern TypeScript monorepo template (pnpm workspaces, Turborepo, oxlint, oxfmt, tsdown, Vitest, and Changesets).
A drop-in monorepo starter. Fork it, rename a few fields, and you have a production-ready repository with build, test, lint, format, release and CI already wired up.
Every agent reads from the same source: AGENTS.md plus the Agent Skills in .agents/skills/.
Tool-specific files are symlinks, not copies, so nothing drifts out of sync.
The badges link to the steps below rather than installing anything directly: neither tool has a URL scheme yet for installing a plugin from a third-party marketplace. Cursor's one deeplink is for MCP servers, and the Claude Code equivalent is an open feature request.
Claude Code
claude plugin marketplace add stijnvanhulle/template
claude plugin install toolkit@stijnvanhulleReads CLAUDE.md (a symlink to AGENTS.md) and installs the toolkit plugin: rules, skills,
slash commands, and the code-reviewer subagent. Other projects can install the same plugin
without cloning this repo — see tools/claude/README.md.
Cursor
# agent is the Cursor CLI
agent plugin marketplace add https://github.com/stijnvanhulle/template
agent plugin install toolkit@stijnvanhulleReads AGENTS.md natively and installs the matching Cursor plugin: rules (as .mdc files), the
same slash commands, and the code-reviewer subagent. Other projects install it from
.cursor-plugin/marketplace.json — see tools/cursor/README.md.
Gemini CLI
gemini extensions install https://github.com/stijnvanhulle/templateInstalls the extension from gemini-extension.json at the repo root, which is where Gemini
looks. It reads GEMINI.md and the eight slash commands in commands/*.toml. Gemini has no
on-demand skill loading, so GEMINI.md is generated as AGENTS.md plus the conventions
inlined, rather than symlinked like the other agents' instruction files. No subagent concept
either, so code-reviewer has no equivalent. See
tools/gemini/README.md.
OpenCode
git clone https://github.com/stijnvanhulle/template.gitReads opencode.json and AGENTS.md from the repo root, and picks the toolkit up through
.opencode/, already wired in this repo. OpenCode uses the same command syntax Claude Code
does, so its commands/ is a symlink to the Claude ones rather than a copy. The
code-reviewer subagent works here too, invoked with @code-reviewer. To wire it into another
project, see tools/opencode/README.md.
Codex
mkdir -p ~/.codex/prompts
ln -s "$PWD/tools/codex/prompts"/*.md ~/.codex/prompts/Reads AGENTS.md natively, so instructions and conventions need no setup. Only the commands
need linking, and because Codex discovers prompts from ~/.codex/prompts/ rather than the
repo, each person links them once. .codex-plugin/plugin.json at the repo root describes the
same content for the Codex plugin marketplace. The prompt format matches Claude Code's, so
prompts/ is a symlink, not a copy. See tools/codex/README.md.
Other agents
Nothing to install. These read AGENTS.md directly, or through a symlink, with no plugin step
and no slash commands.
- GitHub Copilot (VS Code) reads
.github/copilot-instructions.md. - Kiro reads
.kiro/steering/and Zed reads.zed/. Both are symlinks back toAGENTS.md. - Amp, Jules, and anything else that speaks the AGENTS.md convention read it directly.
AGENT.mdis symlinked too, for the tools that look for the singular spelling. - Aider takes it as an argument:
aider --read AGENTS.md.
Every agent shares one toolset, so a skill or command written once works in all of them:
| Path | What it does | When it loads |
|---|---|---|
.agents/skills/conventions/ |
Rules: code style, JSDoc, markdown, plain language, security, testing, USA English | Session start, plus path-scoped rules when a matching file opens |
.agents/skills/ |
Playbooks: backlog, branch, changelog, changeset, deslop, documentation, humanizer, issue, jsdoc, pr | On demand, when a task matches the skill |
tools/*/commands/backlog |
/backlog works through the latest open issues, one worktree and subagent per issue |
When you type the command |
tools/*/commands/create-branch |
/create-branch cuts a Conventional Commit branch from the issue it belongs to |
When you type the command |
tools/*/commands/create-changeset |
/create-changeset creates a changeset with the right semver bump |
When you type the command |
tools/*/commands/create-issue |
/create-issue opens a GitHub issue with the type, labels, and fields filled in |
When you type the command |
tools/*/commands/create-pr |
/create-pr runs the pre-push checks, adds a changeset when one is needed, and opens the pull request |
When you type the command |
tools/*/commands/deslop |
/deslop audits the current branch's changes for AI-generated code smell (over-engineering, code style tells, and prose humanizing) and applies only what you confirm |
When you type the command |
tools/*/commands/humanizer |
/humanizer removes AI writing patterns from the prose changed on the current branch |
When you type the command |
tools/{claude,cursor,opencode}/agents/ |
Subagents with their own context window (code-reviewer). Not supported by Gemini CLI or Codex |
When delegated a matching task |
tools/claude/output-styles/ |
System-prompt modes: house (default), plan, diagrams-first. Claude Code only |
Session start, or when selected |
Each agent's plugin manifest sits at the repo root, where its CLI looks for it, and points back
at the shared content under tools/: .claude-plugin/, .cursor-plugin/, .codex-plugin/,
gemini-extension.json, and opencode.json. Gemini also needs its commands/ beside the
manifest, so the root commands/ symlink points at tools/gemini/commands.
Commands live once per format, not once per agent. OpenCode and Codex use Claude Code's command
syntax, so their folders are symlinks to tools/claude/commands/. Cursor and Gemini CLI need
their own formats (.mdc rules, .toml commands), so those are real files, and
pnpm agent-files checks in CI that they still expose the same command set. It also regenerates
GEMINI.md, the one generated file, with pnpm agent-files --write.
.claude/, .cursor/, .gemini/, and .opencode/ are workspace config, symlinked into their
tools/ folders so this repo runs the same plugins it distributes.
- Click Use this template on GitHub.
- Update
package.jsonname/namespace,repository.url, and the author block. - Replace
packages/coreandpackages/demowith your own packages (keepinternals/utilsif useful). - Update
oxlint.config.ts/oxfmt.config.tsignore patterns if needed. - Update
.changeset/config.jsonchangelog.repoandfixed/ignorearrays. - Update
tsconfig.jsonpathsto match the new packages. - Edit
README.md,AGENTS.md,CLAUDE.md,CONTRIBUTING.md,SECURITY.mdfor the new project. - Push to
main. CI runs immediately.
This template uses Changesets:
pnpm changeset # Add a changeset entry describing the change
git commit -am "feat: ..."
git pushWhen changesets land on main, the release.yml workflow opens a "Version
Packages" PR. Merging that PR publishes the affected packages to npm with
provenance.
pnpm upgrade && pnpm installThe upgrade script runs taze
with --maturity-period 3 so new releases need at least 3 days of soak
time before being adopted.
See CONTRIBUTING.md for the project structure, prerequisites, local setup, and commands.
MIT © Stijn Van Hulle