feat(adapter): add JetBrains Copilot adapter#327
feat(adapter): add JetBrains Copilot adapter#327murataslan1 wants to merge 4 commits intomksglu:nextfrom
Conversation
df55be1 to
d60b073
Compare
There was a problem hiding this comment.
Pull request overview
Adds a new JetBrains Copilot platform adapter to the adapters layer, enabling platform detection/config/doctor/upgrade flows for running context-mode hooks from JetBrains IDEs.
Changes:
- Adds
jetbrains-copilotadapter implementation (hooks/config/index) and registers the platform ID. - Extends platform detection and MCP client-name mapping to recognize JetBrains IDEs.
- Adds JetBrains-specific setup documentation and an example
.idea/mcp.jsonconfig.
Reviewed changes
Copilot reviewed 8 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/adapters/types.ts | Adds jetbrains-copilot to the PlatformId union. |
| src/adapters/jetbrains-copilot/index.ts | Implements the JetBrains HookAdapter (parse/format/config/doctor/upgrade). |
| src/adapters/jetbrains-copilot/hooks.ts | Defines JetBrains hook types + command builder for hook invocation. |
| src/adapters/jetbrains-copilot/config.ts | Re-exports adapter + hook constants for compatibility. |
| src/adapters/detect.ts | Adds JetBrains env-var and config-dir based platform detection + adapter loader branch. |
| src/adapters/client-map.ts | Maps JetBrains MCP clientInfo.name values to jetbrains-copilot. |
| docs/jetbrains-copilot.md | Adds JetBrains setup guide. |
| configs/jetbrains-copilot/mcp.json | Provides example MCP server configuration for JetBrains projects. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "Visual-Studio-Code": "vscode-copilot", | ||
| "JetBrains Client": "jetbrains-copilot", | ||
| "IntelliJ IDEA": "jetbrains-copilot", | ||
| "PyCharm": "jetbrains-copilot", |
There was a problem hiding this comment.
New clientInfo.name mappings were added for JetBrains, but tests/adapters/client-map.test.ts currently only asserts a subset of mappings. Please add test cases for the new JetBrains keys (e.g., "JetBrains Client", "IntelliJ IDEA", "PyCharm") to prevent regressions in zero-config detection.
| export function buildHookCommand(hookType: HookType, pluginRoot?: string): string { | ||
| const scriptName = HOOK_SCRIPTS[hookType]; | ||
| if (!scriptName) { | ||
| throw new Error(`No script defined for hook type: ${hookType}`); | ||
| } | ||
| if (pluginRoot) { | ||
| return `node "${pluginRoot}/hooks/jetbrains-copilot/${scriptName}"`; | ||
| } | ||
| return `context-mode hook jetbrains-copilot ${hookType.toLowerCase()}`; | ||
| } |
There was a problem hiding this comment.
buildHookCommand generates (a) pluginRoot-based commands referencing ${pluginRoot}/hooks/jetbrains-copilot/<script>.mjs and (b) a CLI dispatcher command context-mode hook jetbrains-copilot .... Currently the repo has no hooks/jetbrains-copilot/ wrappers, and the CLI hook dispatcher (src/cli.ts HOOK_MAP) does not register jetbrains-copilot, so either command form will fail at runtime. To make this adapter usable, add JetBrains hook wrapper scripts (similar to hooks/vscode-copilot/*), register them in the CLI hook map, and ensure hook response formatting/tool naming is wired for jetbrains-copilot (e.g., hooks/core/formatters + hooks/core/tool-naming).
| ## 3) Verify | ||
|
|
||
| - Restart the IDE after creating `.idea/mcp.json`. | ||
| - Run `context-mode doctor` in the project directory. | ||
| - Confirm MCP registration reports `context-mode found in .idea/mcp.json`. |
There was a problem hiding this comment.
The setup guide only configures the MCP server, but context-mode doctor for this adapter also validates that .idea/mcp.json contains hooks.PreToolUse and hooks.SessionStart entries. As written, following this doc will likely produce failing hook diagnostics. Add a step to run context-mode upgrade (or document the required hooks JSON entries) so the guide results in a passing doctor output.
| ## 3) Verify | |
| - Restart the IDE after creating `.idea/mcp.json`. | |
| - Run `context-mode doctor` in the project directory. | |
| - Confirm MCP registration reports `context-mode found in .idea/mcp.json`. | |
| ## 3) Upgrade the project config | |
| Run `context-mode upgrade` in the project directory to add any required entries, including the `hooks.PreToolUse` and `hooks.SessionStart` configuration that `context-mode doctor` validates for this adapter. | |
| ## 4) Verify | |
| - Restart the IDE after creating or upgrading `.idea/mcp.json`. | |
| - Run `context-mode doctor` in the project directory. | |
| - Confirm doctor reports `context-mode found in .idea/mcp.json` and that the hook diagnostics pass. |
| if ( | ||
| process.env.IDEA_INITIAL_DIRECTORY | ||
| || process.env.IDEA_HOME | ||
| || process.env.JETBRAINS_CLIENT_ID | ||
| ) { | ||
| return { | ||
| platform: "jetbrains-copilot", | ||
| confidence: "high", | ||
| reason: "IDEA_INITIAL_DIRECTORY, IDEA_HOME, or JETBRAINS_CLIENT_ID env var set", | ||
| }; | ||
| } |
There was a problem hiding this comment.
Platform detection logic was extended for JetBrains, but the repository has thorough adapter detection tests (tests/adapters/detect.test.ts). Add/extend tests to cover IDEA_INITIAL_DIRECTORY / IDEA_HOME / JETBRAINS_CLIENT_ID env var detection and the ~/.config/JetBrains fallback so this behavior is exercised in CI.
|
Let's resolve conflicts, add Unit Tests, update Readme and the other docs. Did you test that also? Is that support that fully hooks? Is that same with exist Copilot? |
Implements JetBrains Copilot adapter with detection via IDEA_INITIAL_DIRECTORY, IDEA_HOME, JETBRAINS_CLIENT_ID env vars and ~/.config/JetBrains/ config dir. Config stored in .idea/mcp.json; session storage in ~/.config/JetBrains/context-mode/sessions/. Registers IntelliJ IDEA, PyCharm, and JetBrains Client in the client map.
Addresses review feedback on mksglu#327: the adapter declared four hook scripts but the files did not exist, and there were no unit tests or hook integration tests. The adapter also was not registered in the shared core's formatter/tool-namer, so hook output was empty. Hooks (new): - hooks/jetbrains-copilot/{pretooluse,posttooluse,precompact,sessionstart}.mjs thin wrappers over hooks/core/* mirroring the VS Code Copilot layout; cwd sourced from IDEA_INITIAL_DIRECTORY, rule file from .idea/copilot-instructions.md with .github/copilot-instructions.md fallback for shared repos. - JETBRAINS_OPTS added to hooks/session-helpers.mjs (configDir .config/JetBrains, projectDirEnv IDEA_INITIAL_DIRECTORY, sessionIdEnv JETBRAINS_CLIENT_ID). - jetbrains-copilot registered in hooks/core/formatters.mjs and hooks/core/tool-naming.mjs (sharing VS Code Copilot's json-stdio response shape and context-mode_<tool> naming convention). Adapter parity: - readSettings() falls back to .claude/settings.json for projects migrating from Claude Code (matches VS Code Copilot). - getInstalledVersion() reports "configured" when .idea/mcp.json has a context-mode entry, otherwise "unknown". Tests (new): - tests/adapters/jetbrains-copilot.test.ts — 37 cases covering capabilities, env-var fallback chain, config paths, response shapes. - tests/hooks/jetbrains-hooks.test.ts — 19 cases exercising all four hooks plus an E2E PostToolUse → PreCompact → SessionStart(compact) roundtrip. - tests/adapters/detect.test.ts — adds IDEA_INITIAL_DIRECTORY, IDEA_HOME, JETBRAINS_CLIENT_ID detection cases and the getAdapter loader. - tests/adapters/client-map.test.ts — adds "JetBrains Client", "IntelliJ IDEA", "PyCharm" → jetbrains-copilot mappings. - tests/hooks/tool-naming.test.ts — bumps KNOWN_PLATFORMS.length to 13. Docs: - docs/jetbrains-copilot.md expanded from 35 to 142 lines: prerequisites, install, .idea/mcp.json example, hook registration (the step the initial PR omitted), env-var table, session persistence, doctor walkthrough, troubleshooting, and a VS Code vs JetBrains differences table. - README.md gains a collapsible JetBrains Copilot setup block after the VS Code one. - docs/platform-support.md adds JetBrains to the paradigm overview and gets a full platform section matching the existing per-platform layout. - CONTRIBUTING.md lists the new adapter directory and the two new test files in the test-organization table. Verification: 1666 / 1681 tests passing. The sole failure is tests/executor.test.ts's Rust case, which requires a rustup default toolchain not configured locally (pre-existing, unrelated).
d60b073 to
b99d95d
Compare
context-mode upgrade run from the IDE terminal was mis-detecting as Claude Code because JetBrains does not export IDEA_INITIAL_DIRECTORY / IDEA_HOME / JETBRAINS_CLIENT_ID to the terminal subprocess — those only appear inside the Copilot plugin host. If the shell had CLAUDE_PROJECT_DIR set from a profile, the env-var loop matched claude-code first and the generated .idea/mcp.json was wrong for the platform. JetBrains IDEs *do* reliably export TERMINAL_EMULATOR=JetBrains-JediTerm to the built-in terminal. Use that signal, gated on the absence of active runtime signals from other tools (CLAUDE_SESSION_ID, CURSOR_SESSION_ID, CURSOR_TRACE_ID, OPENCODE_PID, CODEX_THREAD_ID) so a Claude Code / Cursor / OpenCode session running inside the terminal still wins. Also export DETECTION_ENV_VARS — a single source of truth listing every env var that can influence detectPlatform() — so tests have one list to scrub. detect-config-dir.test.ts was relying on its own copy of PLATFORM_ENV_VARS and therefore did not clear IDEA_*/JETBRAINS_/ TERMINAL_EMULATOR vars; now imports DETECTION_ENV_VARS instead. Tests: 5 new cases in detect.test.ts covering the TERMINAL_EMULATOR signal and its gates. Full suite: 1574 / 0 failures. Docs: docs/jetbrains-copilot.md gains a TERMINAL_EMULATOR row in the env table plus a troubleshooting note explaining the detection path and the CONTEXT_MODE_PLATFORM override. Reported in the JetBrains POC walkthrough for issue mksglu#321.
…de.json The original PR put hook config in .idea/mcp.json's hooks block, which the JetBrains Copilot plugin does not read. Static analysis of the shipped Copilot agent (com.github.copilot v1.8.0-243, shared runtime with VS Code Copilot) shows loadEventsForWorkspace() unconditionally scans .github/hooks/*.json for hook definitions. So the JetBrains and VS Code hook paths are byte-for-byte identical — .idea/mcp.json was never a live config surface for hooks. MCP server registration is separate and lives in the IDE Settings UI (Settings > Tools > GitHub Copilot > MCP). That path is plugin-internal and not CLI-inspectable. Adapter changes (src/adapters/jetbrains-copilot/index.ts): - getSettingsPath(): .idea/mcp.json → .github/hooks/context-mode.json - writeSettings(): mkdirSync target flipped to .github/hooks - readSettings(): updated comment; .claude/settings.json fallback preserved - validateHooks(): diagnostic messages reference the correct path - checkPluginRegistration(): rewritten to emit a WARN noting the config is Settings-UI-managed and cannot be verified from CLI - getInstalledVersion(): reports "configured" when hooks block is present in .github/hooks/context-mode.json, else "unknown" Test fix (tests/adapters/jetbrains-copilot.test.ts): - getSettingsPath expectation updated to .github/hooks/context-mode.json Docs rewritten to match reality: - docs/jetbrains-copilot.md (115 → 195 lines): splits MCP registration (Settings UI) from hook registration (.github/hooks/context-mode.json), adds "How it works" explainer of the shared Copilot agent, documents v1.5.57+ plugin version requirement for MCP, adds verification steps that match the new doctor output. - README.md JetBrains block: MCP step moved to IDE Settings UI; hook example points at .github/hooks/context-mode.json. - docs/platform-support.md: configuration section split into two files with different owners. - configs/jetbrains-copilot/hooks.json (NEW): checked-in reference hook config, mirrors configs/vscode-copilot/hooks.json with jetbrains-copilot command label. Full suite: 1574 passing / 0 failing / 1 skipped (--fileParallelism=false to avoid the unrelated SQLite-under-high-concurrency flake). Refs issue mksglu#321, PR mksglu#327.
Full HookAdapter implementation for JetBrains IDEs (IntelliJ IDEA, PyCharm, WebStorm, GoLand, etc.) with GitHub Copilot plugin. Shares the same Copilot agent runtime as VS Code Copilot — same hook events (PreToolUse, PostToolUse, PreCompact, SessionStart), same hookSpecificOutput wrapper format, same .github/hooks/ config location. Key differences from VS Code Copilot: - Session storage: ~/.config/JetBrains/context-mode/sessions/ - MCP config: via Settings UI (not .vscode/mcp.json) - Detection: IDEA_INITIAL_DIRECTORY, IDEA_HOME, JETBRAINS_CLIENT_ID - Client map: JetBrains Client, IntelliJ IDEA, PyCharm All 4 blockers from PR #327 review fixed: 1. CLI HOOK_MAP registered (setup/upgrade/doctor work) 2. Hook scripts use parseStdin (not JSON.parse) 3. JETBRAINS_OPTS has configDirEnv field 4. No bundle files committed 26 files changed: 3 adapter source, 4 hook scripts, 6 test files, 4 docs, 2 configs, CLI + formatters + tool-naming + session-helpers. 1794 tests pass, typecheck clean. Closes #321 Co-Authored-By: Murat Aslan <murataslan1@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Landed on
|
Closes #321
Summary
src/adapters/jetbrains-copilot/withhooks.ts,index.ts,config.ts— mirrors thevscode-copilotadapter patternIDEA_INITIAL_DIRECTORY,IDEA_HOME,JETBRAINS_CLIENT_IDenv vars and~/.config/JetBrains/config dir.idea/mcp.json; session storage in~/.config/JetBrains/context-mode/sessions/IntelliJ IDEA,PyCharm, andJetBrains Clientin the client mapconfigs/jetbrains-copilot/mcp.jsonexample config usingnpx -y context-modedocs/jetbrains-copilot.mdsetup guideSession Report
Full implementation notes: https://gist.github.com/murataslan1/048277ac524e7e042a10dd2aca8ebdb1
Test plan
npm run buildexits 0 with no TypeScript errorscontext-mode doctorin a JetBrains project reports adapter detected.idea/mcp.jsonwithnpx -y context-moderegisters the MCP server correctlyhooks/jetbrains-copilot/*.mjs