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
173 changes: 173 additions & 0 deletions .claude/skills/intellij-version-upgrade/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
---
name: intellij-version-upgrade
description: Update this repository to support a new IntelliJ IDEA or platform release. Use this whenever the user asks to add support for a newer IDE version, bump the IntelliJ target, update plugin compatibility metadata, or prepare the repo for a new IntelliJ release. Also use it when the work likely involves `platformVersion`, `pluginSinceBuild`, `CHANGELOG.md`, release steps, or IntelliJ Platform Gradle plugin upgrades.
---

# IntelliJ Version Upgrade

Use this skill to update this repository for a new IntelliJ IDEA release with minimal churn and strong validation.

This repo has an established pattern for compatibility bumps: start with metadata changes, verify the build, and only expand into build-tooling or CI changes when the new IDE version actually requires them.

## Repository-specific expectations

- Main compatibility knobs live in `gradle.properties`:
- `pluginVersion`
- `pluginSinceBuild`
- `platformVersion`
- The Gradle build already reads those values in `build.gradle.kts`, so prefer changing properties rather than rewriting build logic.
- Release notes belong in `CHANGELOG.md`, usually under `[Unreleased]` as `Compatibility with IntelliJ <version>`.
- Release flow reference is in `RELEASE.md`.
- Common validation commands are:
- `./gradlew build`
- `./gradlew check`
- `./gradlew verifyPlugin`
- optional: `./gradlew runIde`

## Workflow

### 1. Inspect the current state

Read these files first:

- `gradle.properties`
- `gradle/libs.versions.toml`
- `build.gradle.kts`
- `CHANGELOG.md`
- `RELEASE.md`
- `qodana.yml`
- `.github/workflows/build.yml`
- `.github/workflows/release.yml`
- `.github/workflows/run-ui-tests.yml` if present
- `CLAUDE.md` if present

Then inspect repo history for prior compatibility updates. Search recent commits and branches for terms like:

- `Compatibility with IntelliJ`
- `Compatibility adjustments`
- `platformType`
- `sinceBuild`

The goal is to recover the repo’s house style before making changes.

### 2. Confirm the exact IntelliJ build baseline

Do not guess `pluginSinceBuild`.

Look up the correct baseline build family for the requested IntelliJ release from JetBrains sources, then set `pluginSinceBuild` to that exact baseline. For example, IntelliJ IDEA 2026.1 maps to baseline `261`.

If you use web search, cite the source in your response.

### 3. Make the minimal compatibility update first

Start with the smallest likely change set:

- Update `gradle.properties`
- bump `platformVersion`
- bump `pluginSinceBuild`
- bump `pluginVersion` to the next release version if this change is intended to ship
- Update `CHANGELOG.md`
- add `Compatibility with IntelliJ <version>` under `[Unreleased]`

Keep `build.gradle.kts` unchanged unless verification proves the IntelliJ Platform Gradle plugin DSL or build wiring needs adjustment.

## Dependency and tooling updates

When a new IntelliJ release is involved, inspect open dependency-update PRs and current pinned versions, but keep the rule simple:

- Prefer updating dependencies that are already clearly part of the IntelliJ/tooling stack for this repo.
- Do not churn unrelated dependencies just because a new IDE version is being added.

### IntelliJ Platform Gradle plugin rule

Whenever you update `org.jetbrains.intellij.platform` in `gradle/libs.versions.toml`, you must check the release notes before finalizing the change.

Specifically:

1. Review release notes for the exact upgrade range.
2. Look only for actionable migration items:
- minimum supported Gradle version changes
- removed DSL aliases or deprecated APIs
- required build script changes
- sandbox path changes
- plugin verification DSL changes
3. Apply required repo changes if they affect this repository.
4. If there are no required repo changes, say that explicitly in the final summary.

For this repo, note that an upgrade from `org.jetbrains.intellij.platform` 2.10.5 to 2.13.1 did **not** require additional repo changes beyond the version bump, but that fact is specific to this repo state and must be rechecked for future upgrades.

