Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
git clone --depth 1 https://github.com/louisbrulenaudet/monorepo-templateWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/rules/louisbrulenaudet/monorepo-template/release)<a href="https://agentmods.dev/rules/louisbrulenaudet/monorepo-template/release"><img src="https://agentmods.dev/badge/rules/louisbrulenaudet/monorepo-template/release/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/rules/louisbrulenaudet/monorepo-template/release"><img src="https://agentmods.dev/badge/rules/louisbrulenaudet/monorepo-template/release.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00000 | $0.03654 |
| Opus 5.5 | $0.00000 | $0.01462 |
| Sonnet 5.5 | $0.00000 | $0.00731 |
| Haiku 4.5 | $0.00000 | $0.00365 |
Grade A, and why
release scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured today.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 70 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Releases
Changesets computes versions; the pipeline is .github/workflows/release.yml - read it for the job list. Human-facing "how do I": .changeset/README.md; writing a changeset: changesets.mdc. CI internals: ci.mdc; the deploy: cd.mdc.
Nothing is published to npm: every workspace is private: true, with no publishConfig and no .npmrc. A release is a git tag plus a Cloudflare Workers promote.
State machine
push to main ──► Release (concurrency release-main, queue: max, never canceled)
├─ gate ALWAYS. uses ci.yml (full graph, not --affected)
├─ select-mode 'version' | 'none' ('publish' is unreachable here)
├─ mode == 'version' → version → open/update the "chore: release" PR
│ → dispatch ci.yml on changeset-release/main [END]
└─ mode != 'version' → tag (needs gate) → created? → deploy → uses cd.yml
Invariants
gateruns on every push to main, in both modes. While a release PR is open the mode is alwaysversion, so a gate only on the release path would leavemainunvalidated for that PR's whole life. Never move it under themode != 'version'branch.- The tag is the idempotency key.
.github/actions/release/create-release-tag.shskips whenvX.Y.Zexists and reportscreated=false;deployis gated oncreated == 'true', so re-runningReleasenever re-deploys. The existence probe is three-way: 2xx skips, 404 creates, any other failure fails the job rather than guessing. Redeploy on purpose withcd.yml'sworkflow_dispatchand the tag. mode != 'version', notmode == 'publish':select-modereturnspublishonly when publishable packages exist, and all of ours are private, so the equality test would never fire. Load-bearing.select-modeinstalls first: with no pending changeset, as on every push after a release PR merges, it runschangeset publish-planthroughrequire.resolve("@changesets/cli/bin.js")from the checkout, so withoutpnpm installthe job fails and no tag is cut. Only theversionbranch works without the CLI, which is why a missing install stays hidden while a release PR is open. Every package is private andprivatePackages.tagisfalse, so the plan is empty and the mode isnone.privatePackages.tag: falseis deliberate:changeset git-tag(v3's name forchangeset tag) would emit one<app>@X.Y.Zper app, while the deploy keys on one sharedvX.Y.Z, whichcreate-release-tag.shcuts instead.fixed: [["*"]]is the app set, resting on apps being unscoped: Changesets matches eachfixedentry with picomatch against package names, and*does not cross/, so the group is exactly the unscoped workspaces (the apps), never an@repo/*package; a new app joins the shared version by existing. Nothing machine-checks the naming underneath (.syncpackrc.json's@repo/**group governs dependency specifiers, not workspace names;pnpm boundariesnever reads a name), so naming.mdc keeps it by hand: an unscoped package underpackages/would silently join the group and bump to the app version.changelognames norepo:@changesets/changelog-githubfalls back toGITHUB_REPOSITORY, which Actions sets in theversionjob, so a repository created from the template links its own PRs and commits. Hard-coding the slug would point every derived changelog at this repository.changeset versionruns only in CI, so nothing local needs it.privatePackages.version: trueis load-bearing: v3 still defaults to{version: false, tag: false}, which would version nothing here.baseBranch: "main"restates the v3 default and stays because the bundledchangesets/actionsub-actions read the config with their own copy of@changesets/config.changedFilePatternsis the "what ships" list, matched with picomatch against paths relative to each package directory, so!*.mddrops only top-level docs (README.md,AGENTS.md,CLAUDE.md), never a Markdown file undersrc/. It has nodotoption: dotfiles never count, so a shipped dotfile (public/.well-known/*) needs its own pattern. Keep it aligned with the excludes of turbo'stransittask.ignore: ["@repo/vitest-config"]: that package is test tooling only, so a change to it never needs a changeset. The config rule that dependents of an ignored package must be ignored too skips devDependency edges, so the apps stay versionable. Never ignore a package an app bundles: its changes would stop requiring a changeset.formatstays at itsautodefault: Changesets runs oxfmt on every changeset and changelog it writes, so they passformat:check(the CLI writes---\n\n---for an empty changeset, which oxfmt rewrites).$schemapins the installed@changesets/configversion; bump it with@changesets/cli.release:check(changesets/check.mjs, its logiccheckChangesetsin changesets/lib.mjs) wrapschangeset status --since=origin/main --output, which exits 1 only when packages changed and no changeset changed since the merge base, and counts only tracked files (git diff), so a new changeset must be staged. Plainchangeset status(release:status) counts every pending changeset, so it cannot tell whether the branch added one. The JSON plan feeds the lint (app-only names, title length, headings,majorbehindCHANGESET_ALLOW_MAJOR). Editing any pending changeset satisfies the presence half: coarse by design, the lint and review cover the rest.- The changeset PR comment renders the gate's own result (changesets/comment.mjs):
changeset-pr-status.ymlrunscheckChangesets, so the comment and the CI Changesets step never disagree, andchangesets/action/pr-commentonly posts it under the default marker. Never go back tochangesets/action/pr-status: it takes no inputs, its add-a-changeset link prefills every changed workspace package (@repo/*and ignored ones included, whichrelease:checkrejects or Changesets refuses as a mixed changeset), an empty changeset reads as "included in the next version bump", and its no-changeset text assumes a non-blocking setup. The job installs becausechangeset statusneeds the CLI; it restores the pnpm store read-only (ci.mdc).changeset statusexits 1 both for a missing changeset and for a crash, so a non-zero exit with no.changeset/*.mdchanged since the merge base reads as missing, anything else as unavailable: the renderer exits 1 after writing that body, andpr-commentruns on!cancelled(), so a failed run replaces the comment instead of leaving the previous commit's. - Catalog bumps are checked separately (changesets/lib.mjs):
pnpm-workspace.yamlbelongs to no package, so Changesets never sees a catalog change.runtimeCatalogChangesdiffs thecatalog:/catalogs:specifiers against the merge base and keeps those an app lists underdependencies. A bump with no changeset in the branch fails the gate. In Actions the merge-basepnpm-workspace.yamlis read through the contents API with the job's read-onlyGITHUB_TOKEN, nevergit show: theblob:nonecheckout would fetch that blob lazily without credentials, which fails on a private repository such as one created from this template. Locally it isgit show. For the same reasonchangesets/lib.mjsrunsgitandchangeset statuswithdiff.renames=false(throughGIT_CONFIG_*): rename detection reads the blobs of every added/deleted pair, so a PR that renames files failed bothrelease:checkand the Release plan oncould not fetch … from promisor remote. Lockfile-only refreshes of a direct dependency are not detected; add lockfile importer diffing if they start to matter. - Dependabot changesets (dependabot-changesets.yml) commit one
patchchangeset per affected app as.changeset/dependabot-<PR>-<app>.md, reconciled to the desired state on every run, so a run that finds them current is a no-op. That no-op path needs no token, which matters because the run our own push triggers gets Actions secrets rather than Dependabot secrets.- The commit goes through GraphQL
createCommitOnBranchwithexpectedHeadOid: GitHub signs it, and it fails rather than overwrite a newer push. - It uses the
CHANGESET_BOT_TOKENDependabot secret (a fine-grained PAT, Contents: write), because Dependabot runs get a read-onlyGITHUB_TOKENand aGITHUB_TOKENpush would start no CI run. [dependabot skip]in the message keeps Dependabot rebasing the PR; a rebase drops the commit and the next run writes it again.pull_request, neverpull_request_target, and neverpnpm installin that job: only git and Node run while the token is in the environment. With the secret unset it prints a notice and exits 0, andci.ymlsetsCHANGESET_SKIP_RUNTIME_DEPENDENCIES=1for that Dependabot PR, so the gate warns instead of failing: a project created from the template works with no setup, and its Dependabot bumps ship without a release note until someone adds one. The flag reads the Dependabot secret store, which is what a Dependabot-triggered run sees.
- The commit goes through GraphQL
- The
versionjob dispatches CI on the release branch (actions: write, beside thecontents/pull-requests: writethatchangesets/action/versionneeds): the release PR is opened withGITHUB_TOKEN, so itspull_requestruns wait for approval and the required check comes only from that dispatch (ci.mdc). While a release PR is open, every push tomaintherefore runs the full graph twice, asgateand as the dispatch. - One contract comment on the release PR (release/comment-release-pr-contract.sh):
changesets/action/versionhas no PR-body input, so its "published to npm automatically" description stays and the comment corrects it.gh pr comment --edit-last --create-if-nonekeeps one comment across everyversionre-run;changesets/action/pr-commentcannot be used here because it only targets the PR that triggered the run. - The version PR branch is force-pushed, not accumulated: every push to
mainresetschangeset-release/mainfrom the tip, re-runschangeset version, and force-pushes one commit, so it is never behind or in conflict withmain, and manual edits to it are destroyed. release.ymlcallscd.ymldirectly because tags created withGITHUB_TOKENstart no workflow (cd.mdc); never "restore" a tag trigger.queue: max, not the default: withqueue: single, a third push replaces the pending run and that release is silently dropped.
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- today Changed · +1 lines c253356fb35f
- 3d ago Changed 44b4a96e1326
- 15d ago Changed 0a579a1892bb
- 20d ago Changed · +3 lines 4ea6b304030c
- 22d ago Changed · +15 lines b6c708de3ea0
- 23d ago Changed · -1 lines f2c76d24c9b4
- 24d ago Changed dca2d0e911be
- 25d ago Changed bcda0245d112
- 27d ago Changed · +1 lines 0544d1a6efb2
- 1mo ago First seen · 51 lines · 0 tokens per session scan A 02d8cc5e7d6a
release is a cursor rule published in the GitHub repository louisbrulenaudet/monorepo-template (19 stars, last pushed today), licensed Apache-2.0. It costs nothing until one of its globs matches a file; then it loads 3,654 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-03.
Other cursor rules, from other repositories
mcp-releasing
Steps and procedures for releasing MCP (Model Context Protocol) servers as NPM packages.
add-to-changelog
Update the project's CHANGELOG.md file with a new entry.
changelog-generator-manual
This rule generates a comprehensive changelog.md file by analyzing all git tags and commits, creating a chronological record of all project changes with proper semantic versioning structure. The changelog.md file is stored at the root of the project.
release-commit-analysis-auto
This rule analyzes commits to determine if they should trigger a version bump. It categorizes conventional and non-conventional commits into Features, Bug Fixes, Breaking Changes, Documentation, and Other. It uses intelligent keyword matching for non-conventional commits and analyzes file changes to help categorize…
release-git-tags-auto
This rule checks for existing tags before creating new ones. It also offers to push the tag to the remote repository. It runs when users request release creation, version bumping, or package publishing.
release-validation-auto
This rule validates release prerequisites including branch naming conventions and package.json structure. It runs when users request release creation, version bumping, or package publishing. The rule ensures releases only occur from appropriate branches (release/, hotfix/, fix/) and validates package.json exists with…