Skip to content

fix(cli): write Cursor rules as .mdc, the only extension Cursor reads - #133

Open
MajorLift wants to merge 1 commit into
mainfrom
jongsun/fix/cursor-rules-mdc-extension
Open

fix(cli): write Cursor rules as .mdc, the only extension Cursor reads#133
MajorLift wants to merge 1 commit into
mainfrom
jongsun/fix/cursor-rules-mdc-extension

Conversation

@MajorLift

Copy link
Copy Markdown
Contributor

Cursor has never read the rules this installer emits.

tools/install writes them to .cursor/rules/mms-<skill>/RULE.md. Cursor's docs state that project rules must use .mdc, and that a plain .md file there is ignored by the rules system because it carries no frontmatter that system can read. A fresh --repo metamask-extension install at cce2ee1 emits 89 .md and 0 .mdc.

Nothing else about the emission is wrong. description + alwaysApply: false is Cursor's apply-intelligently mode, and nested directories under .cursor/rules are documented as supported. The extension alone accounts for it.

What changed

write_cursor emits RULE.mdc. is_managed_project_skill still accepts RULE.md, because dropping it would make --prune-stale stop recognising every tree an older installer wrote and orphan it. write_cursor deletes that legacy file once the .mdc is written — but only when it carries the managed banner, so a hand-written rule of the same name is left alone.

Evidence

Reverting only tools/install and keeping the updated expectation turns the suite red, so the test discriminates rather than passing either way:

installer reverted   ✖ removes only stale installer-managed skills across project targets
                     ℹ pass 64  ℹ fail 1
installer restored   ℹ pass 65  ℹ fail 0

A fresh extension install on this branch emits 26 .mdc, 0 RULE.md.

Migration, run against a tree the old installer had already written:

install with base installer   RULE.md 26   .mdc  0
re-install with this branch   RULE.md  0   .mdc 26
hand-written RULE.md present after re-install:  yes

bash -n tools/install is clean.

What this does not establish

The claim that the surface is inert rests on Cursor's documented behaviour. I have not run Cursor against an installed tree and observed a rule load or fail to load, so that remains a prediction rather than an observation. It is cheap to check for anyone with Cursor open, and it is the reason the defect survived this long — nothing in CI can see it.

Out of scope

globs is still never emitted (0 occurrences in the repo), so Cursor's apply-to-specific-files mode stays unavailable. That is the only native conditional-attachment mechanism any of the three surfaces offers, but whether to adopt it depends on an unresolved question — whether an auto-attached rule whose globs do not match still contributes its description to context. If it does, globs gates the rule body only. Tracked in AIENG-142 rather than decided here.

Measured at cce2ee1. Sites: tools/install L267, L268, L412; test/cli.test.mjs L136.

Cursor ignores a plain `.md` in `.cursor/rules` because it carries no
frontmatter the rules system can read, so every rule the installer has
emitted has been inert on arrival.

`is_managed_project_skill` still accepts `RULE.md`, or `--prune-stale`
would stop recognising every tree an older installer wrote and orphan
it. `write_cursor` removes that file once it has written the `.mdc`,
but only when it carries the managed banner, so a hand-written rule of
the same name survives.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant