This repository is an IntelliJ Platform plugin written in Kotlin. It provides a "Developer Tools" tool window, standalone dialog, editor popup actions, and intention actions for common developer utilities.
Use this file as the working map for future AI agents. It explains where the important code lives, how tools are registered, how state is persisted, and what commands to run before handing work back.
- Root Gradle project:
intellij-developer-tools-plugin - Build system: Gradle Kotlin DSL with
org.jetbrains.intellij.platformplugin. - Language/runtime: Kotlin/JVM on Java 21.
- Minimum IDE build and platform are controlled from
gradle.properties. - The default
platform=ideaincludes Java- and Kotlin-dependent modules. Non-IDEA platforms only include the platform/common modules. - Plugin id is intentionally misspelled as
dev.turingcomplete.intellijdevelopertoolsplugins; do not "fix" it.
Important root files:
build.gradle.kts: root build, IntelliJ plugin packaging, signing, publishing, verification, common test/compiler config.settings.gradle.kts: module inclusion; conditionally includesjava-dependentandkotlin-dependentwhenplatform == "idea".gradle/libs.versions.toml: dependency and plugin versions.gradle.properties: plugin metadata, platform version, bundled plugins, Kotlin stdlib opt-out.src/main/resources/META-INF/plugin.xml: main plugin descriptor and extension-point registry.src/main/resources/META-INF/dev.turingcomplete.intellijdevelopertoolsplugins-withJava.xml: optional Java plugin integrations.src/main/resources/META-INF/dev.turingcomplete.intellijdevelopertoolsplugins-withKotlin.xml: optional Kotlin plugin integrations.
modules/common: shared utilities, i18n bundle wrapper, plugin info, editor helpers, crypto/hash/text helpers, test fixtures.modules/settings: application and instance settings, settings UI abstractions, persistence and legacy migration for tool configurations.modules/tools/editor: editor popup actions and generic editor intentions for selected text.modules/tools/ui: the main UI tool framework, tool window/dialog implementation, all UI tools, shared Swing/UI DSL components, test fixtures.modules/java-dependent: Java PSI-specific editor actions and intentions. Only loaded through optional Java descriptor.modules/kotlin-dependent: Kotlin PSI-specific editor actions and intentions. Only loaded through optional Kotlin descriptor.src/test: root-level integration tests around plugin XML and cross-module tool behavior.
The main descriptor is src/main/resources/META-INF/plugin.xml.
It declares:
- Required dependencies: platform, lang, json.
- Optional dependencies:
com.intellij.javaandorg.jetbrains.kotlin, each with its own descriptor. - Tool window:
MainToolWindowFactory, idDeveloper Tools. - Standalone dialog action:
OpenMainDialogAction, added toToolsMenu. - Editor popup group:
DeveloperToolsActionGroup, added toEditorPopupMenu. - Main selected-text intention:
DataGeneratorIntentionAction. - Settings configurable:
GeneralSettingsConfigurablewith nestedJsonHandlingSettingsConfigurable. - Keymap extension:
ShowDeveloperUiToolKeymapExtension. - Custom extension points:
developerUiTool: registers tool factories.developerUiToolGroup: registers menu groups.developerToolConfigurationEnumPropertyType: registers enum types that can be persisted in tool settings.
The Java/Kotlin optional descriptors add language-specific intentions and editor action groups. Keep those registrations out of the main descriptor unless they do not depend on Java/Kotlin APIs.
Most new user-facing utilities should be implemented as a DeveloperUiTool in modules/tools/ui.
Core classes:
DeveloperUiTool: base class for a tool UI. Subclasses implementPanel.buildUi(). It wraps UI DSL output, registers validation, supports activation/deactivation, reset, disposal, scroll wrapping, and optionalDataProviderdata.DeveloperUiToolFactory<T>: creates tools and returnsDeveloperUiToolPresentation.DeveloperUiToolFactoryEp: extension-point bean fordeveloperUiTool; readsid,implementationClass,groupId,preferredSelected, andinternalToolfromplugin.xml.DeveloperUiToolContext: carries the extension id and whether vertical layout should be preferred, mainly for tool-window layout.DeveloperUiToolPresentation: titles/descriptions used in menu, grouped menu, and content panel.DeveloperUiToolGroup: extension-point bean for grouping tools in the menu tree.
Registration flow:
plugin.xmlregisters a<developerUiTool id="..." implementationClass="...$Factory"/>.ToolsMenuTreereadsDeveloperUiToolFactoryEp.EP_NAME.- Each factory is instantiated and asked for a tool creator.
DeveloperToolNoderestores or createsDeveloperToolConfigurationworkbenches.DeveloperToolContentPanelcreates tabs, callsDeveloperUiTool.createComponent(), and drivesactivated()/deactivated().
If a factory returns null from getDeveloperUiToolCreator, the tool is hidden for that context. This is useful for project-dependent tools.
Two instances expose the same tool framework with different persistence scopes:
-
Dialog:
OpenMainDialogActionopensMainDialogService.MainDialogusesContentPanelHandlerandDeveloperToolsDialogSettings.- Dialog inputs/configuration are application-level.
-
Tool window:
MainToolWindowFactorycreates async tool-window content.MainToolWindowServicestores and opens/selects tool-window content.ToolWindowContentPanelHandlerusesDeveloperToolsToolWindowSettings.- Tool-window inputs/configuration are project-level.
ContentPanelHandler is the shared coordinator. It owns the menu tree, switches group/tool panels, caches panels depending on generalSettings.toolWindowUiCacheUi, and implements openTool()/showTool().
Application settings:
DeveloperToolsApplicationSettingsis an app service persisted todeveloper-tools.xml.- It contains
GeneralSettings,InternalSettings, andJsonHandlingSettings. - Settings interfaces use annotations from
modules/settings/.../base.
Tool instance settings:
DeveloperToolsInstanceSettingsis the basePersistentStateComponent.DeveloperToolsDialogSettingsstores dialog state at app level.DeveloperToolsToolWindowSettingsstores tool-window state at project level.- Each UI tool workbench has a
DeveloperToolConfiguration. - Tool properties are registered by calling
configuration.register("key", defaultValue, propertyType, example).
Persistence details to respect:
- Only changed properties are persisted.
PropertyType.CONFIGURATION,INPUT, andSENSITIVEare filtered by general settings.- Sensitive values are not saved unless
saveSensitiveInputsis enabled. - Supported built-in persisted value types are in
DeveloperToolsInstanceSettings.builtInConfigurationPropertyTypes. - Enum configuration values must be registered in
plugin.xmlvia<developerToolConfigurationEnumPropertyType ...>. - If renaming property keys or moving enum classes, update
DeveloperToolsInstanceSettingsLegacyand the legacy test resources undersrc/test/resources/.../instancesettings.
Common base classes in modules/tools/ui/src/main/kotlin/.../tool/ui:
converter/base/Converter: two-pane conversion base with source/target handlers, live conversion, validation, diff support, file/text handlers, and background conversion for heavy work.converter/base/UndirectionalConverter: one-way converter UI.EncoderDecoder: bidirectional converter base for encoding/decoding tools.OneLineTextGenerator: generator base for UUID/password/NanoID/etc.; handles generated value, copy, regenerate, and bulk generation.MultiLineTextGenerator: generator base for multi-line output.AdvancedEditor: shared editor component with input/output modes and diff support.AsyncTaskExecutor: debounced async UI/background task helper.FileHandling,ErrorHolder, validation helpers, regex helpers, and copy actions intool/ui/common.
Tool categories and representative files:
- Converters:
tool/ui/converter, including Base32/Base64, URL, ASCII, text format, date/time, CLI command, JWT, units. - Transformers:
tool/ui/transformer, including hashing/HMAC, text case, sorting/filtering, JSON Path, SQL and code formatting. - Generators:
tool/ui/generator, including UUID/ULID/NanoID/password/lorem/barcode. - Other tools:
tool/ui/other, including regex matcher, JSON schema validator, unarchiver, color picker, server certificates, HTTP server, notes, text diff/statistics, cron, ASCII art.
When adding a new UI tool:
- Choose the closest base class instead of starting from
DeveloperUiTooldirectly. - Put it in the matching package under
modules/tools/ui. - Add a nested
Factory : DeveloperUiToolFactory<YourTool>. - Register the factory in
plugin.xmlwith a stableid. - Add enum property type registrations for any persisted enum defaults.
- Use
configuration.register(...)for all persisted controls. Pick stable keys. - Add bundle entries if the surrounding package uses message bundles.
- Add or update tests when persistence, plugin XML registration, or conversion behavior changes.
Generic selected-text actions live in modules/tools/editor.
DeveloperToolsActionGroupis the root editor popup group.EncodeDecodeActionGroup,EscapeUnescapeActionGroup,TextCaseConverterActionGroup,DataGeneratorActionGroup, andEditorTextStatisticActionoperate mostly on selected text.- Shared operation lists are in
EncodersDecoders,EscapersUnescapers, andDataGenerators. - Editor mutations should go through
EditorUtils.executeWriteCommand. - Error dialogs are shown via IntelliJ APIs and failures are logged.
Generic intentions live in modules/tools/editor/src/main/.../intention.
Java/Kotlin language-specific variants live in:
modules/java-dependent/.../PsiJavaUtils.ktmodules/java-dependent/.../tool/editor/actionmodules/java-dependent/.../tool/editor/intentionmodules/kotlin-dependent/.../PsiKotlinUtils.ktmodules/kotlin-dependent/.../tool/editor/actionmodules/kotlin-dependent/.../tool/editor/intention
Those modules are optional and must stay behind their optional plugin descriptors.
Common commands:
./gradlew test
./gradlew check
./gradlew verifyPlugin
./gradlew spotlessApplyCI runs:
./gradlew check --stacktrace
./gradlew verifyPlugin --stacktraceFocused examples:
./gradlew :tools-ui:test
./gradlew :settings:test
./gradlew test --tests '*PluginXmlTest'
./gradlew test --tests '*DeveloperToolsInstanceSettingsTest'Test infrastructure:
IdeaTestsets up IntelliJ test application/project fixtures and Bouncy Castle.PluginXmlTestvalidates descriptor class/file references.DeveloperUiToolsInstancesinstantiates all registered UI tools from the extension point for integration tests.DeveloperUiToolUnderTestrandomizes and resets registered tool properties.- Intention description tests validate bundled intention descriptions/templates.
Some tests need IntelliJ test infrastructure and can be slow. On Linux/CI, run under Xvfb as the workflow does.
- Kotlin formatting is ktfmt Google style through Spotless.
.editorconfiguses 2-space Kotlin indentation and 100 character max line length.- The code often uses section comments like
// -- Properties --; keep them when editing nearby code. - Prefer IntelliJ Platform APIs and the local helper classes over new abstractions.
- Use IntelliJ UI DSL builder patterns already present in neighboring tools.
- Register disposables with the passed
parentDisposable. - Keep long or blocking work off the EDT. Existing code uses pooled threads,
Task.Backgroundable,AsyncTaskExecutor, andAlarm. - Many UI components rely on
ValuePropertyor IntelliJ observable properties; bind controls rather than manually syncing when possible. - Do not change plugin ids, extension ids, or persisted property keys without migration/test updates.
The HTTP Server tool downloads and runs WireMock standalone:
- Implementation:
HttpServer.kt. - Process tracking:
ExternalSystemProcessRegistry.kt. - Download URL/version constants are at the bottom of
HttpServer.kt. - The tool supports built-in and custom server modes and registers/stops process handlers.
Be careful with lifecycle changes here: processes must be unregistered and stopped on disposal.
publishPlugindepends oncheckand requiresplatform == "idea".- Signing reads certificate/private key from
~/.jetbrainsand a Gradle property password. - Marketplace token is read from Gradle properties.
buildSearchableOptionsis disabled.- Plugin verification uses recommended IDEs plus additional IDEs from
pluginVerificationAdditionalIdes. - Changelog rendering comes from
CHANGELOG.md;tools-uialso generates a bundledchangelog.html.
Before editing:
- Run
git status --shortand do not overwrite unrelated user changes. - Use
rg/rg --filesfor navigation. - Read the closest existing implementation before adding a new pattern.
For UI tools:
- Start from the nearest tool in the same package.
- Wire configuration through
DeveloperToolConfiguration. - Register tool and enum property types in
plugin.xml. - Run at least
./gradlew :tools-ui:testor the smallest relevant module test, plusPluginXmlTestif descriptors changed.
For settings persistence:
- Check
DeveloperToolsInstanceSettings,DeveloperToolConfiguration, and legacy migration tests. - Add enum registrations and migration entries as needed.
- Run
DeveloperToolsInstanceSettingsTest.
For editor actions/intentions:
- Keep generic selected-text logic in
tools-editor. - Keep Java/Kotlin PSI logic in optional modules.
- Add/update intention descriptions under
resources/intentionDescriptions. - Run the relevant intention description tests.
Before final response:
- Run the narrowest meaningful Gradle tests.
- If descriptor or broad registration changed, run
PluginXmlTest. - If formatting changed, run
./gradlew spotlessApplyor./gradlew spotlessCheck. - Mention any tests that could not be run.