Skip to content

fix: load skills and see edits on Cursor - #3

Merged
sebastian-iancu merged 4 commits into
mainfrom
fix/cursor-skill-load
Oct 27, 2026
Merged

sebastian-iancu merged 4 commits into
mainfrom
fix/cursor-skill-load

Conversation

@sebastian-iancu

@sebastian-iancu sebastian-iancu commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Makes the shared skills, agents, hooks and Cursor rule work on Cursor without changing Claude Code. Cursor has no Skill tool and edits files with StrReplace, so before this change ordinary SQL edits ran no hook there, and the focused skills never opened. Targets main; it was first stacked on #2, which has since merged.

Hooks

  • Cursor's postToolUse matches Write|StrReplace. afterFileEdit stays unused because it has no output field, so a nudge there would not reach the model.
  • A relative Cursor tool path is joined to CURSOR_PROJECT_DIR, because Cursor runs a plugin hook in the plugin install. An absolute path is left as it is.
  • On Cursor, the nudge, the squawk report and the session-start line name the skill's absolute SKILL.md path in the plugin install, JSON-escaped. A Cursor subagent cannot find the install on its own, so the session-start path is the one a brief passes on. Claude Code still gets pgsql-coding:<skill>, and its hook output is unchanged.
  • A multi-line edit now nudges even when its keyword is not on the first line. Line breaks in the edit text were breaking the keyword match; they now count as spaces. This affected both hosts.

