Fix --target intellij validation (#1957)#2041
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes apm install --target intellij being rejected at the parser/validation layer by adding intellij to the set of accepted --target tokens, while keeping it excluded from plain "all" expansion (as an MCP-only pseudo-target). It also adds unit tests to prevent regressions.
Changes:
- Introduce
MCP_ONLY_TARGETS = {"intellij"}and include it inVALID_TARGET_VALUES. - Allow
"all,intellij"inparse_target_field()by exempting MCP-only targets from the"all" cannot be combinedrestriction. - Add unit tests covering
intellijacceptance (single, multi-target, andall,intellij).
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/apm_cli/core/target_detection.py |
Adds MCP_ONLY_TARGETS and updates target validation + "all" combination logic to accept intellij. |
tests/unit/core/test_target_detection.py |
Adds regression tests ensuring intellij is accepted by the --target parsing/validation flow. |
APM Review Panel:
|
| Persona | B | R | N | Takeaway |
|---|---|---|---|---|
| Python Architect | 0 | 1 | 2 | MCP_ONLY_TARGETS is the right abstraction and correctly wired; one recommended follow-up on the target:/targets: YAML validator asymmetry; two nits on stale comment and undocumented invariant. |
| CLI Logging Expert | 0 | 1 | 1 | Help text omits intellij from Values: list; provenance silently shows copilot when --target intellij is used. No console helper regressions. |
| DevX UX Expert | 0 | 1 | 2 | Fix is functionally correct but --target help text still omits intellij, leaving the primary discovery path broken for the feature this PR ships. |
| Supply Chain Security Expert | 0 | 1 | 1 | No security bypass introduced; policy gate uses raw 'intellij' string instead of canonical 'copilot', causing fail-closed false positives under allow/enforce policies. |
| OSS Growth Hacker | 0 | 1 | 1 | Unblocks documented JetBrains target for ~25M JetBrains users; CHANGELOG entry missing, README hero still silent on IntelliJ. |
| Doc Writer | 0 | 2 | 1 | CHANGELOG [Unreleased] has no entry for #1957; ide-tool-integration.md still directs users to legacy --runtime intellij; targets-matrix omits intellij entirely. |
| Test Coverage Expert | 0 | 2 | 1 | Parser-layer unit tests are solid; two gaps: missing ALL_CANONICAL_TARGETS exclusion lock for intellij and no integration test for apm install --target intellij. |
B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.
Top 5 follow-ups
- [Supply Chain Security Expert] Apply RUNTIME_TO_CANONICAL_TARGET alias normalization in policy_target_check.py before passing to _check_compilation_target -- Orgs with allow: [copilot] policies see --target intellij falsely rejected today. Fail-closed is safe, but it breaks valid enterprise workflows for exactly the customer segment this EPAM contribution signals, and leaves the policy layer semantically inconsistent with the parser layer.
- [CLI Logging Expert] Add intellij to the --target flag Values: help text in install.py with a note that it is MCP-only (devx-ux-expert convergent) -- The primary discovery path for the feature this PR ships is currently broken: --help does not mention intellij, causing users to conclude the flag is invalid and fall back to --runtime intellij. The fix is two sentences of help text and closes the entire discovery gap.
- [Doc Writer] Add CHANGELOG [Unreleased] ### Fixed entry for --target intellij and update ide-tool-integration.md JetBrains example from --runtime to --target (oss-growth-hacker convergent) -- Consumers relying on CHANGELOG to track when issue [BUG] MCP server integration lacks IntelliJ as target #1957 is resolved will have no signal at release; the guide actively teaches the legacy flag for the one target this PR fixes.
- [Test Coverage Expert] Add test_intellij_not_in_all_canonical_targets and test_all_expansion_excludes_intellij to test_target_detection.py (evidence: missing, governed-by-policy) -- The PR asserts intellij is excluded from --target all expansion but no automated guard enforces this invariant; a future contributor can silently break the promise.
- [Test Coverage Expert] Create tests/integration/test_intellij_target.py mirroring test_hermes_target.py to exercise the full apm install --target intellij CLI-to-MCP-adapter path (evidence: missing, integration-with-fixtures tier required) -- Hermes and openclaw have integration tests; intellij has zero. Without it the fix can silently regress across refactors.
Architecture
classDiagram
direction LR
class TargetParamType {
<<ClickParamType>>
+convert(value, param, ctx) str or list
}
class parse_target_field {
<<PureFunction>>
+value str or list or None
+source_path Path or None
}
class VALID_TARGET_VALUES {
<<Frozenset>>
union gate for all CLI tokens
}
class ALL_CANONICAL_TARGETS {
<<Frozenset>>
vscode claude cursor opencode codex gemini windsurf kiro
}
class MCP_ONLY_TARGETS {
<<Frozenset>>
intellij
}
class EXPLICIT_ONLY_TARGETS {
<<Frozenset>>
agent-skills antigravity
}
class EXPERIMENTAL_TARGETS {
<<Frozenset>>
copilot-cowork hermes openclaw
}
class RUNTIME_TO_CANONICAL_TARGET {
<<Dict>>
intellij maps to copilot
}
class IntelliJClientAdapter {
<<MCPAdapter>>
+target_name intellij
+install_mcp_config()
}
class parse_targets_field {
<<PureFunction>>
apm_yml.py plural targets validator
}
class CANONICAL_TARGETS {
<<Frozenset>>
apm_yml.py no intellij entry
}
TargetParamType ..> parse_target_field : delegates
parse_target_field ..> VALID_TARGET_VALUES : validates each token
VALID_TARGET_VALUES ..> ALL_CANONICAL_TARGETS : union
VALID_TARGET_VALUES ..> MCP_ONLY_TARGETS : union
VALID_TARGET_VALUES ..> EXPLICIT_ONLY_TARGETS : union
VALID_TARGET_VALUES ..> EXPERIMENTAL_TARGETS : union
parse_target_field ..> EXPLICIT_ONLY_TARGETS : all-gate subtract
parse_target_field ..> MCP_ONLY_TARGETS : all-gate subtract
IntelliJClientAdapter ..> RUNTIME_TO_CANONICAL_TARGET : intellij maps to copilot
parse_targets_field ..> CANONICAL_TARGETS : validates against
class MCP_ONLY_TARGETS:::touched
class parse_target_field:::touched
class VALID_TARGET_VALUES:::touched
classDef touched fill:#fff3b0,stroke:#d47600
flowchart TD
CLI["CLI: apm install --target intellij"] --> TPC["TargetParamType.convert\ntarget_detection.py"]
TPC --> PTF["parse_target_field\ntarget_detection.py"]
PTF --> VAL{"token in VALID_TARGET_VALUES?"}
VAL -- "pre-PR: intellij absent" --> ERR["BadParameter raised"]
VAL -- "post-PR: HIT via MCP_ONLY_TARGETS" --> SINGLE["return 'intellij' token"]
SINGLE --> AT["active_targets(root, 'intellij')"]
AT --> RTCA["RUNTIME_TO_CANONICAL_TARGET.get('intellij') = 'copilot'"]
RTCA --> KT["KNOWN_TARGETS.get('copilot') -> copilot TargetProfile"]
KT --> FS1["primitives deployed to .github/"]
SINGLE --> RTR["_resolve_target_runtimes explicit_target='intellij'"]
RTR --> GATE["_gate_project_scoped_runtimes intellij->copilot in active set"]
GATE --> FS2["IntelliJClientAdapter.install_mcp_config"]
SINGLE --> ALLP["all,intellij: non_all_tokens - EXPLICIT_ONLY - MCP_ONLY == empty"]
ALLP --> EXP["return sorted(ALL_CANONICAL_TARGETS) + ['intellij']"]
EXP --> DEDUP["active_targets: intellij->copilot deduped vscode->copilot already in seen set"]
Recommendation
Merge once the policy-gate alias fix (supply-chain finding, policy_target_check.py) and the --target help-text update (cli-logging and devx-ux convergent, install.py) are included in this PR or committed as same-day fast follows -- these two items directly gate enterprise correctness and feature discoverability for the capability being shipped. The CHANGELOG entry, ide-tool-integration.md doc update, and the two missing test-coverage items (all-expansion regression trap tagged governed-by-policy, and the integration test) should land in the same release window. The python-architect apm.yml plural-key asymmetry can trail as a documented follow-up issue. The core fix is correct and the PR author has earned a clean merge; close the discovery and policy gaps first.
Full per-persona findings
Python Architect
- [recommended] targets: [intellij] (plural YAML key) still rejected by apm_yml.CANONICAL_TARGETS after this fix at
src/apm_cli/core/apm_yml.py:25
After this PR the singulartarget: intellijin apm.yml is accepted via parse_target_field, but the pluraltargets: [intellij]still fails with UnknownTargetError because parse_targets_field validates against CANONICAL_TARGETS in apm_yml.py, which has no 'intellij' entry. Before this PR both forms failed; after this PR only the plural form fails -- a newly visible asymmetry.
Suggested: Either add 'intellij' to CANONICAL_TARGETS in apm_yml.py, or add a note to MCP_ONLY_TARGETS docstring documenting the intentional split between the two validation paths. - [nit] Stale comment at target_detection.py:630 says 'explicit-only ones' after MCP_ONLY_TARGETS is also now combinable with all at
src/apm_cli/core/target_detection.py:630
The comment still refers only to explicit-only tokens; a reader implementing a new MCP-only target would miss the established pattern.
Suggested: Change to: '# "all" + explicit-only or MCP-only tokens (e.g. "all,agent-skills", "all,intellij"): expand "all" to canonical targets and append the pass-through tokens.' - [nit] active_targets() all-branch silently relies on invariant that no MCP_ONLY_TARGETS member has a KNOWN_TARGETS entry at
src/apm_cli/integration/targets.py:1147
If a future contributor accidentally adds an MCP-only name to KNOWN_TARGETS, it would silently appear in 'all' expansions without any guard. A one-line comment would make the contract explicit.
Suggested: Add before line 1147: '# MCP_ONLY_TARGETS members (e.g. intellij) have no KNOWN_TARGETS entry by contract; no filter needed here.'
CLI Logging Expert
- [recommended] --target help text Values: list does not include intellij at
src/apm_cli/commands/install.py:945
The --target option in install.py has a hard-coded 'Values:' sentence. intellij is now accepted by VALID_TARGET_VALUES but is invisible in the help string. A user running 'apm install --help' will not find intellij and will fall back to --runtime intellij -- the legacy path this PR is designed to replace.
Suggested: Append to the Values: sentence: "'intellij' is also accepted (MCP-only: routes to the JetBrains Copilot MCP config; does not deploy harness primitives)." - [nit] Provenance line silently shows 'copilot' when user passes --target intellij at
src/apm_cli/install/phases/targets.py:379
The intellij->copilot remap via RUNTIME_TO_CANONICAL_TARGET is invisible in the '[i] Targets: copilot (source: --target flag)' output. In verbose mode, a one-liner makes the mapping explicit without cluttering default output.
Suggested: After _normalize_runtime_target_aliases, if any token was remapped and logger.is_verbose, emit a verbose-detail log line: 'intellij resolved to copilot (MCP-only alias)'.
DevX UX Expert
- [recommended] --target help text does not list intellij in the Values enumeration at
src/apm_cli/commands/install.py:945
The --target flag's inline help string lists values with no mention of intellij. Meanwhile --runtime help text explicitly lists intellij. A user reading 'apm install --help' will conclude --target intellij is invalid and fall back to --runtime intellij, exactly the legacy path this PR is trying to replace.
Suggested: Append 'intellij' to the Values clause. A parenthetical such as '(intellij is MCP-only; maps to the copilot harness)' gives just enough context. - [nit] ide-tool-integration.md JetBrains example still uses deprecated --runtime intellij at
docs/src/content/docs/integrations/ide-tool-integration.md:144
The guide teaches the old form for the one target this PR fixes. Now that --target intellij works, the guide actively directs users to the legacy path.
Suggested: Change the example to 'apm install --target intellij (package)' and update the prose note at line 152 to recommend --target over --runtime. - [nit] 'all,intellij' is allowed but the help text gives no hint this combination exists at
src/apm_cli/commands/install.py:945
The --target help text mentions 'all,agent-skills' and 'all,antigravity' but is silent about intellij combinations. The pattern 'all,(mcp-only)' is now real and undocumented inline.
Suggested: Extend the 'all' explanation: 'combine with agent-skills, antigravity, or intellij to add them (e.g. all,intellij adds the JetBrains MCP config on top of all harness targets).'
Supply Chain Security Expert
- [recommended] policy_target_check uses raw target_override ('intellij') without alias canonicalization, producing false-positive blocks under copilot-restricting org policies at
src/apm_cli/install/phases/policy_target_check.py:58
effective_target is taken directly from ctx.target_override ('intellij'), and synthetic_yml = {'target': 'intellij'} is passed to _check_compilation_target. An org with allow: ['copilot'] will see --target intellij falsely rejected even though intellij resolves to copilot. Fail-closed is secure, but it is a correctness regression for any org whose policy allows 'copilot'.
Suggested: Apply RUNTIME_TO_CANONICAL_TARGET.get(effective_target, effective_target) normalization before building synthetic_yml in policy_target_check.py. - [nit] MCP_ONLY_TARGETS has no enforced contract requiring a RUNTIME_TO_CANONICAL_TARGET entry per element at
src/apm_cli/core/target_detection.py:424
A future contributor adding a new MCP-only target without a RUNTIME_TO_CANONICAL_TARGET entry would silently produce a self-mapping target, potentially causing the targets phase to skip primitive deployment without error.
Suggested: Add a comment after the frozenset definition asserting: '# Invariant: every MCP_ONLY_TARGET must have a RUNTIME_TO_CANONICAL_TARGET entry.'
OSS Growth Hacker
- [recommended] No CHANGELOG entry for this fix -- JetBrains users who hit [BUG] MCP server integration lacks IntelliJ as target #1957 will not know it is resolved at
CHANGELOG.md
The [Unreleased] block in CHANGELOG.md is currently empty. This is a discoverable community fix that closes a documented-but-broken feature for a massive IDE ecosystem -- it earns a ### Fixed line.
Suggested: Add under [Unreleased] ### Fixed: '-apm install --target intellijnow accepted by the CLI parser;intellijwas absent fromVALID_TARGET_VALUESdespite the adapter and docs all working correctly. IntroducesMCP_ONLY_TARGETSfor pseudo-targets that map to a canonical runtime but are not full harness targets. (by @sergio-sisternes-epam, closes [BUG] MCP server integration lacks IntelliJ as target #1957)' - [nit] README hero line omits IntelliJ/JetBrains -- silent to the JetBrains community at the top of the funnel at
README.md
Now that --target intellij works and is documented, adding IntelliJ to the hero line converts JetBrains visitors who scan the top 30 lines looking for their IDE.
Suggested: Append 'IntelliJ' to the hero tool list in README.md.
Auth Expert -- inactive
The changed files (target_detection.py, test_target_detection.py) are not in the auth activation list, and the fallback self-check confirms the intellij adapter and MCP integrator contain no auth flows, credential resolution, or token management code affected by adding 'intellij' to VALID_TARGET_VALUES.
Doc Writer
- [recommended] CHANGELOG [Unreleased] has no entry for this bug fix at
CHANGELOG.md
The [Unreleased] section is empty. Consumers relying on CHANGELOG to know when a bug is fixed will have no signal for issue [BUG] MCP server integration lacks IntelliJ as target #1957.
Suggested: Add under [Unreleased] ### Fixed: '-apm install --target intellijno longer fails with an unknown-target error;intellijis now included inVALID_TARGET_VALUESas an MCP-only target. (closes [BUG] MCP server integration lacks IntelliJ as target #1957) (Fix --target intellij validation (#1957) #2041)' - [recommended] ide-tool-integration.md directs users to the legacy --runtime flag for explicit IntelliJ targeting at
docs/src/content/docs/integrations/ide-tool-integration.md
Lines 144 and 152 show the legacy --runtime intellij form. Leaving the doc pointing to the legacy flag is drift now that --target intellij is the correct path.
Suggested: Update the JetBrains code example toapm install --target intellij <package>. Update the note at line 152 to: 'Use--target intellijto deploy to JetBrains explicitly;--runtime intellijis a legacy alias that remains functional.' - [nit] targets-matrix.md has no entry for intellij at
docs/src/content/docs/reference/targets-matrix.md
Every other valid --target value has a row or prose mention. intellij appears nowhere in the matrix.
Suggested: Add a sentence to the MCP/experimental prose block: 'intellijis an MCP-only target (no deploy root for instructions, prompts, skills, or agents); it writes to the JetBrains Copilot user-scope mcp.json and is excluded from--target allexpansion.'
Test Coverage Expert
- [recommended] No regression-trap asserting intellij is excluded from --target all expansion at
tests/unit/core/test_target_detection.py
The PR asserts intellij is 'excluded from all expansion'. The copilot-cowork precedent establishes a named pattern: every target-category split must have a constant-split guard. The existing test_all_combined_with_intellij_allowed asserts the combination IS allowed, not that bareallexcludes intellij. Grep of test file confirmed: no test for 'intellij not in ALL_CANONICAL_TARGETS'.
Suggested: Add: test_intellij_not_in_all_canonical_targets (asserts 'intellij' not in ALL_CANONICAL_TARGETS) and test_all_expansion_excludes_intellij (asserts 'intellij' not in normalize_target_list('all')).
Proof (missing at unit):tests/unit/core/test_target_detection.py::test_intellij_not_in_all_canonical_targets-- proves: '--target all' never silently deploys to IntelliJ; intellij is opt-in only [devx, governed-by-policy] - [recommended] No integration test exercises apm install --target intellij through the CLI runner at
tests/integration/test_intellij_target.py
This PR fixes a CLI validation rejection bug. Tier-floor for CLI surface changes requires integration-with-fixtures evidence. Hermes and openclaw have integration tests (test_hermes_target.py, test_openclaw_target.py); grep of tests/integration/ for 'intellij' returned zero matches.
Suggested: Create tests/integration/test_intellij_target.py mirroring test_hermes_target.py with a CliRunner-backed test: result = runner.invoke(cli, ['install', '--target', 'intellij', '--global']); assert result.exit_code == 0.
Proof (missing at integration-with-fixtures):tests/integration/test_intellij_target.py::TestIntelliJParserE2E::test_target_intellij_accepted_and_exits_zero-- proves: 'apm install --target intellij' routes to the IntelliJ MCP adapter and exits 0 rather than 'unknown target' [devx, multi-harness-support] - [nit] test_all_combined_with_intellij_allowed uses parse_target_field directly rather than TargetParamType.convert, inconsistent with parallel all-combination tests at
tests/unit/core/test_target_detection.py
The other 'all,X' tests use self.tp.convert. Minor -- parse_target_field IS the shared implementation so coverage is functionally equivalent.
Suggested: Change to use self.tp.convert('all,intellij', None, None) for consistency with the test class pattern.
Performance Expert -- inactive
No performance-sensitive paths touched. Change is limited to a module-level frozenset literal constructed once at import time, one frozenset union at import time, and one additional frozenset difference inside the CLI argument parser -- all O(1) or O(n) with n equal to the number of user-supplied target tokens. None of the four install phases (Resolve, Fetch, Materialize, Verify) are touched.
This panel is advisory. It does not block merge. Re-apply the
panel-review label after addressing feedback to re-run.
Generated by PR Review Panel for issue #2041 · 722.1 AIC · ⌖ 17.8 AIC · ⊞ 5.5K · ◷
- Normalise intellij -> copilot in policy_target_check.py via RUNTIME_TO_CANONICAL_TARGET so org allow-lists are not falsely rejected - Add intellij to --target help text in install.py with MCP-only note - Add CHANGELOG entry under [Unreleased] Fixed - Update ide-tool-integration.md from --runtime intellij to --target intellij - Add constant-split guard tests: intellij not in ALL_CANONICAL_TARGETS, in MCP_ONLY_TARGETS, and all-expansion excludes intellij - Create tests/integration/test_intellij_target.py with constant guards, CLI E2E parser acceptance, and policy normalisation tests Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add intellij to VALID_TARGET_VALUES via a new MCP_ONLY_TARGETS set so that `apm install --target intellij` passes the CLI parser. Previously the adapter, factory registration, auto-detection, and MCP install logic all existed but the --target flag rejected the token at parse time. MCP-only pseudo-targets (like intellij) have a client adapter but no KNOWN_TARGETS entry -- they map to a canonical target for primitive deployment via RUNTIME_TO_CANONICAL_TARGET. The new MCP_ONLY_TARGETS frozenset captures this category explicitly and is included in VALID_TARGET_VALUES alongside the canonical, experimental, and explicit-only sets. Also allows `all,intellij` combination (same pattern as `all,agent-skills`). Closes #1957 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Address review feedback: detect_target() now maps explicit_target and config_target 'intellij' to 'vscode' (same group as copilot/agents), preventing silent fallthrough to auto-detect when --target intellij is used with apm compile or apm pack. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Normalise intellij -> copilot in policy_target_check.py via RUNTIME_TO_CANONICAL_TARGET so org allow-lists are not falsely rejected - Add intellij to --target help text in install.py with MCP-only note - Add CHANGELOG entry under [Unreleased] Fixed - Update ide-tool-integration.md from --runtime intellij to --target intellij - Add constant-split guard tests: intellij not in ALL_CANONICAL_TARGETS, in MCP_ONLY_TARGETS, and all-expansion excludes intellij - Create tests/integration/test_intellij_target.py with constant guards, CLI E2E parser acceptance, and policy normalisation tests Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
RUNTIME_TO_CANONICAL_TARGET maps vscode -> copilot too, so applying it unconditionally broke existing tests that pass vscode as effective_target. Guard the normalisation with an MCP_ONLY_TARGETS membership check so only pseudo-targets like intellij are remapped. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
7d9659e to
6b7a0a2
Compare
APM Review Panel:
|
| Persona | B | R | N | Takeaway |
|---|---|---|---|---|
| Python Architect | 0 | 1 | 1 | Remove duplicated IntelliJ mapping truth. |
| CLI Logging Expert | 0 | 0 | 1 | Surface policy normalization in verbose output. |
| DevX UX Expert | 0 | 1 | 2 | Keep CLI references and help discoverable. |
| Supply Chain Security Expert | 0 | 0 | 1 | Fail closed if an MCP-only mapping is missing. |
| OSS Growth Hacker | 0 | 0 | 2 | Use user-facing release wording. |
| Doc Writer | 1 | 1 | 1 | Correct the command and target references. |
| Test Coverage Expert | 0 | 2 | 0 | Add real CLI/install evidence and policy coverage. |
B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.
Top 5 follow-ups
- [Doc Writer] (blocking-severity) Forward
--target intellijthrough direct MCP installation and correct the documented command. - [Test Coverage Expert] Add an empirical subprocess test that writes the IntelliJ MCP config.
- [Test Coverage Expert] Exercise IntelliJ-to-Copilot policy normalization.
- [Python Architect] Remove duplicated hardcoded IntelliJ mapping.
- [Supply Chain Security Expert] Replace the fail-open canonical mapping fallback.
Recommendation
Fold these bounded changes into this PR, then re-run the panel against the user-observable install flow.
Full per-persona findings
The highest-signal evidence is tests/integration/test_intellij_target.py: it invokes the CLI without an MCP name and only checks that an error string is absent. It does not execute MCP integration or assert that github-copilot/intellij/mcp.json is written. The docs example also supplies no value to --mcp. Other findings concern duplicated mapping logic, policy mapping fallback, verbose diagnostics, and reference coverage.
This panel is advisory. It does not block merge. Re-apply the panel-review label after addressing feedback to re-run.
Forward --target through the direct MCP install path, prove the real CLI writes JetBrains Copilot configuration, and align policy, help, and reference documentation with the user-visible behavior. Addresses panel follow-ups for PR #2041. Co-authored-by: Sergio Sisternes <sergio.sisternes@epam.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Guard MCP-only membership checks for list-valued target inputs and retain the documented all-target expansion in CLI help. Co-authored-by: Sergio Sisternes <sergio.sisternes@epam.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Make the subprocess regression select the worktree binary, harden policy mapping invariants, improve target diagnostics and typing, and complete IntelliJ documentation. Co-authored-by: Sergio Sisternes <sergio.sisternes@epam.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
apm-spec-waiver: This restores documented IntelliJ behavior through existing target and MCP extension points; it does not extend the OpenAPM specification. Co-authored-by: Sergio Sisternes <sergio.sisternes@epam.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Align documentation with the Copilot primitive profile, make verbose target diagnostics stable for lists, and document the dual MCP routing contract. apm-spec-waiver: This restores documented IntelliJ behavior through existing target and MCP extension points; it does not extend the OpenAPM specification. Co-authored-by: Sergio Sisternes <sergio.sisternes@epam.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Make delegated Copilot primitives explicit in every docs surface, gate the binary integration test declaratively, and tighten target diagnostics and legacy type boundaries. apm-spec-waiver: This restores documented IntelliJ behavior through existing target and MCP extension points; it does not extend the OpenAPM specification. Co-authored-by: Sergio Sisternes <sergio.sisternes@epam.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
APM Review Panel:
|
| Persona | B | R | N | Takeaway |
|---|---|---|---|---|
| Python Architect | 1 | 0 | 0 | Multi-target policy checks still crash on list input. |
| CLI Logging Expert | 1 | 1 | 0 | Multi-target policy output crashes before structured diagnostics. |
| DevX UX Expert | 1 | 0 | 0 | Explicit IntelliJ selection may touch adjacent Copilot runtimes. |
| Supply Chain Security Expert | 2 | 0 | 0 | Direct MCP and plural-target policy paths are not uniformly governed. |
| OSS Growth Hacker | 0 | 0 | 0 | Adoption surfaces are otherwise clean. |
| Doc Writer | 0 | 1 | 0 | Auto-detection docs still overstate the non-MCP contract. |
| Test Coverage Expert | 0 | 2 | 0 | Scalar flow is proven; composed and governed flows lack integration proof. |
| Performance Expert | 0 | 0 | 0 | No performance defect found. |
B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.
Top 5 follow-ups
- [Supply Chain Security Expert] (blocking-severity) Unify direct
--mcppreflight and post-target policy evaluation around the same resolved target set, including plural targets and MCP-only canonical mappings. --compilation.target.allowmust apply uniformly across install paths. - [Python Architect] (blocking-severity) Make target handling shape-stable so both
strandlist[str]forms are normalized before membership checks or policy evaluation. -- The reproduced TypeError turns valid multi-target input into a runtime crash. - [DevX UX Expert] (blocking-severity) Constrain explicit
--target intellijinstalls to the intended JetBrains Copilot MCP side effects. -- A specific client target should not write adjacent client config. - [Test Coverage Expert] Add CLI coverage for
--target intellij,claude,--target all,intellij, and plural-target policy enforcement. -- Existing passing evidence is scalar-only. - [Doc Writer] Reconcile target detection documentation after runtime behavior is corrected. -- Public claims must match the final install contract.
Architecture
flowchart TD
A[\"apm install --mcp NAME --target intellij\"] --> B[\"TargetParamType validation\"]
B --> C[\"_handle_mcp_install target=intellij\"]
C --> D[\"run_mcp_install\"]
D --> E[\"MCPIntegrator.install runtime=intellij explicit_target=intellij\"]
E --> F[\"JetBrains mcp.json write\"]
A --> G[\"policy_target_check\"]
G --> H{\"target shape\"}
H -->|scalar| I[\"intellij to copilot\"]
H -->|list| J[\"TypeError before policy result\"]
Recommendation
Do not ship this SHA yet. First fix target-shape and policy-path inconsistencies so direct --mcp, scalar targets, and plural targets share one resolved-target contract. Then verify explicit IntelliJ selection only touches intended config, add composed-flow regression coverage, and rerun the panel.
Full per-persona findings
Python Architect
- [blocking]
policy_target_checkcrashes on valid IntelliJ-containing target lists atsrc/apm_cli/install/phases/policy_target_check.py:74.
effective_target in MCP_ONLY_TARGETShashes a list and raisesTypeErrorbefore policy evaluation.
CLI Logging Expert
- [blocking] Multi-target installs crash before structured policy output at
src/apm_cli/install/phases/policy_target_check.py:74. - [recommended] Legacy
vscodeallowlists may not be equivalent tocopilotfor IntelliJ policy normalization.
DevX UX Expert
- [blocking] Explicit IntelliJ selection can retain other runtimes whose canonical target is Copilot at
src/apm_cli/integration/mcp_integrator.py:1068.
Supply Chain Security Expert
- [blocking] Direct targeted MCP installs can miss
compilation.targetpreflight atsrc/apm_cli/commands/install.py:845. - [blocking] Policy target checks ignore resolved plural targets at
src/apm_cli/install/phases/policy_target_check.py:57.
OSS Growth Hacker
No findings.
Auth Expert -- inactive
No authentication, token, credential, host-classification, header, or fallback surface changed.
Doc Writer
- [recommended] The targets matrix overstates IntelliJ auto-detection outside MCP runtime discovery.
Test Coverage Expert
- [recommended] IntelliJ target combinations lack real CLI integration coverage.
- [recommended] The Copilot allowlist promise remains unit-tier only.
Performance Expert
No findings.
This panel is advisory. It does not block merge. Re-apply the panel-review label after addressing feedback to re-run.
Add isinstance(str) guards before 'in MCP_ONLY_TARGETS' checks in detect_target() and policy_target_check.py to prevent TypeError when explicit_target is a list (multi-target mode like ['intellij', 'claude']). Also handle list normalisation in policy_target_check. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Normalize scalar and plural selectors through one policy contract, preserve exact direct MCP runtime sets, and add empirical composed-target coverage. Addresses final panel follow-ups for PR #2041. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Separate JetBrains MCP runtime discovery from file-primitive target detection. Addresses the final doc-writer panel finding for PR #2041. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
APM Review Panel:
|
| Persona | B | R | N | Takeaway |
|---|---|---|---|---|
| Python Architect | 0 | 0 | 3 | Clean MCP-only pseudo-target layering; shape-preserving policy normalization is sound. |
| CLI Logging Expert | 0 | 1 | 1 | Output is consistent overall; one new progress line uses internal "runtimes" wording. |
| DevX UX Expert | 0 | 0 | 0 | IntelliJ is discoverable and composed-target behavior is documented consistently. |
| Supply Chain Security Expert | 0 | 0 | 0 | No security concerns; direct and plural policy enforcement is preserved. |
| OSS Growth Hacker | 0 | 0 | 0 | Schema failure after two retries; skill-defined placeholder used. |
| Doc Writer | 0 | 0 | 0 | Final docs match code, including separate file and MCP discovery behavior. |
| Test Coverage Expert | 0 | 0 | 0 | Critical scalar, plural, direct-policy, and side-effect contracts are defended. |
| Performance Expert | 0 | 0 | 0 | No install-path performance regression detected. |
B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.
Top 2 follow-ups
- [CLI Logging Expert] Align the new user-facing "runtimes" wording to "targets" -- this matches the manifest and documentation vocabulary.
- [Python Architect] Consider the cosmetic defensive-check and lazy-import-comment cleanups in a future maintenance pass -- they do not affect behavior.
Architecture
classDiagram
direction LR
class TargetParamType {
+convert(value, param, ctx)
}
class target_detection {
+detect_target(project_root, explicit_target, config_target)
+normalize_policy_targets(value)
}
class InstallContext {
+target_override: str | list | None
}
class PolicyTargetCheckPhase {
+run(ctx)
}
class MCPIntegrator {
+install(deps, runtime, explicit_target)
}
class InstallPreflight {
+run_policy_preflight(effective_target)
}
TargetParamType ..> target_detection : parses
PolicyTargetCheckPhase ..> target_detection : normalizes
PolicyTargetCheckPhase ..> InstallContext : reads override
MCPIntegrator ..> target_detection : resolves exact targets
InstallPreflight ..> target_detection : normalizes
flowchart TD
A[CLI target input] --> B[Parse scalar or list]
B --> C[Normalize policy targets]
C --> D{Policy allows all targets?}
D -->|No| E[Stop install]
D -->|Yes| F[Resolve exact explicit runtime set]
F --> G[Write only selected MCP configurations]
Recommendation
Ship now. Exact-head checks are green, regression guards passed, all prior rework findings were folded, and the final panel found no correctness concern. Track the terminology adjustment as optional follow-up polish.
Full per-persona findings
Python Architect
- [nit] Redundant
isinstance(explicit_target, str)guard indetect_targetatsrc/apm_cli/core/target_detection.py:130
The signature and guarded call site already constrain this value tostr | None; the defensive check is harmless but can suggest a broader contract.
Suggested: Simplify the membership check when next touching this helper. - [nit] Lazy import rationale could live beside the import at
src/apm_cli/core/target_detection.py:509
The lazy import correctly avoids the target module cycle, but a local explanation would make that choice easier to preserve. - [nit] The lightweight adapter is the right design at this scope
Shape-preserving normalization cleanly maps the MCP-only target domain to canonical policy targets; a class hierarchy would be unnecessary today.
CLI Logging Expert
- [recommended] Progress message uses internal "runtimes" vocabulary at
src/apm_cli/integration/mcp_integrator_install.py:357
progress()is user-facing, and IntelliJ is a target that maps to a runtime rather than a runtime itself.
Suggested: PreferTarget: intellijorTargets: intellij, claude. - [nit] The removed outer verbose guard is intentionally asymmetric at
src/apm_cli/install/mcp/command.py:118
verbose_detail()already self-gates, so the change is correct; a future cleanup could make the surrounding guards visually consistent.
DevX UX Expert
No findings.
Supply Chain Security Expert
No findings.
OSS Growth Hacker
No findings. The persona returned malformed output after two retries; the schema-defined placeholder was used.
Auth Expert -- inactive
No authentication, token, credential, host classification, or authorization header files are changed.
Doc Writer
No findings.
Test Coverage Expert
No findings.
Performance Expert
No findings.
This panel is advisory. It does not block merge. Re-apply the
panel-review label after addressing feedback to re-run.
Why
apm install --target intellijrejectsintellijas an unknown target at the CLI parser layer, even though the IntelliJ client adapter, factory registration, auto-detection logic, MCP install/cleanup code, and documentation all exist and work correctly. The--runtime intellijlegacy flag works fine because it bypasses target validation entirely.The root cause:
intellijis absent fromVALID_TARGET_VALUESintarget_detection.py. This frozenset is the union ofALL_CANONICAL_TARGETS,EXPERIMENTAL_TARGETS,EXPLICIT_ONLY_TARGETS, andTARGET_ALIASES-- butintellijwas in none of them.Approach
Introduces a
MCP_ONLY_TARGETSfrozenset for pseudo-targets that have a client adapter but noKNOWN_TARGETSentry (they map to a canonical target for primitive deployment viaRUNTIME_TO_CANONICAL_TARGET). This new set is:VALID_TARGET_VALUESso the CLI parser accepts--target intellij"all,<target>"combination check (same pattern asall,agent-skills)"all"expansion (intellij is MCP-only, not a full harness target)--mcpinstalls so JetBrains Copilot's user-scopemcp.jsonis writtencopilotfor organization policy evaluationapm-spec-waiver: This restores documented IntelliJ behavior through existing target and MCP extension points; it does not extend the OpenAPM specification.
Tests added
intellijpresence inVALID_TARGET_VALUES--target intellijparses successfullyintellij,claudeacceptedall,intellijcombination allowedmcp.jsonScenario evidence
apm install --mcp NAME --target intellijexits successfully and writes JetBrains Copilot's OS-specificmcp.jsonwith the requested server.tests/integration/test_intellij_target.py::TestIntelliJCliE2E::test_mcp_install_writes_intellij_configcopilotalso permits the MCP-onlyintellijtarget.tests/unit/install/test_policy_target_check_phase.py::TestTargetOverride::test_intellij_override_is_normalized_to_copilottests/integration/test_intellij_target.py::TestIntelliJConstants::test_all_mcp_only_targets_have_canonical_mappingMutation-break evidence: removing direct
--targetforwarding caused the subprocess integration test to fail because JetBrains Copilot'smcp.jsonwas not written; restoring forwarding returned the test to green.Fixes: #1957