Skip to content

feat(adapter): add JetBrains Copilot adapter#327

Closed
murataslan1 wants to merge 4 commits intomksglu:nextfrom
murataslan1:feat/jetbrains-copilot-adapter
Closed

feat(adapter): add JetBrains Copilot adapter#327
murataslan1 wants to merge 4 commits intomksglu:nextfrom
murataslan1:feat/jetbrains-copilot-adapter

Conversation

@murataslan1
Copy link
Copy Markdown
Contributor

@murataslan1 murataslan1 commented Apr 22, 2026

Closes #321

Summary

  • Adds src/adapters/jetbrains-copilot/ with hooks.ts, index.ts, config.ts — mirrors the vscode-copilot adapter pattern
  • Detects JetBrains 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
  • Adds configs/jetbrains-copilot/mcp.json example config using npx -y context-mode
  • Adds docs/jetbrains-copilot.md setup guide

Session Report

Full implementation notes: https://gist.github.com/murataslan1/048277ac524e7e042a10dd2aca8ebdb1

Test plan

  • npm run build exits 0 with no TypeScript errors
  • context-mode doctor in a JetBrains project reports adapter detected
  • .idea/mcp.json with npx -y context-mode registers the MCP server correctly
  • Hook scripts resolve to hooks/jetbrains-copilot/*.mjs

Copilot AI review requested due to automatic review settings April 22, 2026 19:16
@murataslan1 murataslan1 force-pushed the feat/jetbrains-copilot-adapter branch from df55be1 to d60b073 Compare April 22, 2026 19:17
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-copilot adapter 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.json config.

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.

Comment on lines 17 to +20
"Visual-Studio-Code": "vscode-copilot",
"JetBrains Client": "jetbrains-copilot",
"IntelliJ IDEA": "jetbrains-copilot",
"PyCharm": "jetbrains-copilot",
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment on lines +72 to +81
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()}`;
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
Comment thread docs/jetbrains-copilot.md Outdated
Comment on lines +29 to +33
## 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`.
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
## 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.

Copilot uses AI. Check for mistakes.
Comment thread src/adapters/detect.ts
Comment on lines +129 to +139
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",
};
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
@mksglu mksglu changed the base branch from main to next April 22, 2026 19:36
@mksglu
Copy link
Copy Markdown
Owner

mksglu commented Apr 22, 2026

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).
@murataslan1 murataslan1 force-pushed the feat/jetbrains-copilot-adapter branch from d60b073 to b99d95d Compare April 23, 2026 09:07
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.
mksglu added a commit that referenced this pull request Apr 25, 2026
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>
@mksglu
Copy link
Copy Markdown
Owner

mksglu commented Apr 25, 2026

Landed on next — cherry-picked with all fixes ✅

Thank you @murataslan1 for the comprehensive JetBrains Copilot adapter work! We cherry-picked your contribution onto next with all 4 review issues resolved:

What landed (26 files, 1,809 additions)

Adapter source (3 files):

  • src/adapters/jetbrains-copilot/index.ts — Full HookAdapter with JetBrains-specific session storage, MCP detection, and rule file paths
  • src/adapters/jetbrains-copilot/hooks.ts — Hook types, matchers, scripts
  • src/adapters/jetbrains-copilot/config.ts — Re-exports

Hook scripts (4 files) — all use parseStdin ✅:

  • hooks/jetbrains-copilot/pretooluse.mjs, posttooluse.mjs, precompact.mjs, sessionstart.mjs

Infrastructure:

  • src/cli.ts — HOOK_MAP registered ✅ (setup/upgrade/doctor work)
  • hooks/session-helpers.mjsJETBRAINS_OPTS with configDirEnv
  • hooks/core/formatters.mjs + tool-naming.mjs — JetBrains support added

Tests (43 new tests):

  • tests/adapters/jetbrains-copilot.test.ts — 22 adapter tests
  • tests/hooks/jetbrains-hooks.test.ts — 21 hook integration tests
  • Updated: detect.test.ts, client-map.test.ts, tool-naming.test.ts

Docs:

  • docs/jetbrains-copilot.md — Full setup guide
  • docs/platform-support.md — Updated matrix
  • README.md + CONTRIBUTING.md — Updated

Issues fixed from review

  1. CLI HOOK_MAP missing → registered
  2. JSON.parse(raw) instead of parseStdin → all hooks use parseStdin
  3. JETBRAINS_OPTS missing configDirEnv → added
  4. Bundle files in diff → not committed

1,794 tests pass, typecheck clean. Thank you for the contribution! 🙏

Commit: 496b84a

@mksglu mksglu closed this Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: add instructions for using context-mode with Jetbrains Copilot plugin

3 participants