### Qodana and CI

Only update `qodana.yml`, workflow actions, Gradle wrapper, or Java/tool versions when one of these is true:

- the current build warns that the tool is outdated
- the new IntelliJ version breaks verification/building with current tooling
- there is an already-open dependency-update path that clearly belongs with the IDE upgrade

Good candidates in this repo:

- `gradle/libs.versions.toml`
- `qodana.yml`
- `.github/workflows/*.yml`
- `.java-version`
- `gradle/wrapper/gradle-wrapper.properties`

## Validation

After editing, run:

1. `./gradlew build`
2. `./gradlew verifyPlugin`
3. `./gradlew check` if needed for extra confidence or if other files changed
4. optionally `./gradlew runIde` for a sandbox smoke test

Treat `build` and `verifyPlugin` as the core gate.

If verification succeeds with deprecation or override-only API warnings, do not expand scope unless the user asked for cleanup. Report the warnings succinctly and leave them alone.

## Pull request and release behavior

If the user asks for a PR:

1. Check whether unrelated working-tree files exist.
2. Ask whether to include unrelated files if scope is ambiguous.
3. Create a focused branch.
4. Commit only the intended files.
5. Create a PR with:
- a short title like `Add IntelliJ IDEA <version> support`
- summary bullets for metadata/tooling updates
- a test plan listing `./gradlew build` and `./gradlew verifyPlugin`
- a note on the IntelliJ Platform Gradle plugin release-notes review if that plugin was bumped

### Full release workflow for this repository

When the user wants the whole change shipped, follow the release sequence from `RELEASE.md`:

1. Make sure `CHANGELOG.md` has the compatibility note under `[Unreleased]`.
2. Make sure `gradle.properties` has the new `pluginVersion`.
3. Open the PR and get it green.
4. Merge the PR into the repository's release branch/mainline used by the workflow.
5. Wait for GitHub Actions to create the draft GitHub Release.
6. Publish the GitHub Release (convert it from draft to released).
7. Wait for the automation to open the changelog PR created from the release flow.
8. Merge the changelog PR.

Important:

- Treat merge, release publication, and changelog-PR merge as separate high-impact actions. Confirm before doing them unless the user explicitly asked for unattended end-to-end execution.
- If branch naming differs (`main` vs `master`), follow the repository's current release workflow rather than hard-coding a branch name.
- After the PR is green, the release work is not finished until the draft release has been published and the changelog PR has been merged.

If the user asks for unattended execution, follow this workflow end-to-end unless a risky scope decision requires confirmation.

## Output checklist

When you finish, summarize:

- new `platformVersion`
- new `pluginSinceBuild`
- new `pluginVersion` if bumped
- any dependency/tooling changes made
- whether `build` passed
- whether `verifyPlugin` passed
- whether IntelliJ Platform Gradle plugin release notes required any repo changes
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

## [Unreleased]

### Added

- Compatibility with IntelliJ 2026.1

## [0.0.19] - 2025-12-27

### Added
Expand Down
55 changes: 55 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Build, test, and run commands

- `./gradlew build` — full plugin build.
- `./gradlew check` — main local verification path; runs tests plus configured checks. Matches `.run/Run Tests.run.xml`.
- `./gradlew verifyPlugin` — JetBrains plugin verification against recommended IDEs. Matches `.run/Run Verifications.run.xml`.
- `./gradlew test` — run the test suite.
- `./gradlew test --tests 'io.github.srizzo.codebuddy.twiddle.TwiddleActionTest'` — run one test class.
- `./gradlew test --tests 'io.github.srizzo.codebuddy.twiddle.TwiddleActionTest.testTwiddleAction'` — run one test method.
- `./gradlew runIde` — launch a sandbox IDE with the plugin installed. Matches `.run/Run Plugin.run.xml`.
- `./gradlew runIdeForUiTests` — launch IDE configured for UI tests / robot server on port 8082.

## Architecture overview

