Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions .agents/skills/coding/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: coding
description: Implement and review Java code changes for Micronaut framework repositories using maintainer standards. Use when users ask to add or refactor Java code, fix framework bugs, evolve internal APIs, or prepare committer-ready changes with tests and verification.
description: Implement and review Java code changes for Micronaut framework repositories using maintainer standards, including JSpecify null-safety conventions. Use when users ask to add or refactor Java code, fix framework bugs, evolve internal APIs, or prepare committer-ready changes with tests and verification.
license: Apache-2.0
compatibility: Micronaut framework repositories in micronaut-projects generated from micronaut-project-template
metadata:
Expand All @@ -14,7 +14,7 @@ Use this skill for maintainer-facing Java implementation work in Micronaut repos

## Goal

Deliver minimal, source-backed Java changes that preserve framework quality: binary compatibility, null-safety, reflection-free behavior, and full Gradle verification (`check`, `docs`, and compatibility checks when API-facing).
Deliver minimal, source-backed Java changes that preserve framework quality: binary compatibility, JSpecify null-safety, reflection-free behavior, and full Gradle verification (`check`, `docs`, and compatibility checks when API-facing).

## Trigger Examples

Expand Down Expand Up @@ -50,7 +50,10 @@ Should not trigger:

- Prefer modern Java idioms where they improve clarity (records, sealed types, pattern matching, `var` for local inference), but only when supported by the repository toolchain/target level.
- Do not use fully qualified class names unless import conflicts force it.
- Follow the repository's established nullability annotations/defaults; use JSpecify and package-level `@NullMarked` only when that convention already exists in the module.
- Micronaut Java code uses JSpecify nullness annotations from `org.jspecify.annotations`; use JSpecify for new or modified nullability contracts.
- New Java packages must include `package-info.java` with `@NullMarked` and `import org.jspecify.annotations.NullMarked`; when touching an existing package without `@NullMarked`, add it unless the local code has an explicit exception.
- Use `org.jspecify.annotations.Nullable` for nullable values, including nullable parameters, return values, fields, array/component positions such as `String @Nullable []`, nullable collection elements such as `List<@Nullable T>`, and nullable type bounds such as `<T extends @Nullable Object>`.
- Preserve existing nullability intent when editing older code. Use JSpecify for new or modified contracts, but do not rewrite deliberate compatibility annotations such as `io.micronaut.core.annotation.Nullable` or `jakarta.annotation.Nullable` unless the task is specifically a nullability migration and compatibility impact has been checked.
- Avoid reflection-oriented implementations in framework code paths; prefer Micronaut compile-time/introspection mechanisms.
- Use `jakarta.inject` APIs for DI, not `javax.inject`.
- Prefer constructor injection and immutable state over field injection.
Expand All @@ -65,6 +68,8 @@ Should not trigger:
- When using the deprecate-and-add path, keep deprecated APIs functional, point to replacements in Javadoc, and schedule removals only for the next major version.
- If breaking public-facing changes are explicitly allowed, document them in the user guide under `src/main/docs/guide` with migration notes, and update `toc.yml` when adding new guide sections.
- Mark non-user-facing APIs with `@io.micronaut.core.annotation.Internal`.
- Mark unstable public APIs with `@io.micronaut.core.annotation.Experimental` and avoid presenting them as stable contracts.
- Mark members directly called by generated code with `@io.micronaut.core.annotation.UsedByGeneratedCode`; preserve those signatures unless the generated-code callers are updated in the same change.
- Keep visibility as narrow as possible for non-public internals.
- When deprecating API, provide migration-friendly Javadoc and avoid silent behavioral breaks.

Expand Down Expand Up @@ -106,6 +111,7 @@ If Spotless fails, run `./gradlew -q spotlessApply` and re-run `spotlessCheck`.
## Guardrails

- Do not introduce `javax.inject` usage.
- Do not introduce legacy or third-party nullability annotations for new or modified Micronaut Java contracts when JSpecify is available, except for deliberate compatibility annotations whose impact has been checked.
- Do not hard-code dependency versions in module build files.
- Do not break public APIs without explicit major-version intent.
- Do not skip tests or docs verification for code changes.
Expand All @@ -127,8 +133,8 @@ When finishing implementation work, report:

