diff --git a/.agents/skills/create-rule/SKILL.md b/.agents/skills/create-rule/SKILL.md deleted file mode 100644 index 3b42641..0000000 --- a/.agents/skills/create-rule/SKILL.md +++ /dev/null @@ -1,183 +0,0 @@ ---- -name: create-rule -description: > - Use this skill when asked to add, create, or implement a new validation rule - in the Heylogs project. It covers picking the right enum, adding the constant, - the validate method, the test, the resource file (if needed), and the - documentation row. ---- - -Add a new validation rule to `heylogs-ext-rules` by following these steps in order. Execute all steps without asking for confirmation. - -## Step 0 — Choose the right enum - -Rules live in three categorized enums under `heylogs-ext-rules/src/main/java/nbbrd/heylogs/ext/rules/`: - -| Enum | File | Category | Typical node type | -|----------------|---------------------|--------------------------------------|------------------------------------------| -| `ReleaseRules` | `ReleaseRules.java` | Release structure and versioning | `Document`, `Heading` | -| `LinkRules` | `LinkRules.java` | Link validation and reference checks | `Link`, `LinkNodeBase`, `BulletListItem` | -| `StyleRules` | `StyleRules.java` | Formatting and style conventions | `Document`, `BulletListItem` | - -Pick the enum whose category best matches the new rule, then use that file for Steps 1–3. - -> **Note**: Rules for core changelog structure (changelog heading, H2 version format, type-of-change headings, date display, version ordering) belong to `GuidingPrinciples` in `heylogs-api` and are not part of this skill. - -## Step 1 — Add the enum constant - -**File**: `heylogs-ext-rules/src/main/java/nbbrd/heylogs/ext/rules/.java` - -**Action**: Use `replace_string_in_file` to add a new constant BEFORE the final `;` of the enum (after the last existing constant). The rule ID is derived automatically from the constant name (`MY_RULE` → `my-rule`). - -**Template**: -```java -MY_RULE { - @Override - public @Nullable RuleIssue getRuleIssueOrNull(@NonNull Node node, @NonNull RuleContext context) { - return node instanceof BulletListItem ? validateMyRule((BulletListItem) node) : NO_RULE_ISSUE; - } - - @Override - public @NonNull String getRuleName() { - return "My rule"; - } - - // Only add this override when severity is not ERROR: - @Override - public @NonNull RuleSeverity getRuleSeverity() { - return RuleSeverity.WARN; // or OFF - } -}, -``` - -**Node type selection**: - -| Node type | What it covers | Common pattern | -|-------------------------|------------------------------------|------------------------------------------------------| -| `Document` | Whole-document checks | Use `ChangelogHeading.root(doc)` helper | -| `Heading` | Version or type-of-change headings | Check `Version.isVersionLevel(heading)` | -| `BulletListItem` | Changelog list entries | Use `item.getChars().trim().toString()` | -| `Link` / `LinkNodeBase` | Inline links | Parse URL with `Parser.onURL().parse(link.getUrl())` | - -## Step 2 — Add the static validate method - -**File**: Same as Step 1 - -**Action**: Use `replace_string_in_file` to add a `@VisibleForTesting` static method AFTER the last existing `validate*` method (before any inner class or `Batch` class at the end). - -**Template for BulletListItem rules**: -```java -@VisibleForTesting -static @Nullable RuleIssue validateMyRule(@NonNull BulletListItem item) { - String text = item.getChars().trim().toString(); - if (text.isEmpty()) return NO_RULE_ISSUE; - - // Early return NO_RULE_ISSUE for valid cases - if (someCondition) return NO_RULE_ISSUE; - - // Return issue for invalid cases - return RuleIssue - .builder() - .message("Descriptive error message") - .location(item) - .build(); -} -``` - -**Best practices**: -- Always use `.trim()` when checking `BulletListItem` text content -- Use early returns with `NO_RULE_ISSUE` for valid/skip cases -- Use `Character` utility methods for character checks (e.g., `Character.isLetter()`, `Character.isUpperCase()`) -- Use `String.format(ROOT, "...")` for parameterized messages -- For `Document` rules, delegate to a private helper: `ChangelogHeading.root(doc).map(MyEnum::validateHelper).orElse(NO_RULE_ISSUE)` -- If the new method needs `truncate()`, call `RulesUtil.truncate(text, maxLength)` (package-private helper in the same package) - -## Step 3 — Add the test - -**File**: `heylogs-ext-rules/src/test/java/nbbrd/heylogs/ext/rules/Test.java` - -**Action**: Use `replace_string_in_file` to add a test method AFTER the last existing test method (before the closing `}`). - -**Template**: -```java -@Test -public void testValidateMyRule() { - assertThat(validateMyRule(asBulletListItem("- Valid entry"))) - .describedAs("valid case") - .isNull(); - - assertThat(validateMyRule(asBulletListItem("- Invalid entry"))) - .describedAs("invalid case") - .isEqualTo(RuleIssue.builder().message("Expected message").line(1).column(1).build()); -} -``` - -**Tips**: -- Import the static methods at the top: `import static nbbrd.heylogs.ext.rules..*;` -- Use `.isNull()` instead of `.isEqualTo(NO_RULE_ISSUE)` (they are equivalent but `isNull` is cleaner) -- Use `.describedAs("...")` for each assertion to document test intent -- For `Document`-level rules, load a Markdown fixture with `using("/MyTestFile.md")` (see Step 3a) -- Helper methods available: `asBulletListItem(String)` and `asLink(String)` are in `RulesTestHelper`; `asHeading(String)` and `using(String)` are in `tests.heylogs.api.Sample` - -### Step 3a — Add test resource (only for Document-level rules) - -If the test uses `using("/MyTestFile.md")`, the `.md` file must exist in **both**: - -1. `heylogs-api/src/test/resources/MyTestFile.md` — original source of truth -2. `heylogs-ext-rules/src/test/resources/MyTestFile.md` — local copy required for the ext-rules test classpath - -Create both files with the minimal changelog content needed to trigger the rule. - -> **Why two copies?** The `heylogs-api` test-jar only packages `.class` files, not test resources. Each ext module that needs a resource must carry its own copy under `src/test/resources/`. - -## Step 4 — Update documentation - -**File**: `docs/feature-rules.md` - -**Action**: Use `replace_string_in_file` to add a row to the table in **alphabetical order** by rule ID (kebab-case). Use `rules` as the module name. - -**Row format**: -```markdown -| `rules` | [`my-rule`](#my-rule) | My rule | `ERROR` | -``` - -**Severity values**: `ERROR` (default), `WARN`, or `OFF` - -Also add a reference section entry at the bottom of the file: - -```markdown -### `my-rule` -Description of what the rule checks and when it fires. -``` - -## Post-implementation checks - -**Validation**: After all edits, call `get_errors` on both modified Java files to verify no compilation errors. - -**Files to validate**: -- `heylogs-ext-rules/src/main/java/nbbrd/heylogs/ext/rules/.java` -- `heylogs-ext-rules/src/test/java/nbbrd/heylogs/ext/rules/Test.java` - -## Testing (optional) - -```shell -# Fast test of the changed module (from workspace root) -mvn test -pl heylogs-ext-rules -am -Pyolo - -# Run only the new test method -mvn test -pl heylogs-ext-rules -am -Pyolo -Dtest=Test#testValidateMyRule - -# Full build with all checks -mvn clean install -``` - -## Constraints - -- Rule ID must match `ServiceId.KEBAB_CASE` (enforced at runtime by `RuleSupport`). -- Default severity is `ERROR`; only override when `WARN` or `OFF` is needed. -- The `test()` method in each `*Test` class automatically skips rules with `OFF` severity. -- Never reference `internal.*` packages from public API classes. The three rule enums are in the `nbbrd.heylogs.ext.rules` public package and may only access `internal.heylogs.*` directly (not `internal.heylogs.base.*`, `internal.heylogs.git.*`, etc.) — enforced by `ArchitectureTest`. -- `getRuleModuleId()` must return `"rules"` (already inherited from the enum body; do not change it). -- Target Java 8; avoid `String.repeat()`, `var`, `Stream.toList()`, `List.of()`. -- Use `trim()` before checking text content of `BulletListItem`. -- All common imports are already present in each enum; only add new ones if strictly required. diff --git a/.agents/skills/create-versioning/SKILL.md b/.agents/skills/create-versioning/SKILL.md deleted file mode 100644 index 76b6de0..0000000 --- a/.agents/skills/create-versioning/SKILL.md +++ /dev/null @@ -1,476 +0,0 @@ ---- -name: create-versioning -description: > - Use this skill when asked to add, create, or implement a new versioning scheme - in the Heylogs project. It covers creating the extension module, the public - SPI class, the internal parser/comparator, the tests, registering the module - in all POMs, and updating the documentation. ---- - -Add a new versioning scheme to Heylogs by creating a `heylogs-ext-` module. Execute all steps without asking for confirmation. - -## Prerequisites — Gather context - -Before starting, read these reference files to understand the patterns: - -1. **SPI interface**: `heylogs-api/src/main/java/nbbrd/heylogs/spi/Versioning.java` -2. **Support builder**: `heylogs-api/src/main/java/nbbrd/heylogs/spi/VersioningSupport.java` -3. **Test fixture**: `heylogs-api/src/test/java/tests/heylogs/spi/VersioningAssert.java` -4. **Reference implementation (no-arg)**: `heylogs-ext-semver/src/main/java/nbbrd/heylogs/ext/semver/SemVer.java` -5. **Reference implementation (with-arg)**: `heylogs-ext-calver/src/main/java/nbbrd/heylogs/ext/calver/CalVer.java` -6. **Reference test (no-arg)**: `heylogs-ext-semver/src/test/java/nbbrd/heylogs/ext/semver/SemVerTest.java` -7. **Reference test (with-arg)**: `heylogs-ext-calver/src/test/java/nbbrd/heylogs/ext/calver/CalVerTest.java` -8. **Reference POM (no external dep)**: `heylogs-ext-calver/pom.xml` -9. **Reference POM (external dep)**: `heylogs-ext-semver/pom.xml` - -## Step 0 — Determine the versioning characteristics - -Decide the following before writing code: - -| Decision | Option A (simpler) | Option B (complex) | -|----------------------|-------------------------------|---------------------------------------------| -| **Argument** | No argument (`withoutArg`) | Requires argument (`compilingArg` / custom) | -| **External library** | None (pure regex / algorithm) | External dependency (e.g., `semver4j`) | -| **Internal classes** | Single internal helper class | Multiple internal classes | - -This determines which reference files to follow most closely: -- No arg + no external dep → follow `heylogs-ext-pep440` pattern -- No arg + external dep → follow `heylogs-ext-semver` pattern -- With arg → follow `heylogs-ext-calver` pattern - -## Step 1 — Create the module POM - -**File**: `heylogs-ext-/pom.xml` - -**Action**: Create the file using the template below. - -**Template** (no external dependency): -```xml - - - 4.0.0 - - - com.github.nbbrd.heylogs - heylogs-parent - 0.18.2-SNAPSHOT - - - heylogs-ext- - jar - - heylogs-ext- - Keep-a-changelog tool - extension - https://github.com/nbbrd/heylogs - - - - - org.jspecify - jspecify - provided - - - org.projectlombok - lombok - provided - - - com.github.nbbrd.java-design-util - java-design-processor - provided - - - com.github.nbbrd.java-service-util - java-service-processor - provided - - - - - heylogs-api - ${project.groupId} - ${project.version} - - - - - - heylogs-api - ${project.groupId} - ${project.version} - tests - test-jar - test - - - org.junit.jupiter - junit-jupiter - test - - - org.assertj - assertj-core - test - - - -``` - -> **Note**: Read the current `` from the root `pom.xml` parent tag — do not hardcode the version shown above. - -> **External dependency**: If an external library is needed, add it in the `` section and also declare its version in the root POM `` section. - -## Step 2 — Create the public SPI class - -**File**: `heylogs-ext-/src/main/java/nbbrd/heylogs/ext//.java` - -**Action**: Create the file. The class must: -1. Be `public final` and implement `Versioning` -2. Be annotated with `@DirectImpl` and `@ServiceProvider` -3. Use `@lombok.experimental.Delegate` to delegate to a `VersioningSupport` instance -4. The `id` must be in `KEBAB_CASE` and match the module name convention - -**Template (no-arg versioning)**: -```java -package nbbrd.heylogs.ext.; - -import internal.heylogs.ext..; -import nbbrd.design.DirectImpl; -import nbbrd.heylogs.spi.Versioning; -import nbbrd.heylogs.spi.VersioningSupport; -import nbbrd.service.ServiceProvider; - -import static nbbrd.heylogs.spi.VersioningSupport.withoutArg; - -@DirectImpl -@ServiceProvider -public final class implements Versioning { - - @lombok.experimental.Delegate - private final Versioning delegate = VersioningSupport - .builder() - .id("") - .name("") - .urlOf("") - .moduleId("") - .validator(arg -> arg == null ? null : " does not take any arguments") - .predicate(withoutArg(::isValid)) - .comparator(withoutArg(::compare)) - .familyMapper(withoutArg(::toFamily)) - .build(); -} -``` - -**Template (with-arg versioning)** — see `CalVer.java` for reference: -```java -package nbbrd.heylogs.ext.; - -import internal.heylogs.ext..; -import nbbrd.design.DirectImpl; -import nbbrd.heylogs.spi.Validator; -import nbbrd.heylogs.spi.Versioning; -import nbbrd.heylogs.spi.VersioningSupport; -import nbbrd.service.ServiceProvider; - -import java.util.Objects; - -import static nbbrd.heylogs.spi.VersioningSupport.compilingArg; - -@DirectImpl -@ServiceProvider -public final class implements Versioning { - - @lombok.experimental.Delegate - private final Versioning delegate = VersioningSupport - .builder() - .id("") - .name("") - .urlOf("") - .moduleId("") - .validator(Validator.of(::parse)) - .predicate(compilingArg(::parse, ::isValidVersion)) - .comparator(arg -> { - format = .parse(Objects.requireNonNull(arg)); - return (a, b) -> compare(format, a, b); - }) - .familyMapper(arg -> { - format = .parse(Objects.requireNonNull(arg)); - return version -> toFamily(format, version); - }) - .build(); - - // Add private static helper methods for compare and toFamily -} -``` - -### `VersioningSupport` builder fields reference - -| Field | Type | Required | Description | -|----------------|----------------------------------------------------|----------|---------------------------------------------------------------------| -| `id` | `String` | Yes | Kebab-case identifier (e.g., `"pep440"`, `"semver"`) | -| `name` | `String` | Yes | Human-readable name | -| `url`/`urlOf` | `URL`/`CharSequence` | Yes | Link to the versioning spec | -| `moduleId` | `String` | Yes | Usually same as `id` | -| `validator` | `Function` | Yes | Returns null if arg valid, error message otherwise | -| `predicate` | `Function>` | Yes | Tests if a string is a valid version | -| `comparator` | `Function>` | No | Compares two versions; return 0 for incomparable | -| `familyMapper` | `Function>` | No | Maps version to family key (e.g., `"MAJOR.MINOR"`); null if invalid | - -### Helper methods in `VersioningSupport` - -| Method | Use when | Wraps argument handling | -|-----------------------------|--------------------------------------------|-------------------------------------| -| `withoutArg(Predicate)` | No argument needed | Returns predicate when arg is null | -| `withoutArg(Comparator)` | No argument needed | Returns comparator when arg is null | -| `withoutArg(Function)` | No argument needed | Returns mapper when arg is null | -| `compilingArg(factory, bi)` | Argument is compiled into an engine object | Compiles arg, then delegates | - -## Step 3 — Create the internal helper class - -**File**: `heylogs-ext-/src/main/java/internal/heylogs/ext//.java` - -**Action**: Create the file with the parsing, validation, comparison, and family-mapping logic. - -**Required static methods for no-arg versioning**: - -```java -package internal.heylogs.ext.; - -import lombok.NonNull; -import org.jspecify.annotations.Nullable; - -public final class { - - private () { - throw new UnsupportedOperationException(); - } - - /** Returns true if text is a valid version string. */ - public static boolean isValid(@NonNull CharSequence text) { ... } - - /** - * Compares two version strings. - * Returns 0 if either is invalid (incomparable). - */ - public static int compare(@NonNull CharSequence a, @NonNull CharSequence b) { ... } - - /** - * Returns the family key (typically "MAJOR.MINOR"), or null if invalid. - */ - public static @Nullable String toFamily(@NonNull CharSequence version) { ... } -} -``` - -**Implementation guidelines**: -- Use `java.util.regex.Pattern` for validation (compile as a `private static final` field) -- Return `0` from `compare` when either input is invalid (incomparable) -- Return `null` from `toFamily` when input is invalid -- Family is typically `"MAJOR.MINOR"` (first two numeric components) -- Target Java 8: no `var`, no `String.repeat()`, no `Stream.toList()`, no `List.of()` -- Use `Locale.ROOT` for any case conversions - -## Step 4 — Create the test class - -**File**: `heylogs-ext-/src/test/java/nbbrd/heylogs/ext//Test.java` - -**Action**: Create the file with four test methods. - -**Template (no-arg)**: -```java -package nbbrd.heylogs.ext.; - -import nbbrd.heylogs.spi.Versioning; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static tests.heylogs.spi.VersioningAssert.assertVersioningCompliance; - -class Test { - - @Test - public void testCompliance() { - assertVersioningCompliance(new ()); - } - - @Test - void testIsValidVersion() { - Versioning x = new (); - - // Verify that passing an argument is rejected - assertThatIllegalArgumentException() - .isThrownBy(() -> x.getVersioningPredicateOrNull("")) - .withMessage(" does not take any arguments"); - - // Verify valid and invalid versions - assertThat(x.getVersioningPredicateOrNull(null)) - .accepts(/* valid version examples */) - .rejects(/* invalid version examples */); - } - - @Test - void testComparator() { - Versioning x = new (); - - assertThatIllegalArgumentException() - .isThrownBy(() -> x.getVersioningComparatorOrNull("")) - .withMessage(" does not take any arguments"); - - assertThat(x.getVersioningComparatorOrNull(null)) - .isNotNull() - .satisfies(comparator -> { - // basic ordering - assertThat(comparator.compare("2.0.0", "1.0.0")).isPositive(); - assertThat(comparator.compare("1.0.0", "2.0.0")).isNegative(); - assertThat(comparator.compare("1.0.0", "1.0.0")).isZero(); - - // scheme-specific ordering tests - - // incomparable - assertThat(comparator.compare("invalid", "1.0.0")).isZero(); - }); - } - - @Test - void testFamilyMapper() { - Versioning x = new (); - - assertThatIllegalArgumentException() - .isThrownBy(() -> x.getVersioningFamilyMapperOrNull("")) - .withMessage(" does not take any arguments"); - - assertThat(x.getVersioningFamilyMapperOrNull(null)) - .isNotNull() - .satisfies(mapper -> { - assertThat(mapper.apply("2.4.0")).isEqualTo("2.4"); - assertThat(mapper.apply("2.4.1")).isEqualTo("2.4"); - assertThat(mapper.apply("invalid")).isNull(); - }); - } -} -``` - -**Template (with-arg)** — see `CalVerTest.java` for reference. Key differences: -- Passing `null` arg throws `IllegalArgumentException` (instead of being accepted) -- Tests pass a format string argument to each method - -**Test guidelines**: -- Always include a `testCompliance()` method calling `assertVersioningCompliance` -- Test at least 3 valid and 3 invalid versions in `testIsValidVersion` -- Test basic ordering, scheme-specific ordering, and incomparable cases in `testComparator` -- Test family mapping for multiple versions and the invalid case in `testFamilyMapper` -- Use AssertJ fluent assertions - -## Step 5 — Register the module in POMs - -Use `replace_string_in_file` for each of the following files. Insert the new module adjacent to existing versioning extensions (after `heylogs-ext-calver` or `heylogs-ext-semver`). - -### 5a — Root POM (`pom.xml`) - -Add `heylogs-ext-` in the `` section: -```xml -heylogs-ext- -``` - -### 5b — BOM (`heylogs-bom/pom.xml`) - -Add a `` entry in ``: -```xml - - heylogs-ext- - ${project.groupId} - ${project.version} - -``` - -### 5c — Consumer modules (runtime dependency) - -Add a `runtime` dependency in each of: -- `heylogs-cli/pom.xml` -- `heylogs-maven-plugin/pom.xml` -- `heylogs-enforcer-rules/pom.xml` - -```xml - - heylogs-ext- - ${project.groupId} - ${project.version} - runtime - -``` - -### 5d — Architecture tests (`heylogs-architecture-tests/pom.xml`) - -Add a `test` dependency: -```xml - - com.github.nbbrd.heylogs - heylogs-ext- - ${project.version} - test - -``` - -## Step 6 — Update documentation - -### Versioning table (`docs/feature-versioning.md`) - -Add a row to the versioning schemes table in **alphabetical order** by ID: - -```markdown -| `` | []() | `` | - | -``` - -The argument column should be `-` for no-arg versionings, or a description for with-arg. - -Also add a usage example: -```markdown -- `$ heylogs check -v ` -``` - -## Post-implementation checks - -**Validation**: After all edits, call `get_errors` on these files: -- `heylogs-ext-/src/main/java/nbbrd/heylogs/ext//.java` -- `heylogs-ext-/src/main/java/internal/heylogs/ext//.java` -- `heylogs-ext-/src/test/java/nbbrd/heylogs/ext//Test.java` - -## Testing - -```shell -# Fast test of the new module -mvn test -pl heylogs-ext- -am -Pyolo - -# Full build with all checks -mvn clean install -``` - -Expect: -- 4 tests run (compliance + isValidVersion + comparator + familyMapper) -- 0 failures, 0 errors -- BUILD SUCCESS - -## Constraints - -- **ID** must match `ServiceId.KEBAB_CASE` (lowercase letters, digits, hyphens; e.g., `pep440`, `semver`, `calver`). -- **Java 8 target**: no `var`, `String.repeat()`, `Stream.toList()`, `List.of()`, `Map.of()`. -- **No BOM in source files**: if creating files via PowerShell, use `[System.IO.File]::WriteAllText(path, content, (New-Object System.Text.UTF8Encoding $false))` to avoid UTF-8 BOM bytes. -- **Internal packages**: parsing/comparison logic goes in `internal.heylogs.ext.` — never expose internal types in the public API. -- **Annotations**: `@DirectImpl` + `@ServiceProvider` on the public class; `@lombok.experimental.Delegate` on the delegate field. -- **Backward compatibility**: the `Versioning` SPI contract requires `getVersioningPredicateOrNull` to throw `IllegalArgumentException` when the validator rejects the arg. -- **Incomparable versions**: `compare()` must return `0` when either input is not a valid version for the scheme. -- **Family mapping**: `toFamily()` must return `null` when the input is not a valid version. -- **No additional features**: do not add features beyond what the `Versioning` SPI defines. - -## Quick reference — Existing versioning modules - -| Module | ID | Arg? | External dep? | Internal class(es) | -|----------------------|----------|------|------------------|-----------------------------------| -| `heylogs-ext-semver` | `semver` | No | `semver4j` | (none — uses library directly) | -| `heylogs-ext-calver` | `calver` | Yes | No | `CalVerFormat`, `CalVerTag`, etc. | -| `heylogs-ext-pep440` | `pep440` | No | No | `Pep440Version` | -| `heylogs-ext-maven` | `maven` | No | `maven-artifact` | (none — uses library directly) | - diff --git a/AGENTS.md b/AGENTS.md index 4944054..5c189b2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ Heylogs is a Java 8+ multi-module Maven project for validating and releasing changelogs in [Keep a Changelog](https://keepachangelog.com) format. It parses Markdown into an AST (via [flexmark-java](https://github.com/vsch/flexmark-java)) and operates on the tree. -> **This file** covers building and contributing to Heylogs itself. To *use* Heylogs (run `check`, tune rules, configure `heylogs.properties`) on a changelog, see the [`heylogs` skill](skills/heylogs/SKILL.md). +> **This file** covers building and contributing to Heylogs itself. To *use* Heylogs (run `check`, tune rules, configure `heylogs.properties`) on a changelog, see the [`changelog` skill](skills/changelog/SKILL.md). ## Architecture diff --git a/README.md b/README.md index 7b658b0..88f4485 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Heylogs is available in multiple formats to fit your workflow: - **[Maven Enforcer rules](docs/usage-enforcer-rules.md)** - Enforce changelog quality in builds - **[CI/CD pipelines](docs/usage-pipelines.md)** - Integrate into CI/CD environments -> Using an AI coding assistant? The [`heylogs` skill](skills/heylogs/SKILL.md) is an agent-generic guide to running `check`, tuning rules, and configuring `heylogs.properties`. Install it with `npx skills add nbbrd/heylogs --skill heylogs` ([details](skills/heylogs/README.md)). +> Using an AI coding assistant? The [`changelog` skill](skills/changelog/SKILL.md) is an agent-generic guide to running `check`, tuning rules, and configuring `heylogs.properties`. Install it with `npx skills add nbbrd/heylogs` ([details](skills/changelog/README.md)). ## Features diff --git a/skills/heylogs/README.md b/skills/changelog/README.md similarity index 81% rename from skills/heylogs/README.md rename to skills/changelog/README.md index 584f2b4..9fc75f2 100644 --- a/skills/heylogs/README.md +++ b/skills/changelog/README.md @@ -1,6 +1,6 @@ -# Install the `heylogs` skill +# Install the `changelog` skill -The `heylogs` skill teaches an AI coding agent how to validate and maintain +The `changelog` skill teaches an AI coding agent how to validate and maintain [Keep a Changelog](https://keepachangelog.com)–formatted `CHANGELOG.md` files with the **[Heylogs](https://github.com/nbbrd/heylogs)** CLI — running `check`, tuning rules, and configuring `heylogs.properties`. The skill definition is in @@ -24,7 +24,7 @@ explains how to run it with no prerequisites via JBang (see ## Installation ```bash -npx skills add nbbrd/heylogs --skill heylogs +npx skills add nbbrd/heylogs ``` The installer fetches the skill from the repository, asks which agents to install @@ -36,23 +36,23 @@ Confirm to finish. Non-interactive (CI-friendly) install for Claude Code, global: ```bash -npx skills add nbbrd/heylogs --skill heylogs -g -a claude-code -y +npx skills add nbbrd/heylogs -g -a claude-code -y ``` ## Alternative: manual installation If you prefer not to use `npx skills`, download the skill folder -[`skills/heylogs/`](.) and register it as a local skill folder per your agent's +[`skills/changelog/`](.) and register it as a local skill folder per your agent's documentation (no Node.js required). ## Update ```bash -npx skills update heylogs +npx skills update changelog ``` ## Usage -Once installed, invoke `/heylogs` in the selected agent, or just ask it to check, +Once installed, invoke `/changelog` in the selected agent, or just ask it to check, fix, or release a changelog — the skill's `description` triggers it automatically. See the [skill definition](SKILL.md) for full capabilities. diff --git a/skills/heylogs/SKILL.md b/skills/changelog/SKILL.md similarity index 96% rename from skills/heylogs/SKILL.md rename to skills/changelog/SKILL.md index 1501797..a6a7805 100644 --- a/skills/heylogs/SKILL.md +++ b/skills/changelog/SKILL.md @@ -1,9 +1,9 @@ --- -name: heylogs +name: changelog description: > - Validate and maintain Keep a Changelog–formatted CHANGELOG.md files with the - Heylogs CLI. Use this skill whenever the user asks to check, lint, validate, - fix, format, or release a changelog, sees Heylogs rule violations (e.g. + Check, lint, fix, format, or release Keep a Changelog CHANGELOG.md files with + the Heylogs CLI. Use this skill whenever the user asks to validate or maintain + a changelog, sees Heylogs rule violations (e.g. no-empty-group, latest-version-first, forge-ref), wants to get a repo to "0 problems" via heylogs.properties without editing the changelog, or needs to add/extract/export changelog entries. Covers the `check` command and rule diff --git a/skills/heylogs/references/commands.md b/skills/changelog/references/commands.md similarity index 100% rename from skills/heylogs/references/commands.md rename to skills/changelog/references/commands.md diff --git a/skills/heylogs/references/config-file.md b/skills/changelog/references/config-file.md similarity index 100% rename from skills/heylogs/references/config-file.md rename to skills/changelog/references/config-file.md diff --git a/skills/heylogs/references/rules.md b/skills/changelog/references/rules.md similarity index 100% rename from skills/heylogs/references/rules.md rename to skills/changelog/references/rules.md diff --git a/skills/heylogs/references/running-cli.md b/skills/changelog/references/running-cli.md similarity index 100% rename from skills/heylogs/references/running-cli.md rename to skills/changelog/references/running-cli.md