Skills, agents, rule

  • On Cursor, the router, both agents and the rule read <plugin root>/skills/<name>/SKILL.md. They never look under skills/ in the user's repository.
  • The plan summariser runs by its full path, so a relative plan file resolves in the workspace.
  • pgsql-reviewer and pgsql-plan-analyst set permissionMode: readonly, and tools: stays. Bash and psql can still write on either host, so no-edit and no-write stay rules the agents keep.
  • docs/authoring.md is the one place that says what each host enforces, with sources. Cursor's docs give readonly: true and don't mention permissionMode, and Claude Code ignores permissionMode in plugin agents.
  • The Cursor rule attaches to **/*.sql. For SQL in Go or PHP it points to pgsql-query.

Validation

  • validate.py fails an edit hook whose matcher misses one of a host's edit tools: Write|Edit for Claude Code, Write|StrReplace for Cursor. A selftest case covers it.
  • One skill list now serves both session-start lines, so the routing check covers Cursor's too.
  • hooks-test.sh covers both hosts' wording, the Cursor install path (including a quote in it), relative and absolute Cursor paths in both edit hooks, and multi-line edits. Each new test was checked against a deliberately broken copy of its hook: all 8 broken copies failed.

Test plan

  • ./scripts/validate.sh and python3 scripts/validate.py --selftest (20 checks)
  • ./scripts/hooks-test.sh (70 checks)
  • python3 scripts/plan-summary-test.py
  • claude plugin validate .
  • python3 scripts/validate.py --check-links (257 of 257)
  • Claude Code hook output compared before and after this change: identical
  • Cursor: install this plugin, edit an existing .sql file (StrReplace), and confirm the nudge arrives as additional_context with the skill's path
  • Cursor: ask pgsql-reviewer to fix a file it reviewed and confirm it refuses (permissionMode: readonly), and that it read a skill from the path its brief gave

Made with Cursor · 🤖 Review fixes with Claude Code

Cursor has no Skill tool and applies incremental edits with StrReplace.
The shared skills, agents and rule now name /pgsql-* and the plugin
install, postToolUse matches Write and StrReplace, and the report-only
agents set permissionMode: readonly.

Co-authored-by: Cursor <cursoragent@cursor.com>
@sebastian-iancu
sebastian-iancu changed the base branch from refactor/skills-agents-qa to main October 27, 2026 13:27
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sebastian-iancu

Copy link
Copy Markdown
Contributor Author

Review applied in f4b6bea (merge of main), 9756c28 (hooks and tests) and 3709574 (prose). The base is now main; refactor/skills-agents-qa was already merged.

Fixed

  • Conflict with main in agents/pgsql-reviewer.md: the description keeps refactor: QA pass on the skills and agents #2's trimmed text, and the seat sentence names neither host, so it fits both (977 chars).
  • Summariser on Claude Code: pgsql-performance ran it "from this skill's directory", so a relative plan.txt resolved inside the plugin install. It now runs the script by its full path, as the rule and the analyst do.
  • Reviewer path on Cursor: it pointed at skills/ under agents/. Both agents now read <plugin root>/skills/<name>/SKILL.md, a path the brief or the session-start line supplies.
  • Hook messages on Cursor: "read /pgsql-jsonb" reads as a filesystem path, and a subagent cannot find the install on its own. The hooks now print the absolute SKILL.md path (JSON-escaped), and the session-start line prints it once for the session and for briefs.
  • Host claims: "Claude Code enforces tools:" overstated the grant, since Bash and psql can write. "Contracts you keep, not a sandbox" is back. The permissionMode vs readonly facts now live only in docs/authoring.md, with sources: Cursor's subagent docs give readonly: true and do not mention permissionMode, and Claude Code ignores permissionMode in plugin agents. docs/testing.md gains a Cursor check that settles it on a real install.
  • Multi-line edits gave no nudge when the keyword was not on the first line, because a JSON \n broke the word edge. This affected both hosts (it was already on main for Claude Code). Line breaks now count as spaces.
  • Tests: the validator now fails an edit-hook matcher that misses a host's edit tool (selftest 20). hooks-test.sh now checks the Claude wording in the banner and in lint-on-save, every skill and the install path in the Cursor banner, a quote in that path, lint-on-save's relative and absolute Cursor paths, multi-line edits, and the relative-path case with CURSOR_PROJECT_DIR really unset. Each new test was checked against a deliberately broken copy of its hook; all 8 broken copies failed the tests.
  • Prose: one skill list now serves both banners, so the routing check covers Cursor. The rule no longer says to search for squawk.toml. The CHANGELOG Changed group is dropped while nothing is released.

Checks: all pass locally: validate.sh, --selftest (20), hooks-test.sh (70), plan-summary-test.py, claude plugin validate . and --check-links (257 of 257). Claude Code hook output is unchanged.

Still open: loading the plugin in Cursor to confirm the StrReplace payload fields, permissionMode: readonly, and that a subagent reads a skill from the path its brief gives.

sebastian-iancu and others added 2 commits October 27, 2026 14:37
…changed

- session-start, skill-nudge and lint-on-save tell Cursor the absolute
  SKILL.md path under the plugin install (JSON-escaped), since "read
  /pgsql-jsonb" reads as a filesystem path and a subagent cannot find
  the install itself. One skill list serves both banners, so the
  routing check covers Cursor's too. Claude Code output is unchanged.
- skill-nudge reads JSON line breaks in the added text as spaces, so a
  keyword on a later line of a multi-line edit still nudges (on both
  hosts), and marks a skill as nudged only after the message is out.
- validate.py fails an edit hook whose matcher misses a host's edit
  tool (Claude Write|Edit, Cursor Write|StrReplace), with a selftest.
- hooks-test.sh: Claude wording in the banner and lint-on-save, every
  skill and the install path in the Cursor banner, a quote in that
  path, lint-on-save's relative and absolute Cursor paths, an absolute
  path beside CURSOR_PROJECT_DIR, multi-line edits, and the relative
  path case run with CURSOR_PROJECT_DIR really unset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Agents: read <plugin root>/skills/<name>/SKILL.md on Cursor (the old
  reviewer path pointed into agents/); the summariser runs by its full
  path, with the Claude Code fallback back; the reviewer loads only the
  skills the change touches; "contracts you keep, not a sandbox" is back,
  since Bash and psql can write on either host.
- pgsql-performance: run the summariser by its full path, so a relative
  plan file resolves in the workspace.
- Router, Cursor rule, README briefs: a Cursor brief carries the
  absolute SKILL.md path; the rule's squawk.toml line no longer says to
  search for it.
- docs/authoring.md is the one home for what each host enforces, with
  sources: Cursor documents readonly: true, not permissionMode; Claude
  Code ignores permissionMode in plugin agents. testing.md adds a
  Cursor check that settles it.
- CHANGELOG: no Changed group while nothing is released.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sebastian-iancu
sebastian-iancu merged commit 5501705 into main Oct 27, 2026
2 checks passed
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