- [ ] `SKILL.md` frontmatter is valid and `name` matches directory (`coding`).
- [ ] Guidance is maintainer-focused (not end-user app guidance).
- [ ] Java conventions include nullability, DI, and reflection-free guidance.
- [ ] API boundary guidance includes `@Internal` and compatibility checks.
- [ ] Java conventions include JSpecify nullability (`@NullMarked`, `@Nullable`), DI, and reflection-free guidance.
- [ ] API boundary guidance includes `@Internal`, `@Experimental`, `@UsedByGeneratedCode`, and compatibility checks.
- [ ] For public API evolution without breaking changes, deprecations include clear replacement guidance and functional compatibility is preserved.
- [ ] If breaking changes are allowed, user guide docs in `src/main/docs/guide` are updated with migration notes.
- [ ] Verification includes tests, style checks, `check`, and `docs`.
Expand Down
148 changes: 148 additions & 0 deletions .agents/skills/guides/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
---
name: guides
description: Create or update standalone Micronaut Guides in micronaut-projects/micronaut-guides, including topic discovery, guide authoring, validation, PDF export, and pull request handoff. Use for requests to create a Micronaut Guide, add a guide to micronaut-guides, author a tutorial for a Micronaut module, or prepare a guide PR with PDF.
license: Apache-2.0
compatibility: Micronaut Guides repository and Micronaut repositories that need standalone tutorial PRs
metadata:
author: Micronaut Agent Company
version: "1.0.0"
---

# Guides (Micronaut Maintainer)

Use this skill for standalone tutorial work in `micronaut-projects/micronaut-guides`. Start from the caller's local Micronaut repository to understand the API, module, or behavior being taught, then do the guide implementation in a current clone of `micronaut-guides`.

Do not use this skill for ordinary module documentation under `src/main/docs/guide`; use the `docs` skill for that work. Do not use it for generic non-Micronaut tutorials.

## Goal

Produce a reviewable pull request against `micronaut-projects/micronaut-guides` with source-backed guide content, validation evidence, and a PDF export of the rendered guide page for maintainers.

## Procedure

1. Define the topic from the local repository.
2. Refresh upstream `micronaut-guides` and deduplicate against existing guides.
3. Inspect current repository conventions before writing.
4. Author the smallest correct guide change.
5. Validate the guide and render the page.
6. Export a PDF and prepare the PR handoff.

### 1) Define the Topic

- Identify the exact Micronaut feature, module, API, integration, or migration path the guide should teach.
- Read the local implementation, tests, module docs, and examples that prove the behavior.
- Decide the target reader task in one sentence, for example: "Use Micronaut Serialization with a custom serializer in a controller response."
- Prefer a runnable application and tests over prose-only explanation.

### 2) Refresh and Deduplicate

Work from current upstream facts, not this skill's snapshot:

```bash
git clone https://github.com/micronaut-projects/micronaut-guides.git
cd micronaut-guides
git fetch origin
git switch master
git pull --ff-only
```

Before creating a new guide, inventory `guides/*/metadata.json` and nearby guide source. Check titles, slugs, tags, categories, `apps`, `base`, `publish`, and guide bodies for duplicates or near-duplicates. Treat `publish: false` guides as base or partial guides, not public topics, but inspect them when a new guide could reuse them.

If an existing guide already teaches the task, update that guide instead of creating a duplicate. If overlap is ambiguous, stop and ask for maintainer direction.

### 3) Inspect Current Conventions

Always read these current upstream files before editing:

- `README.md`
- `build.gradle`
- `buildSrc/src/main/java/io/micronaut/guides/core/Guide.java`
- `buildSrc/src/main/java/io/micronaut/guides/Category.java`
- `buildSrc/src/main/resources/guide-metadata.schema.json`
- Nearby guides in the same topic family

Use `references/repository-workflow.md` for clone, branch, build-output, task naming, and validation details. Use `references/guide-authoring-conventions.md` for metadata, directory layout, macros, placeholders, and base-guide rules.

### 4) Author the Guide

- Choose a kebab-case slug that matches the reader task and does not collide with existing guide directories.
- Create or update `guides/<slug>/metadata.json`.
- Use one root AsciiDoc file named `<slug>.adoc` unless current metadata conventions require `asciidoctor`.
- Put source under the expected Java, Groovy, and Kotlin layout when the guide supports multiple languages. If the feature is language-specific, set `languages` in metadata and explain why in the PR.
- For single-app guides, use an app named `default`. For multi-app guides, mirror existing app-directory patterns and declare each app in metadata.
- Use validated guide macros such as `common:`, `source:`, `resource:`, `test:`, `testResource:`, `callout:`, `external:`, `dependency:`, and `guideLink:` instead of manually duplicating generated paths.
- Use conditional blocks such as `:exclude-for-languages:` and `:exclude-for-build:` for language-specific or build-tool-specific text.
- Keep secrets out of source, generated code, rendered HTML, and the PDF. Use placeholders and documented cleanup steps for cloud resources.