This is an IntelliJ Platform plugin called `CodeBuddy`, targeting IntelliJ IDEA 2025.3+ (`gradle.properties`). The plugin is registered through `src/main/resources/META-INF/plugin.xml`, which wires together actions, application services, a bundled macOS keymap, the settings page, and a post-startup activity.

### Main feature areas

- `findreplace/`: headless find/replace actions that operate on the current editor selection and update IntelliJ `FindModel`s instead of opening the usual search UI.
- `select/`: editor selection helpers such as paragraph selection and enclosing typing-pair selection.
- `twiddle/`: multi-caret text rotation/swapping behavior.
- `columnmode/`: temporary column-selection mode behavior, including modifier-key driven entry/exit, single-caret restoration, and cursor updates.
- `settings/`: persisted application-level plugin settings shown under Editor > CodeBuddy.
- `util/`: shared editor/action helpers used across features.

### How column mode works

Column mode is the most cross-cutting part of the plugin.

- `ColumnModeStartupActivity` installs a global `IdeEventQueue` dispatcher after project startup.
- That dispatcher watches raw `KeyEvent`s and conditionally triggers IntelliJ actions by ID through `RunActionUtil`.
- Behavior is gated by booleans in `CodeBuddySettingsState`, which is an application-level `PersistentStateComponent` stored in `CodeBuddySettingsPlugin.xml`.
- `BlockSelectionUtil` contains the core selection/block-selection conversion logic and platform-specific modifier detection (`Alt` on macOS, `Ctrl` elsewhere).
- `CrosshairCursorOnColumnModeUpdater` and related actions provide the visual/editor-state side of the feature.

When editing column mode behavior, check both the event interception path and the action implementations; the feature is split between startup wiring, settings flags, and editor mutation utilities.

### Actions and IDs

Most user-facing behavior is exposed as IntelliJ actions declared in `plugin.xml`. Tests and internal code often invoke actions by ID or by action class constant rather than by directly calling helper methods, so keep action IDs stable unless you also update tests and registrations.

### Testing approach

Tests are mostly IntelliJ fixture tests based on `BasePlatformTestCase` via `src/test/java/io/github/srizzo/codebuddy/test/BaseTestCase.java`. Test data for editor-behavior tests lives under `src/test/testData/`. Some newer tests are simpler instantiation/assertion tests that do not use fixtures.

When changing editor actions, check whether the existing test style is fixture-based with before/after files or a lighter unit-style test, and extend the matching style instead of introducing a third pattern.

## Project-specific notes

- The Gradle build extracts the plugin description from the `<!-- Plugin description --> ... <!-- Plugin description end -->` block in `README.md`; keep that block valid when editing plugin metadata.
- Plugin compatibility is driven by `pluginSinceBuild=252` and `platformVersion=2025.3` in `gradle.properties`.
- The repository uses the IntelliJ Platform Gradle Plugin 2.x, plus Changelog, Qodana, and Kover plugins (`gradle/libs.versions.toml`).
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ pluginGroup = io.github.srizzo
pluginName = codebuddy
pluginRepositoryUrl = https://github.com/srizzo/code-buddy-plugin
# SemVer format -> https://semver.org
pluginVersion = 0.0.19
pluginVersion = 0.0.20

# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
pluginSinceBuild = 252
pluginSinceBuild = 261

# IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
platformVersion = 2025.3
platformVersion = 2026.1

# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.jetbrains.php:203.4449.22, org.intellij.scala:2023.3.27@EAP
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ opentest4j = "1.3.0"

# plugins
changelog = "2.5.0"
intelliJPlatform = "2.10.5"
intelliJPlatform = "2.13.1"
kotlin = "2.2.21"
kover = "0.9.3"
qodana = "2025.2.2"
Expand Down
2 changes: 1 addition & 1 deletion qodana.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# https://www.jetbrains.com/help/qodana/qodana-yaml.html

version: "1.0"
linter: jetbrains/qodana-jvm-community:2024.3
linter: jetbrains/qodana-jvm-community:2025.2
projectJDK: "21"
profile:
name: qodana.recommended
Expand Down
Loading