jamesfredley opened a new pull request, #15805: URL: https://github.com/apache/grails-core/pull/15805
## The Problem The app-facing Grails agent skills (`grails-developer`, `grails-8-upgrade`) live in `.agents/skills`, and applications have no versioned way to get them. The first version of this PR exposed them to the [SkillsJars](https://www.skillsjars.com) publisher, but that service clones the repository and deploys unvoted `com.skillsjars:*` artifacts to Maven Central itself, outside the ASF release process. ## The Fix Publish the skills ourselves, as part of the normal Grails release, in the SkillsJars jar format. - Each published skill gets its own Gradle project under `grails-skills/`: - `:grails-skills-developer` → `org.apache.grails.skills:grails-developer` - `:grails-skills-upgrade-guide-8` → `org.apache.grails.skills:grails-8-upgrade` - Each skill lives in the project that publishes it, at `grails-skills/<project>/skills/<skill>/`. `.agents/skills/<skill>/SKILL.md` becomes a symlink to it, the same pattern `.claude/skills` already uses, so agents such as OpenCode still find the skills where they look by default. - A new convention plugin, `org.apache.grails.buildsrc.agent-skills`, packages a project's `skills/` directories at `META-INF/skills/<githubSlug>/<skill>/`, the layout SkillsJars defines. It fails the build when a project has no skills, a skill has no `SKILL.md`, or a skill's frontmatter `name` differs from its directory. - The jars are published projects, so they are staged, signed, and voted on with every other Grails artifact, and `grails-bom` manages them (through `grails-base-bom`). An application declares them without a version and gets the skills for the Grails version it builds with. - The root build collects every `grails-skills-*` project into a new `skillProjects` category, alongside `cliProjects`, `docProjects` and the others, and publishes all of them. A new skill project only needs registering in `settings.gradle`, and the build can single out skill projects later. - Contributor-only skills (`gradle-developer`, `groovy-developer`, `hibernate-developer`, `java-developer`, `mono-repo-integration`, `test-fixer`, `violation-fixer`) stay unpublished. ## Consuming the skills Applications use the [SkillsJars Gradle plugin](https://github.com/skillsjars/skillsjars-gradle-plugin), which extracts skill jars from any group as of 0.1.0. This PR uses 0.1.3, which also includes the fix for skillsjars/skillsjars-gradle-plugin#10: ```groovy plugins { id 'com.skillsjars.gradle-plugin' version '0.1.3' } dependencies { skill 'org.apache.grails.skills:grails-developer' skill 'org.apache.grails.skills:grails-8-upgrade' } skillsjars { outputDir = layout.projectDirectory.dir('.agents/skills') } ``` `./gradlew extractSkillsJars` then writes each skill to `.agents/skills/skillsjars__apache__grails-core__<skill>/`. - **No versions:** the Grails Gradle plugin applies the Grails BOM to every configuration, including `skill`, so the dependencies need no version. A build without the Grails plugin adds `skill platform(grails-bom)`. - **Grails 7:** applications still on Grails 7 declare the version explicitly. Verified on Grails 7.0.14 with Gradle 8.14.5 and JDK 17. - **Output directory:** the guide warns that `extractSkillsJars` empties the output directory and `clean` deletes it, so it should hold only extracted skills. - **Naming:** directories are named after the jar path rather than the skill. OpenCode keys skills by their frontmatter `name` and scans recursively, so it finds them. Before 0.1.3, the plugin's `packageSkillsJars` task required a `skills/` directory in any project that applies the `java` plugin, which broke every Grails application that only extracts skills (skillsjars/skillsjars-gradle-plugin#10). The fix (skillsjars/skillsjars-gradle-plugin#11) shipped in 0.1.3, so no workaround is needed. ## Testing - New `AgentSkillsPluginSpec` in build-logic (TestKit), 8 cases: the jar layout including supporting files, a `githubSlug` set after the plugin is applied, a removed skill being dropped from the next jar, and each validation failure. Mutation-checked: disabling the validation fails the three validation cases. - New checked-in example builds in `end-to-end`: `agent-skills`, a Grails application declaring the skills without versions, and `agent-skills-plain-build`, which names the BOM. Both apply the SkillsJars Gradle plugin 0.1.3 and resolve the published jars and BOM. Their spec asserts that exactly the published skills are extracted, byte-identical to the repository's skills, each declaring the expected `name`. - Built both jars and checked their layout: `META-INF/skills/apache/grails-core/<skill>/SKILL.md` plus `LICENSE`, `NOTICE`, and `sbom.json`. `grails-bom` now manages `grails-developer.version` / `grails-8-upgrade.version`. - Manually checked a Grails 7.0.14 app (Gradle 8.14.5, JDK 17) extracting `grails-8-upgrade` with SkillsJars plugin 0.1.3 and an explicit version, and `com.skillsjars:maven-plugin:0.0.7` extracting both jars. - `:grails-doc:publishGuide` renders the Agent Skills section and its cross-references. Refs #15454 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