### 5) Validate

Convert the guide slug from kebab-case to lowerCamelCase for dynamic tasks:

```bash
./gradlew <guideLowerCamel>Build
./gradlew <guideLowerCamel>RunTestScript
```

For broad validation or shared infrastructure changes, run:

```bash
./gradlew build
```

Generated applications are under `build/code`. Rendered HTML and site assets are under `build/dist`. For cloud, credentialed, or cost-incurring guides, do not run provisioning commands without explicit confirmation; document skipped validation and the reason.

### 6) Export PDF and Handoff

After rendering, export the reviewed HTML page to PDF. Prefer a headless browser export when available, and fall back to a manual browser "Print to PDF" export when needed. Keep the PDF as local review evidence or attach it to the PR; do not commit generated PDFs unless maintainers explicitly request that.

The PR body must include:

- Guide slug and user-facing task.
- Files changed.
- Commands run and outcomes.
- Rendered HTML path inspected.
- PDF filename and whether it is attached or linked.
- Any skipped validation, cloud costs, credentials, or cleanup notes.

See `references/pdf-export-and-pr.md` for the export workflow and PR checklist.

## Security Guardrails

- Never commit secrets, tokens, local credentials, cloud account identifiers, `.env` files, or generated PDFs containing private data.
- Ask before running commands that provision cloud resources or incur cost.
- Prefer sample placeholders for credentials and explain cleanup for created resources.
- Scrub screenshots, HTML, logs, and PDFs before attaching them to a PR.
- Do not add custom Starter features, dependencies, or buildSrc changes unless the guide topic requires them and nearby guide conventions support the change.

## Examples

Use this skill for:

- "Create a Micronaut Guide for the new serialization feature."
- "Add a guide to `micronaut-guides` for this module."
- "Author a tutorial for Micronaut Data's new repository behavior."
- "Prepare a guide PR with the rendered PDF."

Do not use this skill for:

- "Update `src/main/docs/guide/toc.yml` in this module."
- "Fix the release history page in this repository."
- "Write a generic blog post about Java."

## Validation Checklist

- [ ] Current `micronaut-guides` was cloned or fetched before writing.
- [ ] Existing guide titles, slugs, tags, categories, and `publish: false` bases were checked for duplicates.
- [ ] `README.md`, metadata schema, category source, and nearby guide examples were inspected.
- [ ] Guide source uses current metadata, directory, macro, language, and build-tool conventions.
- [ ] Single-guide build and test-script tasks were run, or skipped with a specific reason.
- [ ] Rendered HTML was inspected under `build/dist`.
- [ ] PDF export was created and named in the PR handoff.
- [ ] PR handoff explains changed files, validation, skipped steps, and any security-sensitive handling.

## References

- `references/repository-workflow.md`
- `references/guide-authoring-conventions.md`
- `references/guide-inventory.md`
- `references/pdf-export-and-pr.md`
151 changes: 151 additions & 0 deletions .agents/skills/guides/references/guide-authoring-conventions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Guide Authoring Conventions

Micronaut Guides are generated tutorials. A single guide source can render several language and build-tool variants, so write source-backed content and avoid hard-coded generated paths where guide macros can do the work.

## Guide Directory

A regular guide normally lives at:

