* feat(skills): add Cursor Koolook PR-review skills (batched-verify + Grok) Port the K-Memory v2 Cursor review pipeline with Koolook invariants briefs, PR-head refresh, and fast/deep entry points for issue #279. Co-authored-by: Cursor <cursoragent@cursor.com> * chore(skills): shorten PR-review skill names to review-pr-comfy-cursor Rename deep/fast Cursor review skills from *-koolook-cursor to *-comfy-cursor. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(skills): update triggers and paths to review-pr-comfy-cursor Keep skill body text, menu-comfy, and Cursor mirrors aligned with the shortened names. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(skills): keep review worktrees in-repo and guard Cursor mirrors Use .review-worktrees/ so Cursor Tasks can Read/Grep the PR head, and assert .claude/.cursor SKILL mirrors stay byte-identical. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
35 lines
1.3 KiB
Python
35 lines
1.3 KiB
Python
"""Guards for Cursor discovery mirrors of repo-local skills.
|
|
|
|
`.claude/skills/<name>/SKILL.md` is canonical. When a matching
|
|
`.cursor/skills/<name>/SKILL.md` discovery mirror is maintained for Cursor
|
|
skill discovery, the two files must stay byte-identical so edits cannot
|
|
drift silently.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
# Skills that intentionally keep a Cursor discovery mirror in sync with the
|
|
# Claude canonical copy. Older thin/divergent mirrors (e.g. add-external-fork)
|
|
# are out of scope until they opt into this contract.
|
|
BYTE_IDENTICAL_CURSOR_MIRRORS = (
|
|
"review-pr-comfy-cursor",
|
|
"review-pr-fast-comfy-cursor",
|
|
)
|
|
|
|
|
|
def test_cursor_discovery_mirrors_match_claude_canonical() -> None:
|
|
for name in BYTE_IDENTICAL_CURSOR_MIRRORS:
|
|
canonical = REPO_ROOT / ".claude" / "skills" / name / "SKILL.md"
|
|
mirror = REPO_ROOT / ".cursor" / "skills" / name / "SKILL.md"
|
|
assert canonical.is_file(), f"missing canonical skill: {canonical}"
|
|
assert mirror.is_file(), f"missing Cursor mirror: {mirror}"
|
|
assert canonical.read_bytes() == mirror.read_bytes(), (
|
|
f"Cursor mirror drifted from canonical for {name}. "
|
|
f"Copy .claude/skills/{name}/SKILL.md → "
|
|
f".cursor/skills/{name}/SKILL.md"
|
|
)
|