mcp-steroid
CLAUDE.md82 starsChanged 3 months agoApache-2.0View on GitHub
Guidance for Claude Code when working with this repository. Instructions here override default behavior. Three tenets govern every change in this repo — to code, MCP tools, or prompts. Read docs/PHILOSOPHY.md (mirrored as mcp-steroid://skill/design-philosophy for runtime fetch via steroid_fetch_resource) before proposing any of: Short version: the MCP tool surface (8 today) stays narrow on purpose; the IntelliJ capability surface stays full, exposed via steroid_execute_code plus prompt resources. The strategy page's "Give AI the whole IDE, not just the files" is…
- Commits and pushes
1 other project uses a version of this.
Adopted by
Most recently taken up by
- jonnyzzz/mcp-steroidword for word, first seen Aug 5, 2026
Other versions1 project uses a version of this.
Word for word · 1
- jonnyzzz/mcp-steroid★ 78100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository10 other files it gives its agents.
- prompts/AGENTS.mdAGENTS.md
- test-integration/AGENTS.mdAGENTS.md
- docs/CLAUDE.mdCLAUDE.md
- ij-plugin/CLAUDE.mdCLAUDE.md
- installer-gen/CLAUDE.mdCLAUDE.md
- test-experiments/CLAUDE.mdCLAUDE.md
- test-integration-agent-launch/CLAUDE.mdCLAUDE.md
- website/CLAUDE.mdCLAUDE.md
- website-gen/CLAUDE.mdCLAUDE.md
- promptSkill
The file
Show its rules and text
We split this CLAUDE.md into the rules it gives an agent
23 rules. About 0 are common, 9 are distinctive, and 14 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
14
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 26
Before acting on any task that touches files in a sub-folder, walk the directory tree from the changed file's folder up to the project root …
- Distinctive: line 46
When changing files across multiple sub-folders, read the guides for each.
- Very specific: line 63
Use IntelliJ MCP for everything where you can — see ij-plugin/CLAUDE.md for the API patterns.
- Distinctive: line 64
Never ignore warnings or errors — fix them properly.
- Very specific: line 65
No test-only branches (isUnitTestMode) — use correct IntelliJ actions (writeIntentReadAction, writeCommandAction).
- Distinctive: line 68
Prefer JSON libraries for JSON parsing/manipulation.
- Distinctive: line 71
Never include AI as co-author or mention AI in commit messages.
- Very specific: line 77
The
internalvisibility modifier: Prefer plain public (no modifier). - Very specific: line 85
Never COPY or chmod +x it inside Dockerfiles.
- Distinctive: line 94
Infrastructure workarounds in tests: When a test fails due to missing Docker socket, missing CLI, wrong JDK, or missing native library, fix …
- Very specific: line 110
Do not use UsefulTestCase.shouldRunTest() for this: it silently reports the test as passed-without-running, hiding that the coverage never …
- Very specific: line 145
Never assert contains("some/relative/path") against a message that embeds Path.toString() — build the expected fragment with …
- Very specific: line 151
Never assert a raw Path.toString() substring against output that re-encodes the value as JSON: Windows backslashes arrive JSON-escaped …
- Very specific: line 194
Prose-only prompt edits need only the contract test: When a change under prompts/src/main/prompts/ touches no
kotlin fence, run./gradlew … - Distinctive: line 247
Read requirements; ask if ambiguous.
- Distinctive: line 248
Add a failing test, then implement (test-first.
- Very specific: line 249
Run Gradle build/test via the IDE's MCP, not shell — see ij-plugin/CLAUDE.md for the run-config recipe.
- Very specific: line 251
Test with IntelliJ MCP. Validate full Docker scenarios via :test-integration:test / :test-experiments:test.
- Very specific: line 252
Use steroid_execute_code to verify warnings/errors are gone before declaring done.
- Very specific: line 253
Update TODO* and commit.
- Very specific: line 315
Never advance website while VERSION on main has no matching *published* GitHub release — gate the push with …
- Very specific: line 327
origin → jb: always via merge (the jb-merge procedure below).
- Distinctive: line 328
jb → origin: always via cherry-pick (individual commits, manual conflict resolution).
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md, AGENTS.md
Guidance for Claude Code when working with this repository. Instructions here override default behavior.
Design philosophy
Three tenets govern every change in this repo — to code, MCP tools, or
prompts. Read docs/PHILOSOPHY.md (mirrored as
mcp-steroid://skill/design-philosophy for runtime fetch via
steroid_fetch_resource) before proposing any of:
- a new
steroid_*MCP tool - a new method on
McpScriptContext - a "helper" that wraps an IntelliJ API
Short version: the MCP tool surface (8 today) stays narrow on
purpose; the IntelliJ capability surface stays full, exposed via
steroid_execute_code plus prompt resources. The strategy page's
"Give AI the whole IDE, not just the files" is delivered through that
combination — steroid_execute_code reaches every IDE API, and the
mcp-steroid:// prompt corpus teaches the agent how. New tools and new
context methods are not the lever.
Recursive context lookup (do this before sub-folder work)
Before acting on any task that touches files in a sub-folder, walk the directory tree from the changed
file's folder up to the project root and read every CLAUDE.md and AGENTS.md you find on the way
(including this one). Sub-folder guides take precedence over the root for their own scope; the root only
holds project-wide rules.
Recipe (run this in your head, or with a one-liner). Normalize the starting directory to an
absolute path first — relative paths converge on . and never match the repo root, infinite-looping:
# from any file path (relative or absolute), walk parents to repo root, collecting CLAUDE.md / AGENTS.md
file="<changed-file>"
dir=$(cd "$(dirname "$file")" && pwd)
root=$(git rev-parse --show-toplevel)
while [ "$dir" != "$root" ] && [ "$dir" != "/" ]; do
for f in CLAUDE.md AGENTS.md; do [ -f "$dir/$f" ] && echo "$dir/$f"; done
dir=$(dirname "$dir")
done
for f in CLAUDE.md AGENTS.md; do [ -f "$root/$f" ] && echo "$root/$f"; doneWhen changing files across multiple sub-folders, read the guides for each.
Sub-folder guides
| Folder | Guide | Scope |
ij-plugin/ | ij-plugin/CLAUDE.md | IntelliJ plugin code, services, threading, build, deployment, sandbox/index troubleshooting, registry keys |
prompts/ | prompts/AGENTS.md | Prompt file format, IDE conditionals, mcp-steroid:// resources, KtBlocks |
test-integration/ | test-integration/AGENTS.md | Stable Docker IDE smoke tests, shared infra, hung-test diagnosis, multi-version compat tests, playgrounds, Rider/.NET, Linux Docker CI gotchas |
test-experiments/ | test-experiments/CLAUDE.md | DPAIA arena suite, debugger demos, prompt-quality comparisons, IMPROVEMENTS.md harness |
docs/ | docs/CLAUDE.md | Autoresearch / prompt-optimization working notes, DPAIA history |
website/ | website/CLAUDE.md | Hugo site sources, GitHub Pages deployment |
installer-gen/ | installer-gen/CLAUDE.md | Build-tooling: computed JDK data model (Corretto/Azul, PGP-verified, pinned fingerprints), on-disk download cache, install.sh/install.ps1 generation |
website-gen/ | website-gen/CLAUDE.md | Build-tooling generator: version.json + updatePlugins.xml (depends on :installer-gen for shared HTTP) |
MUST DO
- Use IntelliJ MCP for everything where you can — see
ij-plugin/CLAUDE.mdfor the API patterns. - Never ignore warnings or errors — fix them properly.
- No test-only branches (
isUnitTestMode) — use correct IntelliJ actions (writeIntentReadAction,writeCommandAction). - Tests must show reality. Never remove, disable, or weaken a failing test; fix the underlying issue.
- No
@Suppress("DEPRECATION")— find the non-deprecated replacement. - Prefer JSON libraries for JSON parsing/manipulation; only static final JSON constants may be hand-written as raw strings.
- Log new ideas/tasks in
TODO*files (TODO.md,TODO-*.md). - Atomic commits with descriptive messages (what and why). Test and build before committing.
- Never include AI as co-author or mention AI in commit messages.
Banned patterns
runCatching{}.onFailure{}— usetry { } catch (e: Exception) { }instead. OtherrunCatchinguses (.getOrNull(),.getOrDefault()) are fine.- The
internalvisibility modifier. Prefer plain public (no modifier). Don't addinternalto declarations — including test-visible helpers. - Returning a
(value, errorFlag)pair/tuple from a call that can fail. Return the value (or a domain value object) and signal failure by throwing or returningnull— notPair<Result, Boolean>where the boolean is an error/isError flag. - Empty
catch/catch (_: Exception) {}. Fail fast and log: every catch must rethrow, log viaSystem.err.println/logger.error, or both. Silent failure hides root causes. run-agent.shreferences in production code or tests. It is a manual dev/peer-review tool only. NeverCOPYorchmod +xit inside Dockerfiles. Implement agent integrations directly via CLI flags.- Cross-subproject
build/directory access in Gradle build files. Use Gradle dependency configurations. Fail fast withrequire()/error()— no silent fallbacks. append("\n")tricks to bypass theNoLargeInlineStringsTestlint rule. When abuildString { }exceeds the consecutive-appendLinelimit, move the content toprompts/src/main/prompts/and reference it via the article URI.- Hardcoded
mcp-steroid://...URI literals in production Kotlin. Use the generated article class:XxxPromptArticle().uri(fromcom.jonnyzzz.mcpSteroid.prompts.generated.*). Enforced byNoHardcodedMcpSteroidUriUsageTest. SeeFetchResourceToolHandler.kt. - Infrastructure workarounds in tests. When a test fails due to missing Docker socket, missing CLI, wrong JDK, or missing native library, fix the infrastructure — never add detection-and-skip code.
- Detecting failures and skipping tests at runtime (
try { } catch { skip() },Assumptions.assumeTrue(isAvailable),TestAbortedExceptionon error). The only acceptable skip is at the Gradle task level (enabled = !condition) when an entire suite is structurally incompatible with the platform.- Single documented exception: Gemini API key on CI. TC has no Gemini token and there is no plan to
add one.
DockerGeminiSession.Companionopts intoskipTestWhenKeyMissing = true(seetest-helper/.../AISessionBase.kt), sorequireApiKey()throwsAssumptionViolatedExceptioninstead ofIllegalStateExceptionwhen the key is missing — JUnit 4/5 runners report that as ignored. JUnit 3 /BasePlatformTestCasetests (e.g.CliGeminiIntegrationTest) get no skip from that assumption under the plain bridge —JUnit38ClassRunner.addErrorfiresfireTestFailurefor everyThrowable, assumptions included (still true in JUnit 4.13.2) — so they must additionally run under@RunWith(JUnit38AssumeSupportRunner::class)(the IntelliJ test-framework runner that reroutesAssumptionViolatedExceptiontofireTestAssumptionFailed, i.e. a real SKIPPED/ignored result) and gaterunBareearly onskipTestBecauseApiKeyMissing()so the skip costs no fixture/Docker setup. Do not useUsefulTestCase.shouldRunTest()for this: it silently reports the test as passed-without-running, hiding that the coverage never executed. Constraints when working in this area:- Session creation must stay lazy — called from inside test method bodies, never from
setUp()/ class init /@ClassRule.BasePlatformTestCase-backed tests route everyThrowablethroughJUnit38ClassRunnertofireTestFailure, so an early init failure shows up against the wrong test. - Do NOT add
excludeTestsMatchingor other test-class-level filters — that hides the test from reports. - Unresolved
%credentialsJSON:…%must still fail hard withIllegalStateException— that branch indicates a real TC misconfiguration and must stay visible. The contract is unit-tested in:test-helper:testAIAgentCompanionApiKeyTest. - Do NOT extend the opt-in to other agents. Anthropic / OpenAI keys ARE configured on TC; their tests must keep failing if the key disappears.
- Session creation must stay lazy — called from inside test method bodies, never from
- Single documented exception: Gemini API key on CI. TC has no Gemini token and there is no plan to
add one.
- Java threading primitives (
CountDownLatch,Semaphore,Object.wait()) in coroutine code. UseCompletableDeferred<T>+withTimeout(d) { deferred.await() },Channel<T>, orsuspendCancellableCoroutine. ./gradlew testat the repo root. It fans out to every module and can take hours. Always scope:./gradlew :ij-plugin:test,./gradlew :kotlin-cli:test,./gradlew :prompts:test --tests '<pattern>'. See per-module guidance inij-plugin/CLAUDE.md.- Literal
/*inside KDoc bodies. Kotlin doc comments support nested/* */, so a string like"`7z/win-x64/*`"in a/** */block starts an inner comment; the next*/closes the INNER, leaving the outer open. The compiler reportsUnclosed commentat the end of the file plus a cascade of unresolved-reference errors. Rewrite as//line comments or quote the substring to avoid the/*sequence. - Windows-hostile test fixtures and assertions. Five recurring shapes, all found live on the TC
Windows agent (2026-08-05 #445 + the CliToolSupportTest CRLF round; 2026-08-07 the 0.102
release-week rounds, TC builds 629–630):
- Whole-string assertions on
PrintStreamoutput MUST normalize\r\n→\nin the capture helper (printlnuses the platform separator; the TC report renders expected/actual as visually identical).GeneratedToolRuntimeTestSupportis the reference implementation. File.setExecutable(false)is a silent no-op on NTFS andFiles.isExecutable()stays true for any readable file — a "non-executable file" precondition is unrepresentable there. Use an injectable probe with a production default (seeRemoteDevelopmentLauncherResolver'sisExecutableseam), never chmod-based fixtures.- Never assert
contains("some/relative/path")against a message that embedsPath.toString()— build the expected fragment withPath.of("some", "relative", "path").toString(). - A Unix-style fixture like
Path.of("/home/u")is NOT drive-absolute on Windows: any production path that goes throughtoAbsolutePath()/normalize()gains the current drive (Z:\home\u) and the equality fails. Use a temp-dir fixture (@TempDir,Files.createTempDirectory) — it is genuinely absolute on every OS (HomePathsTest,DevrigSetupTestare the references). - Never assert a raw
Path.toString()substring against output that re-encodes the value as JSON: Windows backslashes arrive JSON-escaped (Z:\\dir). Compare againstJsonPrimitive(value).toString()instead (ScreenshotAndOpenProjectCommandTest). Diagnosing a red Windows leg: without--continue, the first failing module's test task stops later modules — compare the leg's total test count against the Linux leg; a large shortfall means more Windows-hostile tests hide behind the reported ones (the 629→630 "onion": fixing 1 exposed 3). The NEW-failure surface is exactly the test files changed since the last green Windows run.
- Whole-string assertions on
- Snapshotting
/proc/<pid>/cmdline(ProcessHandle.info().arguments()) right after a spawn. On Linux a spawned child execs IN PLACE throughjspawnhelper → setsid → env → shbefore becoming the target binary; a one-shot read races that chain and sees"sh"or an empty Optional (brokemcp_steroid_DevrigTestdeterministically on cold TC agents). Poll withwithTimeout { while (...) delay(...) }until the expected command appears. Identity checks must use exec-stable properties (pid +startInstant), never the cmdline. - MCP stdio scripts writing to stdout. Any shell/PowerShell wrapper
invoked by an agent CLI as a stdio MCP server (
devrig mcp, etc.) must emit only stderr beforeexec-ing the inner binary. Stdout is the JSON-RPC channel — a single stray byte corrupts the protocol. Use>&2(POSIX) orWrite-Error/[Console]::Error.WriteLine(PowerShell). claude mcp addwithout--scope user. The Claude CLI defaults to--scope local, which writes toclaude.json.projects.<cwd>.mcpServersinstead of the top-level user-scopemcpServers. Registration is then invisible from any other project. All user-wide Claudemcp addcalls must pass--scope user. Codex and Gemini default to global/user-wide and do not need the flag.- Materializing files for Gradle's daemon classpath at CONFIG phase.
Anything that needs to be on the gradle daemon's classloader during config
phase (e.g., resources read by
:ij-plugin's IPGPlocal(provider)at task-graph time) must be pre-staged insettings.gradle.kts—buildSrcis chicken-and-egg (its tasks don't run until after settings + buildSrc itself), and main-project task outputs are too late. Seegradle/seven-zip-bootstrap.settings.gradle.ktsfor the canonical example (commit 0b7bbe78).
Test execution discipline
- NEVER run
:test-integrationor:test-experimentstests in parallel. Each test starts a full Docker IntelliJ container. Two concurrent runs exhaust RAM/CPU and OOM-kill both. Wait for completion before starting the next. Seetest-integration/AGENTS.mdfor the full Docker-test playbook. - Diagnose stuck/slow tests with JDK tooling BEFORE killing.
jps -l | grep GradleWorkerMain→jcmd <pid> Thread.print > /tmp/dump.txtwhile the JVM is alive; thengrep '<YourTest>Test' /tmp/dump.txt -A 5. Killing throws away evidence and forces guess-and-retry. Once you have the stuck test's name, iterate on just that test (--tests 'com.example.StuckTest'--rerun-tasks).
- Prose-only prompt edits need only the contract test. When a change under
prompts/src/main/prompts/**touches no```kotlinfence, run./gradlew :prompts:test --tests '*MarkdownArticleContract*'(seconds). The*KtBlock*compilation matrix recompiles every fence against every unpacked IDE (60–120 min) and is only needed when kotlin fences change — never run it casually (a workflow agent once hung 37 min on it for a prose edit). - 1-minute rule for integration tests. Any
:test-integration/:test-experimentscase that hasn't printed PASS/FAIL within ~60 s of> Task :*:testis suspicious — usually a modal dialog, indexing stall, or background task that won't finish. Capture the latest screenshot (ls -t test-integration/build/test-logs/test/run-*/screenshot/*.png | head -1) and an in-container thread dump (docker exec <id> jcmd <PID> Thread.print) before deciding. Full recipe and symptom→cause table intest-integration/AGENTS.md→ "Debugging a stuck/hung Docker test".
Project Overview
devrig is the product — the CLI you install and run. One command installs devrig with its own bundled
runtime (no manual setup); devrig install <agent> wires it into Claude Code, Codex, or Gemini. To reach
real IDE semantics, devrig talks to MCP Steroid, the IntelliJ Platform plugin that exposes a standalone
MCP server letting LLM agents drive the IDE via Kotlin code execution — installed in your JetBrains IDE as
well (JetBrains Marketplace).
- Public repo: https://github.com/jonnyzzz/mcp-steroid
- Docs: README.md, docs/guides/AGENT-STEROID-GUIDE.md
- Modules: see
settings.gradle.kts. Plugin code lives inij-plugin/; prompt resources inprompts/; Docker IDE smoke tests intest-integration/; experimental/long-running tests intest-experiments/.
devrig CLI contributor contract
docs/devrig-cli-contract.md is authoritative for command grammar, help,
human/JSON output, direct MCP-tool commands, and open_project --wait. Keep one Clikt parser and derive
tool commands from their schemas. Use canonical list_projects; projects and project are compatibility
aliases. Missing/invalid parameters must route to focused help with allowed values, and parse validation
must happen before backend, file/stdin, or --out side effects. Agent-facing changes require the unit,
stable Docker, and Claude/Codex experiment buckets named in that contract.
Technology Stack
Gradle 9.6.1 / Kotlin 2.3.20 / Java 25 toolchain / IntelliJ Platform 2026.1+ / Ktor 3.3.2 (CIO+SSE) / kotlinx.serialization
Bytecode targets Java 21 (class-file v65) while the toolchain stays JDK 25: Android Studio 2026.1
bundles JBR 21 (IDEA bundles JBR 25), so the plugin must load on both. Set via the root subprojects {}
convention (jvmTarget=21 + -Xjdk-release=21 + options.release=21); enforced by
verifyClassFileVersions on the plugin/devrig distributions; regression-gated by
AndroidStudioRuntimeCompatTest. See issue #157.
The Gradle Daemon is pinned to JDK 25 via gradle/gradle-daemon-jvm.properties
(matches IDEA 2026.1's bundled JBR — see docs/262-EAP-PLAN.md). The
foojay-resolver-convention plugin in settings.gradle.kts is the auto-download fallback if no JDK 25 is
present locally. To change the daemon JVM: edit gradle-daemon-jvm.properties directly (one-line
toolchainVersion=N).
Workflow
- Read requirements; ask if ambiguous.
- Add a failing test, then implement (test-first; integration tests preferred; never fake tests).
- Run Gradle build/test via the IDE's MCP, not shell — see
ij-plugin/CLAUDE.mdfor the run-config recipe. - Deploy:
./gradlew deployPlugin. - Test with IntelliJ MCP. Validate full Docker scenarios via
:test-integration:test/:test-experiments:test. - Use
steroid_execute_codeto verify warnings/errors are gone before declaring done. - Update
TODO*and commit.
CI
Root build.gradle.kts defines ci-prefixed aggregator tasks for TeamCity and GitHub Actions.
./gradlew tasks --group ci lists them.
| Task | Subprojects | Notes |
buildPluginOnCI | :ij-plugin (builds + publishes ZIP) | Entry point for both GH Actions and TC |
ciBuildPluginTests | All plugin modules except prompts + non-plugin | Per-OS matrix on TC; includes verifyPlugin + bundled-library gates |
ciBuildPromptsTests | prompt-generator, prompts, prompts-api | Linux only; full matrix takes 60–120+ min |
ciIntegrationTests | :test-helper:test → :installer-gen:installerIntegrationTest → :ij-plugin:integrationTest → :test-integration:test | Strict sequential ordering via mustRunAfter; needs Docker + API keys |
ciDevrigTests | :npx-kt:test → :npx-kt:integrationTest | devrig unit + stdio Docker suite; Linux TC config, plus a Windows unit-only TC leg (:npx-kt:test — the real-NTFS BinLauncherWindowsTest runs nowhere else) |
ciAgentLaunchTests | :test-integration-agent-launch (test + windowsPs1Test) | Cross-OS agent-launch behaviour; task-level OS gates (no-op on macOS) |
:test-integration:test and :test-experiments:test have an onlyIf guard — plain root ./gradlew test
silently skips both. Direct ./gradlew :test-integration:test --tests '...' still works. On TC,
:test-integration:test is split by the mcp.testIntegration.lane property (main = smoke matrix,
excludes playgrounds; compat = verifier/262-compat/Android-Studio legs on a fresh agent; unset = full
suite, the local behavior) — see test-integration/AGENTS.md → "CI lane split".
On TeamCity, public Maven hosts route through the JetBrains cache redirector. The TC Mac farm
(icri-big-agent-eqx-*) shares one NAT egress IP that Maven Central 429-rate-limits on cold resolution,
and Gradle disables a repository for the whole build on the first transport error — the failing lookup
was not even a repo dependency but buildSrc's kotlin-dsl → Gradle-distribution-pinned Kotlin, via the
implicit Plugin Portal. gradle/jetbrains-cache-redirector.settings.gradle.kts (+ pluginManagement
mirrors in both settings files) rewrites repo.maven.apache.org / repo1.maven.org /
plugins.gradle.org to cache-redirector.jetbrains.com/<host>/<path>, gated on TEAMCITY_VERSION
alone — GitHub Actions and local builds stay byte-identical. Only verified-mirrored hosts belong in
that list (packages.jetbrains.team is NOT mirrored and stays direct).
Vendor-feed tests are opt-in, so a Google/JetBrains/GitHub outage can never redden a normal build:
| Task | Covers | Cost |
:npx-kt:liveNetworkTest | every supported IDE resolves off its live feed with a plugin-compatible build (live-network tag) | ~1 min, no archive download |
:npx-kt:liveDownloadSmokeTest | idea-community + android-studio really download, unpack and pass product-info.json validation (live-download tag) | multi-GB per case |
:intellij-downloader:liveNetworkTest | products-API filename tokens still match (JUnit4 LiveNetwork category) | seconds |
The offline equivalent runs by default: AllIdeProductsDownloadTest walks every catalog product through
recorded payloads of all three feeds.
TeamCity DSL lives in a separate repo (~/Work/mcp-steroid-teamcity). See its own CLAUDE.md for the
generate→edit→regenerate→commit workflow, the build-configuration landscape (per-push VCS triggers on the
gate configs, the Sunday-03:00 WeeklyAllTests composite, the CompatTests lane) and the jb tc CLI
recipes for triggering/inspecting builds. The TC VCS root pulls from jb, not origin — see "Git remotes"
below. When a DSL change passes a NEW Gradle property to this repo, land the property on jb/main FIRST:
an unknown -P is silently ignored, so the config would quietly run the wrong scope.
GitHub Actions (.github/workflows/): builds the publishable plugin ZIP and deploys the website to
GitHub Pages. Plugin tests are intentionally NOT mirrored — full coverage stays on TC (3–5× faster
internal agents). Trigger PR builds via workflow_dispatch on the PR's head branch.
Website deploys from the website branch, NOT main. GitHub Pages builds on a push to the
long-lived website branch (github-pages.yml). website tracks main (advance via
git merge main → website, normally often) but can deliberately lag it so website changes that depend
on an unreleased devrig binary — e.g. a new install.sh/install.ps1 CLI contract — stay off the
live site until a matching GitHub release exists. The release process advances website AFTER
publishing the release (release/release-instructions.md → "Stage 7c"). Advancing website is the
devrig auto-update rollout trigger: the deploy regenerates version.json + the install scripts
atomically, and devrig sessions auto-install off version.json (docs/updates-check/devrig-auto-update.md).
Never advance website while VERSION on main has no matching published GitHub release — gate the
push with release/scripts/verify-release-ready.sh. website is origin-only
(never synced to jb, which runs TeamCity only). A push to main no longer deploys the website.
Git Remotes: origin vs jb
| Remote | URL | Role |
origin | git@github.com:jonnyzzz/mcp-steroid | Day-to-day development fork; source of truth for new commits |
jb | git@github.com:JetBrains/mcp-steroid.git | JetBrains-org mirror; consumed by TeamCity (mcp_steroid project) |
Sync direction:
- origin → jb: always via merge (the
jb-mergeprocedure below). - jb → origin: always via cherry-pick (individual commits, manual conflict resolution).
- Never fast-forward-push
maintojb—jb/maincarries org-specific commits that would be lost.
git fetch jb
git checkout -b jb-merge jb/main
git merge main --no-ff -m "Merge remote-tracking branch 'origin/main' into jb-merge"
git push jb jb-merge:main
git checkout main && git branch -D jb-merge--no-ff preserves jb/main's existing head as the merge's first parent so jb-only history stays
reachable. Why this matters for CI: TC pulls from jb. If your commit isn't on jb/main, TC builds
stale code.
Push origin BEFORE jb-merging. Concurrent sessions push to origin/main constantly; a rejected
git push origin main after the jb push already landed leaves jb ahead of the source of truth
(hit twice on 2026-08-05). Recovery when it happens anyway: git pull --rebase origin main →
git push origin main — the same change now exists under two SHAs (one on each remote), which is
fine: the next jb-merge unifies identical content without conflict. Never cherry-pick it back.
No GitHub Actions on jb. The JetBrains-org mirror runs TeamCity only — it must carry no
.github/workflows/ at all (those are origin/jonnyzzz-only: the GitHub Pages website deploy, PR compile
gate, etc.). jb/main intentionally deletes every workflow file (e.g. commit "Delete
.github/workflows/github-pages.yml"); that deletion is org-specific history to preserve. So during
jb-merge, a modify/delete conflict on any .github/workflows/* file is expected whenever origin
edits a workflow — always resolve by keeping it deleted on jb (git rm .github/workflows/<file>
then commit the merge). Never resurrect a workflow onto jb.
IntelliJ Source Research
The IntelliJ project at ~/Work/intellij is open in the IDE for research. Use steroid_execute_code with
project_name="intellij" and PSI APIs (FilenameIndex, JavaPsiFacade) — faster and more accurate than
grep. See test-integration/AGENTS.md → "Researching IntelliJ APIs" for the recipe.
run-agent.sh from ~/Work/jonnyzzz-x/ launches AI agents (Claude/Codex/Gemini) for peer reviews,
research, and consensus checks. Encouraged from agent sessions — the BANNED rule applies only to
production code/tests referencing it. Usage: run-agent.sh <agent> <cwd> <prompt-file>; the default
hard timeout is 900 s — deep reviews need RUN_AGENT_TIMEOUT_SECONDS=2700 (the env var is
RUN_AGENT_-prefixed; a bare TIMEOUT_SECONDS is silently ignored).
Environment Constraints
timeout / gtimeout are not available on this Mac. Use Gradle's own timeout mechanisms or the Bash
tool's timeout parameter.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