```text
guides/<slug>/
|-- metadata.json
|-- <slug>.adoc
|-- java/
|-- groovy/
|-- kotlin/
`-- src/main/resources/
```

Use one root AsciiDoc file named `<slug>.adoc` unless `metadata.json` sets `asciidoctor`.

For a single generated application, metadata should use an app named `default`. For multi-application guides, create a directory per app name and place each language tree inside that app directory:

```text
guides/<slug>/<app-name>/java/src/main/java/example/micronaut/...
guides/<slug>/<app-name>/kotlin/src/main/kotlin/example/micronaut/...
guides/<slug>/<app-name>/groovy/src/main/groovy/example/micronaut/...
```

## Metadata

Current upstream metadata is modeled by `buildSrc/src/main/java/io/micronaut/guides/core/Guide.java` and the generated schema at `buildSrc/src/main/resources/guide-metadata.schema.json`.

Required fields:

- `title`
- `intro`
- non-empty `authors`
- non-empty `categories`
- `publicationDate` in `YYYY-MM-DD`
- non-empty `apps`

Common optional fields:

- `minimumJavaVersion`
- `maximumJavaVersion`
- `cloud`
- `skipGradleTests`
- `skipMavenTests`
- `asciidoctor`
- `languages`
- `tags`
- `buildTools`
- `testFramework`
- `zipIncludes`
- `slug`
- `publish`
- `base`
- `env`

Use category labels from `Category.java`. At the inspected upstream revision, labels included Getting Started, Core Basics, Validation, Development, Testing, MCP, Object Storage, Email, Messaging, Logging, Scheduling, Cache, Patterns, i18n, Database Modeling, Data JDBC, Data JPA, Schema Migration, Data R2DBC, MongoDB, Data Access, Micronaut Security, Authorization Code, Client Credentials, Secrets Manager, HTTP Server, HTTP Client, Beyond JSON, JAX-RS, WebSockets, GraphQL, OpenAPI, JSON Schema, Distributed Tracing, Service Discovery, Distributed Configuration, Metrics, Distribution, Registry, GraalVM, Coordinated Restore at Checkpoint, Kubernetes, Serverless, AWS Lambda, Scale to Zero Containers, Views, Turbo, Static Resources, Kotlin, GraalPy, Spring Boot, and Boot to Micronaut Building a REST API. Refresh this list from current upstream before choosing a category.

## Starter Features and Apps

Guide `apps` features must be valid Micronaut Starter features. If a feature is not available from Starter, inspect existing custom features in `buildSrc/src/main/java/io/micronaut/guides/feature` and dependency versions in `buildSrc/src/main/resources/pom.xml`. Add custom features only when the guide topic requires them and validation covers the change.

Example single-app metadata shape:

```json
{
"title": "Micronaut HTTP Client",
"intro": "Learn how to use Micronaut HTTP Client.",
"authors": ["Sergio del Amo"],
"categories": ["HTTP Client"],
"publicationDate": "2026-05-06",
"apps": [
{
"name": "default",
"features": ["http-client"]
}
]
}
```

## AsciiDoc Placeholders

Guide source can use placeholders expanded by the build:

- `@language@`
- `@guideTitle@`
- `@guideIntro@`
- `@micronaut@`
- `@lang@`
- `@build@`
- `@testFramework@`
- `@authors@`
- `@languageextension@`
- `@testsuffix@`
- `@sourceDir@`
- `@minJdk@`
- `@api@`
- `@features@`
- `@features-words@`

## Common Snippets and Macros

Reusable snippets live under `src/docs/common`. Prefer existing snippets for headers, requirements, complete-solution, app creation, test, run, GraalVM, and next-step sections.

Common guide macros include:

- `common:<file>[]`: include a common snippet.
- `source:<ClassName>[]`: include a source file from the current language's main source directory.
- `resource:<file>[]`: include a resource from `src/main/resources`.
- `test:<ClassName>[]`: include a test file and account for JUnit, Kotest, or Spock naming.
- `testResource:<file>[]`: include a test resource.
- `callout:<name>[]`: include a common callout snippet.
- `external:<path>[]`: include content from a base or external guide.
- `dependency:<artifact>[groupId=...,scope=...,version=...]`: render dependency lines.
- `guideLink:<slug>[...]`: link to another guide using guide-site paths.

Most macros accept options such as `tags`, `lines`, `indent`, and `app`. Inspect nearby guides and buildSrc macro tests before using less common options.

## Conditional Blocks

Use custom exclusion blocks when a paragraph or instruction applies only to some render variants:

```asciidoc
:exclude-for-languages:kotlin
This text renders for Java and Groovy, not Kotlin.
:exclude-for-languages:

:exclude-for-build:maven
Run `./gradlew run`.
:exclude-for-build:
```

Also inspect current support for JDK-based exclusions before writing Java-version-specific content.

## Base and Partial Guides

`publish` defaults to true. Set `publish: false` only for draft, base, or partial guides that should not appear as public guide topics.

Use `base` when a guide extends reusable source or narrative from another guide. Inspect the base guide carefully; it may provide shared app code, common AsciiDoc, or resource files. Do not count `publish: false` guide directories as public topic coverage during dedupe, but do use them to avoid duplicating shared scaffolding.

## Code Quality

- Keep application code runnable and focused on the guide's teaching goal.
- Put sample code under `example.micronaut` unless nearby guides for the topic use another package.
- Prefer tests that prove the user's expected outcome.
- Use snippet tags when only part of a file should appear in the guide.
- Avoid prose that drifts from the code; include actual source, resources, and tests with guide macros.
- For cloud and security guides, use placeholders for secrets and include cleanup instructions.
Loading
Loading