The standing decisions that govern how this plugin is built. CLAUDE.md holds the absolute
prohibitions; this holds everything else, and it is read before starting work.
What belongs here: a directive that is in force, with the mechanism behind it, written as what is true now. What does not: how it came to be decided, incidents, dates of what happened.
Claude drives the IDE, and works through the IDE rather than through its own tools. Anything asked for in the IDE is done in the IDE, proactively, so the developer's environment stays current.
We only talk to the IDE. No wrapping gh, glab, docker, kubectl, aws, terraform, ssh
or the ijhttp CLI. If the IDE already does it, we ask the IDE; if the IDE does not, we do not do it.
The Services tool window is the centre of the DevOps story, not a collection of command-line wrappers.
No localisation. Nothing ships as text the maintainer cannot review, least of all a security notice.
The code and its libraries stay current. No technical debt is carried, and no code is kept as dead weight to serve people avoiding a paid licence: IntelliJ IDEA Community and PyCharm Community exist for that, and the plugin serves them.
- When something is deprecated, it is migrated then. If the replacement needs a newer build,
sinceBuildgoes up and the older one stops being supported. - Both forms are never written. No branch per version, no old function kept "just in case". What stops being used is deleted in the same commit.
- The only thing that degrades is a missing plugin (Docker,
com.intellij.database,com.jetbrains.restClient), never a missing platform version. - No deprecated and no internal APIs. The only tolerable warning is
@ApiStatus.Experimental.@ApiStatus.Internalis not: it does not even promise to stabilise. The forbidden symbols, each with its replacement, are indocs/PLATFORM_API_POLICY.md.
What gets added has to do more while spending less. It is an acceptance criterion, not an aspiration: a feature that raises the cost does not ship, however good it is.
The recurring saving is in the shape of the answer, not only in the size of the catalogue. Every
tool returns the smallest answer that settles the question, never a dump; anything that can enumerate
carries a hard limit; the IDE resolves instead of forwarding raw material for the model to resolve;
and no result requires a second call to be useful.
The order of work and what is done lives in docs/MCP_ROADMAP.md.
- Our own servers over stdio on Unix sockets. No ports.
- Four servers by domain:
code,run,vcs,ops. JSON-RPC, no broker. - Nothing loads up front: three meta-tools per server, and at most four tools per domain. A domain that does not fit in four is badly split and gets divided.
- TOON for everything we author. Only what is not ours stays JSON: the JSON-RPC envelope and
inputSchema. - The guard is evaluated inside the MCP server, at the dispatcher, because opening the sockets takes the Claude Code binary out of the path.
- Agent-agnostic: any MCP client can connect.
- Nothing blocks waiting: a queue per server, immediate acknowledgement, out-of-order replies
correlated by
id, a timeout and cancellation on every tool, and a bounded queue depth. - Coroutines only in the new MCP code (
model/mcp/,controller/mcp/). The rest of the plugin keepsAppExecutorUtil,ReadAction.compute,WriteCommandActionand the singleedt {}.
The token is generated by the code; nobody types or configures it. Every stdio service demands
it, without exception: there is no exempt server and no auth-free mode for development. It is handed
over at each server's init, which keeps it in memory only. The plugin's client picks it up. It is
regenerated on every start and rotated every 30 minutes, with a short overlap window so in-flight
requests are not killed.
It reaches the helper on the first line of stdin, never through an environment variable:
/proc/<pid>/environ is readable by any process running as the same user.
- No comments. The reasoning goes into a name, a test, or the commit message. See
CLAUDE.md. - A 250-line ceiling per file, in Kotlin, TypeScript and CSS alike.
- No Swing in the UI: everything visible is JCEF.
- Each external dependency is named in a single gateway file (
GitGateway,TerminalLauncher,DbGateway), with the availability check as its first line. - Adding a tool is adding a row to a table, never editing a central
when. - Tests are not moulded to the code. A red gate is fixed in the code; changing the metric or the threshold is what is forbidden.
- No home-made cryptography. Vetted primitives only.
- One commit per logical unit, Conventional Commits, with the why in the body when the diff does
not already say it. Never
git add -Ablind. - Release tags are cut by the workflow, never by hand.
- Pushing, tagging and opening pull requests are the maintainer's call.
package-lock.jsonis never staged by an agent.- Never
cdin a command; absolute paths. - The repository's documents are updated in the same turn as the change, without asking.