If you use Git worktrees, you probably know the pain. You're deep in your IDE, focused, and then you need to create a new worktree or switch to another one. So you open a terminal, type git worktree add, manually navigate to the new folder, open it in a new IDE window... and by the time you're set up, you've lost your flow.
I've been using worktrees for a while now, and this back-and-forth with the terminal always bugged me. One day I checked and realized JetBrains has absolutely zero native support for worktrees. No panel, no action, nothing. You'd think for an IDE that has amazing Git integration, worktree management would be in there somewhere. But nope 😅
There is an existing plugin that handles worktrees, but some of its features are behind a paywall. I figured if I'm going to solve this problem, I might as well make it fully free and open source so other developers can benefit from it too.
So I decided to build it myself.
The problem: I don't know Kotlin
Here's the thing. I'm a frontend developer. TypeScript, React, that's my world. I had never written a single line of Kotlin, never touched the IntelliJ Platform SDK, and had no idea how JetBrains plugins even work internally.
Building an IDE plugin felt like a completely different universe. The IntelliJ SDK is massive, the documentation can be dense, and the patterns are very specific (extension points, services, message buses, thread management...). Not exactly a weekend side project for someone coming from the web world 😬
But I had Claude Code on my side, and I had plans to push it further than usual.
My Claude Code setup
I've been using Claude Code for a while across different projects, so I'm pretty familiar with how to get the most out of it. For this plugin, I knew I needed to go beyond the default experience. The IntelliJ SDK is a niche domain, and I wanted Claude to be as specialized as possible.
So I did two things:
A custom JetBrains expert subagent
Claude Code lets you create custom subagents. These are specialized agents with their own system prompts and tools. I created a jetbrains-expert agent (.claude/agents/jetbrains-expert.md) that acts as a dedicated IntelliJ Platform SDK expert.
This agent knows about:
- Plugin architecture and
plugin.xmlstructure - Kotlin UI DSL v2 for building dialogs and settings panels
- Threading rules (never block the EDT!)
- Services, extension points,
MessageBuspatterns - VCS integration, process execution, persistence
- Common pitfalls and deprecated API migrations
Instead of Claude having general knowledge about "maybe how IntelliJ plugins work," this subagent has focused, structured knowledge about the exact patterns and APIs I needed. It made a massive difference in code quality from the very first prompt.
A google-research MCP plugin (instead of WebSearch)
Claude Code has a built-in WebSearch tool, but I wasn't happy with it. The results were often shallow, and there's a security concern I cared about: with WebSearch, Claude directly processes raw web content. That means any prompt injection hidden in a web page could potentially influence Claude's behavior.
So I built my own research plugin as part of my Claude Code plugin marketplace. It's called google-research and it works differently. Instead of Claude reading web pages directly, the plugin sends queries to Google Gemini with Google Search grounding enabled. Gemini does the searching, reads the pages, reasons over them with high-level thinking, and returns a synthesized report with inline citations. Claude only ever sees Gemini's output, never the raw web content.
This gives me several things WebSearch doesn't. The search quality is better because Gemini actually reasons over the results instead of just returning links. Every claim in the report comes with inline citations mapped to specific sources, so I can verify what I'm reading. Grounding means the answers are based on real web content, not hallucinated. The content goes through sanitization (strips scripts, iframes, external images) and Gemini's safety filters before reaching Claude, which reduces the prompt injection surface. And I have full control over focus areas, output format, and the research even gets saved to disk automatically.
I used it for everything during the plugin development: looking up IntelliJ SDK docs, researching best practices, checking how other plugin developers solved similar problems.
Having this inside Claude Code means I never had to leave the terminal to go Google something. Claude could just search on its own and come back with grounded answers.
How the development actually worked
I didn't start from a template. Claude set up the entire project from scratch: Gradle config, plugin.xml, project structure, the whole thing. I described what I wanted to build and it scaffolded everything.
From there, features came one at a time. I started with the basics, just listing worktrees in a VCS tab. Then I thought "ok, what if I could create one from here?" Then sync files.
Then PR checkout. The scope grew as I went. Every time I thought "it would be nice if..." I'd just describe it and Claude would build it.
Claude Code wrote the majority of the plugin. I'm not going to pretend otherwise. But it wasn't just "generate code and paste it." It was more like having a senior Kotlin developer sitting next to me who also happened to know the IntelliJ SDK inside out.
A typical cycle looked like this:
- I'd describe what I wanted: "I need a panel in the VCS tool window that lists all worktrees"
- Claude (via the jetbrains-expert subagent) would write the code, using the right IntelliJ APIs like
changesViewContentextension point,TreewithDefaultTreeModel,ColoredTreeCellRenderer... - I'd review it, test it in the sandbox IDE, and iterate
The IntelliJ SDK has a lot of "you need to know this exists" moments. Things like CapturingProcessHandler for running CLI commands, ProgressManager for background tasks, MessageBus for event-driven UI updates. The subagent knew about all of these and used them correctly from the start. That saved me an insane amount of time compared to digging through docs and StackOverflow.
What surprised me the most is that the code didn't feel like "AI-generated code." It followed IntelliJ conventions, used the right patterns, and didn't over-engineer things. I think the custom subagent prompt was key here. It had explicit guidelines like "prefer native IntelliJ Platform APIs" and "don't over-engineer."
What the plugin does
The plugin adds a Worktrees tab in the VCS tool window. From there, you can manage everything without touching the terminal:
You can create worktrees by picking a path and creating a new branch (or using an existing one), with options to auto-sync files and run post-creation commands like npm install. You can remove, lock, and move worktrees directly from the UI. You can also open a worktree in a new window with one click.
One of the features I'm most happy with is file sync across worktrees. It copies .idea/ settings, .env files, or any custom paths you configure. You can set up exclusions too, so you don't accidentally sync workspace.xml and break your window layout.
PR checkout is another one. You enter a PR number and the plugin figures out the right refspec for GitHub, GitLab, or Bitbucket automatically. No need to remember if it's pull/123/head or merge-requests/123/head.
There's also a compare view that shows a side-by-side table with branch, commit, and status for all your worktrees. And you can create a worktree from any commit by right-clicking in the VCS Log.
The plugin also decorates your IDE. The window title shows which worktree branch you're on ([worktree: feature-branch]), and the project sidebar displays the branch name next to the root folder. Small details, but when you're juggling 3-4 worktrees across multiple windows, it makes a big difference.
There's a full settings page under Tools > Git Worktree Tool where you can configure default directories, sync behavior, .idea exclusions, custom sync paths, and post-creation hooks.
The tricky parts
The development was mostly smooth. The subagent really did its job. But there were still some bumps.
The biggest headache was threading. IntelliJ is very strict about what runs on which thread. Git commands have to run in the background (otherwise the UI freezes), but UI updates have to happen on the EDT (Event Dispatch Thread). Sounds simple, but in practice we ran into issues where the worktree panel just wouldn't update after creating or removing a worktree. The data was there, the cache was refreshed, but the tree component wasn't picking it up. Turned out the events were being published on the wrong thread. We ended up using a MessageBus topic (WorktreeListChangedTopic) to properly notify the panel, and that fixed it. But it took a few iterations to get the threading dance right.
Parsing git worktree list --porcelain was more complex than expected too. The output is stateful, you read lines one by one and accumulate fields (path, head, branch, flags) until you hit the next worktree line. Claude nailed the parser, but reviewing it required me to actually understand the git output format in detail.
PR checkout across providers also had a lot of edge cases. GitHub uses pull/123/head, GitLab uses merge-requests/123/head, Bitbucket uses pull-requests/123/from. The plugin detects which provider you're using by parsing the remote URL and builds the right refspec automatically. One of those features that sounds trivial but has more surface area than you'd think.
What I learned from this
Could I have built this plugin without Claude Code? Probably yes, eventually. But it would have taken me significantly longer. Kotlin isn't that far from TypeScript conceptually, and the IntelliJ SDK is well-documented. But the ramp-up time from "I've never written a plugin" to "I have a working VCS tab with a tree model and background threading"... that's where Claude was a massive accelerator.
If I had to give advice to someone thinking about doing something similar, I'd say: invest time in the setup. Creating the specialized subagent was probably the single biggest factor in code quality. Generic AI produces generic code. When you give it focused knowledge about the specific SDK and patterns you're working with, the output is on a completely different level.
You also still need to understand what you're building. I knew exactly what worktree features I wanted because I use them daily. Claude can write the code, but it can't tell you what to build.
And review everything. I learned Kotlin patterns and IntelliJ APIs by reading what Claude produced, not by blindly shipping it. The generated code became my learning material.
One last thing: having MCP plugins for research (like google-research) kept things moving. Being able to search docs without leaving the coding flow made a real difference, especially for a niche SDK where you need very specific, up-to-date information.
Try it out
The plugin is available on the JetBrains Marketplace. Just search for "Git Worktree Manager" in your IDE's plugin settings.
It's also open source, so feel free to check the code, open issues, or contribute:
- 🔗 JetBrains Marketplace
- 💻 GitHub Repository
The custom subagent is in the plugin repo under .claude/agents/. And the google-research MCP plugin I mentioned is part of my Claude Code plugin marketplace, where you can also find other plugins like Discord and Reddit integrations.
If you use Git worktrees in your workflow, I'd love to hear your feedback. What features would you want to see next? And if you've pushed Claude Code with custom subagents or MCP plugins, I'm curious to hear what you've built 🙂
Happy coding!




Top comments (0)