AX-1694 — Align VS Code copilot-instructions with Claude/Cursor agent-guard docs#21
AX-1694 — Align VS Code copilot-instructions with Claude/Cursor agent-guard docs#21MatanEden1 wants to merge 31 commits into
Conversation
…-guard docs
Bring the VS Code MCP management instructions up to the structure of the
updated Claude and Cursor agent-guard docs, while keeping VS Code-native
mechanics:
- Add Pre-flight section (live-execution/no-local-resolution rule,
mandatory <PROJECT>, auto-resolvable <SERVER_ID>, network/sandbox note)
- Catalog-first "Adding an MCP" flow; numbered Steps 1-5 with explicit
start+verify (4a) and OAuth login (5)
- Keep VS Code secrets model: top-level `inputs` + `${input:id}` +
keychain prompt-on-first-start (NOT env-var export)
- Routing table for Listing MCPs; available vs installed
- New Managed Settings section: block non-agent-guard installs and
removal of protected MCPs
- Explicit project re-sync on update/switch; orphaned-input cleanup on
removal; expanded Key Rules and Troubleshooting
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ror project-switch priority into Pre-flight - "live execution" exemption now says "local config files" (covers both workspace .vscode/mcp.json and the user-level MCP config) instead of naming only the workspace file - mirror the explicit project-switch priority into the Pre-flight <PROJECT> bullet so it also governs listing/inspecting, not just writes Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Regression check vs the Claude/Cursor sources found the only dropped canonical detail: both gate --login on a remote section *with type:"http"*. VS Code had generalized it to "a remote section", which could fire --login for non-http remotes. Restore the qualifier. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
YoniMelki
left a comment
There was a problem hiding this comment.
Review: requesting changes
Reviewed against the canonical Claude (claude-plugin/templates/jfrog-mcp-management.md) and Cursor (cursor-plugin/plugins/jfrog/templates/jfrog-mcp-management.md) templates, since the goal of this PR is cross-plugin alignment.
The alignment work itself is solid — structure, command blocks, Pre-flight resolution chains, and Key Rules all track the other two templates, and the VS Code-native mechanics (servers / inputs / ${input:...} keychain model, CodeLens, MCP: List Servers) are preserved correctly. Nice work.
Requesting changes for the items below — details in the inline comments.
Must fix (this file):
- Trailing whitespace, plus a
. For HTTP→.For HTTPmissing-space regression in the Step 4inputsrules.
Needs a decision / release step:
- Version bump: this changes the template that ships to users, but
marketplace.json(currently1.0.2) isn't bumped. Per our release convention vscode-plugin bumpsmarketplace.jsononly — please bump it so the new instructions actually ship. - A few additions here are ahead of / diverge from Claude & Cursor (the
## Managed Settingssection, the<PROJECT>re-syncException:clause, and the richer Step 2 error handling). Each is good on its own, but for true alignment we should either back-port them to the other two plugins or mark them as intentional VS-Code-only. Please also correct the PR description line about VS Code 'missing ... managed-settings enforcement' — it's actually ahead there.
Confirmed separately: the registry env var JFROG_AGENT_GUARD_REPO is correct (matches Claude). Cursor's JFROG_MCP_GATEWAY_REPO is the stale outlier and can be fixed in a separate change.
Address YoniMelki's review on PR #21: - Remove the VS-Code-only <PROJECT> switch/re-sync Exception clause from the Pre-flight bullet (not present in Claude/Cursor). - Reword the broken server-resolution prose into a single clear sentence. - Fix two regressions in the Step 4 inputs rules: trailing whitespace and a missing space ("${input:<id>}".For -> . For). - Remove the net-new Managed Settings section (and its cross-reference in Removing an MCP); not present in Claude/Cursor. Step 2's richer not-allowed/near-miss handling is kept intentionally (to be back-ported to Claude/Cursor for alignment). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…js injector Consolidate ensure-instructions.sh and ensure-instructions.ps1 into a single inject-instructions.mjs that works on all platforms. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ions Add resolveCredentials() with strict priority chain: --server flag, env vars, CLI config default profile, and single-profile fallback. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
YoniMelki
left a comment
There was a problem hiding this comment.
Re-review (head 3585b81): still requesting changes
Thanks for the updates. Confirmed resolved from the previous round: the . For HTTP space regression and the trailing whitespace in the template are fixed, and the project-switch priority is now mirrored into Pre-flight.
The scope grew to replace the shell scripts with inject-instructions.mjs, and that new file has blocking issues — details inline. Summary:
Blocking
inject-instructions.mjsreads the wrong template filename (jfrog-mcp-management.mdvs this repo'scopilot-instructions.md) and fails silently → nothing is ever injected.- The injector no longer writes
.github/copilot-instructions.md, which is the file VS Code / GitHub Copilot actually reads — only the Claude-CodeadditionalContextis emitted now. Need confirmation this delivery-model change is intentional.
Should fix
- Asymmetric force-flag env-var names (disable has a leading
_, enable doesn't). --serverresolution is dead code, since the hook invokes the script with no args.- New per-session network call on SessionStart (minor; please note it in the PR).
Process
marketplace.jsonis1.0.3on bothmainand this branch, so the PR doesn't bump it — confirm these changes ship under a fresh version (if1.0.3is already published, this needs1.0.4).- The PR description is now stale: it doesn't mention the script→Node-injector replacement (the largest code change here), and still claims VS Code was 'missing … managed-settings enforcement while the other two plugins moved ahead' (VS Code is actually ahead). Please update both.
- Fix template filename to copilot-instructions.md (was injecting nothing) - Restore .github/copilot-instructions.md write for Copilot delivery - Align force-enable env vars with underscore-prefixed convention - Remove unreachable --server resolution branch and fix precedence docs - Lower gateway settings-check timeout from 5s to 3s Co-authored-by: Cursor <cursoragent@cursor.com>
--login launches the system browser and runs a local OAuth callback server, so a sandboxed run needs unrestricted permissions. Co-authored-by: Cursor <cursoragent@cursor.com>
YoniMelki
left a comment
There was a problem hiding this comment.
Re-review (head 5cc4d1d): one alignment blocker left
Thanks for the quick turnaround — most of the last round is resolved.
Resolved
- Template filename fixed to
copilot-instructions.md(was injecting nothing); the readcatchnow logs instead of failing silently. .github/copilot-instructions.mdwrite restored (write-when-absent, non-fatal) — Copilot delivery is back, withadditionalContextstill covering Claude Code.--serverdead-code branch removed and the precedence docstring corrected.- Settings-check timeout lowered to 3s with an explanatory comment.
Blocking (alignment)
- The force-flag rename diverges from Claude/Cursor — see inline. Important correction to my previous comment: the disable/enable asymmetry (
_JF_AGENT_GUARD_FORCE_DISABLEwith underscore,JF_AGENT_GUARD_FORCE_ENABLEwithout) is the intentional, identical convention in both reference plugins. My earlier 'align them' note was wrong for this PR's goal. Adding the underscore to the enable flag meansJF_AGENT_GUARD_FORCE_ENABLE(the name that works in Claude/Cursor) now silently no-ops in VS Code. Please match the references exactly.
Minor — VS-Code-ahead deltas (not blocking; reconcile or confirm intentional)
resolveCredentials()adds a JF-CLI-config fallback the references don't have (they're env-only) — nice enhancement, but it changes when the settings check fires vs Claude/Cursor. Worth back-porting for parity or noting as deliberately ahead.- 3s vs the references' 5s timeout, and
isGatewayEnabledViaSettings/ 'gateway' log wording vs the references' 'agent guard' naming (post-rename). Cosmetic. - The clearer
--loginsandbox-permissions note is a good candidate to back-port to Claude/Cursor. .github/copilot-instructions.mdis create-only — see inline lifecycle note.
Process
marketplace.jsonis1.0.3on bothmainand this branch. Per this repo's convention that's the file bumped per ticket, so AX-1694 should ship as1.0.4if1.0.3is already released.- The PR description is stale: it still lists 'Add a Managed Settings section' under Changes, but that section was removed in
0606423; and it doesn't mention the script→Node-injector replacement (the largest change here). Please update both.
- inject-instructions.mjs: fall back to ~/.jfrog/jfrog-cli.conf.v6 (default profile, else the sole profile) when JFROG_URL/token env vars are absent. - copilot-instructions template: default install location to ~/.vscode/mcp.json, clarify remote MCPs use the catalog name (no spec.packageName), and scope the inputs id uniqueness to the config file it lives in. Co-authored-by: Cursor <cursoragent@cursor.com>
Rework instructions to clarify precedence and locations for MCP configuration: prefer workspace .vscode/mcp.json as the default target, and use the VS Code user-level MCP config only for global/personal installs. Update Server ID guidance to read the server value from the workspace file or the VS Code user config (via "MCP: Open User Configuration"). Add explicit OS paths for the user-level config and emphasize writing only to the chosen scope (workspace vs user). Also update Step 4 to reference .vscode/mcp.json consistently and remind that secrets must use ${input:...} substitution.
Consolidate all instruction references to use only ~/.vscode/mcp.json and remove the workspace .vscode/mcp.json branches for a single, consistent config location. Co-authored-by: Cursor <cursoragent@cursor.com>
VS Code never reads ~/.vscode/mcp.json. Point the instructions at the two locations it actually loads: the workspace .vscode/mcp.json and the user-profile mcp.json (MCP: Open User Configuration), with the correct per-OS paths, and explicitly warn off ~/.vscode/mcp.json. Co-authored-by: Cursor <cursoragent@cursor.com>
Update instructions to refer to the user-level ~/.vscode/mcp.json as the default
YoniMelki
left a comment
There was a problem hiding this comment.
Re-review (head af832bb): injector regressed — please don't ship this version
The template MCP-config work this round is good (see below), but inject-instructions.mjs was replaced with what looks like a verbatim copy of the Cursor injector, which re-broke two blockers from earlier rounds and added a third. As it stands on af832bb, the injector delivers nothing to either Copilot or Claude Code. Details inline; summary:
Blocking (all in inject-instructions.mjs)
- Wrong template filename, again — reads
templates/jfrog-mcp-management.md, which does not exist in this repo (the only template iscopilot-instructions.md). The read throws, thecatchwrites{}and exits → nothing injected. This is the round-1 critical bug, reintroduced. .github/copilot-instructions.mdwrite removed, again — the file-materialization block that was restored last round is gone, so Copilot has no instructions file to read. Round-1 major regression, reintroduced.- Wrong output key for this hook — emits top-level
additional_context(Cursor's format), buthooks.jsonis a Claude CodeSessionStarthook, which readshookSpecificOutput.additionalContext. Even with the filename fixed, the payload would be ignored.
Resolved / good
- Force-flag fixed:
forceEnabledis nowJF_AGENT_GUARD_FORCE_ENABLE(no underscore), matching Claude/Cursor. Thanks for the correction. resolveCredentials()refactor is cleaner and keeps the env→JF-CLI-config fallback; naming aligned; 5s timeout matches the references.- Template config-location work is accurate: it correctly warns against
~/.vscode/mcp.jsonand points to the real user-profile paths (…/Code/User/mcp.json) and the workspace.vscode/mcp.json. Nicely done.
The fix: keep this round's force-flag fix and refactor, but restore the three VS-Code-specific bits the Cursor copy dropped — read copilot-instructions.md, re-add the .github/copilot-instructions.md write, and emit hookSpecificOutput.additionalContext. Effectively the prior head's injector plus this round's force-flag change.
Process
marketplace.jsonis still1.0.3on bothmainand this branch — no bump; should be1.0.4per the per-ticket convention if1.0.3is released.- PR description is still stale: it lists 'Add a Managed Settings section' (removed in
0606423) and omits the script→Node-injector rewrite.
Fixed template path to copilot-instructions.md. Restored automatic workspace write to .github/copilot-instructions.md if missing. Aligned stdout payload with Claude Code's SessionStart hook format. Added missing fs imports and explicit debug error logging.
YoniMelki
left a comment
There was a problem hiding this comment.
Re-review (head dace1a6): injector fixed ✅ — but a new template regression
Thanks Matan — all three injector blockers are resolved and verified:
- reads
copilot-instructions.md(not the nonexistentjfrog-mcp-management.md); - restores the
.github/copilot-instructions.mdwrite (write-when-absent, non-fatal); - emits
hookSpecificOutput.additionalContext, the correct shape for this Claude CodeSessionStarthook.
The injector is now coherent and correct. However, a separate commit this round (ba067fa, "Clarify user-level MCP config path") regressed the template in the wrong direction, and it's blocking.
Blocking — wrong user-level MCP config path (7 places)
ba067fa replaced the user-level config path with ~/.vscode/mcp.json everywhere (lines 87, 121, 123, 197, 248, 324, 358) and deleted the correct paths. Per the VS Code docs, the user-level mcp.json lives in the user-profile folder — ~/Library/Application Support/Code/User/mcp.json (macOS), ~/.config/Code/User/mcp.json (Linux), %APPDATA%\Code\User\mcp.json (Windows). VS Code does not read an mcp.json in ~/.vscode/ (that folder holds extensions and argv.json). The previous head (af832bb) had this correct and even warned against this exact path — please restore those paths. Details inline. (Refs: https://code.visualstudio.com/docs/copilot/chat/mcp-servers and https://code.visualstudio.com/docs/agent-customization/mcp-servers)
Process (unchanged)
marketplace.jsonis still1.0.3on bothmainand this branch — no bump; should be1.0.4per the per-ticket convention.- PR description is still stale: it lists 'Add a Managed Settings section' (removed in
0606423) and omits the script→Node-injector rewrite.
Require reachable JFROG_URL credentials for agent guard commands
YoniMelki
left a comment
There was a problem hiding this comment.
Re-review at head 5036f0d.
Landed this round (good ✅) — commit 5036f0d adds the credentials block (template lines ~49–72): JFROG_URL must be the bare platform base URL, present in the command's own environment, with a clear explanation of the '<' looking for beginning of value HTML-not-JSON failure. Accurate, well-scoped, closes a real footgun.
Injector — unchanged since dace1a6 and still correct: reads copilot-instructions.md, writes .github/copilot-instructions.md when absent, emits hookSpecificOutput.additionalContext. All earlier injector blockers remain resolved. ✅
🔴 Blocker (still open) — wrong user-level MCP config path. This is the one remaining functional blocker, and it's now an open disagreement rather than an oversight: the template uses ~/.vscode/mcp.json for the user-level config in 7 places, and Matan's replies note we'd "talked about" that path. I've replied in detail on both inline threads (write path, line 144; read path, line 379) with the evidence:
- VS Code's
MCP: Open User Configurationopensmcp.jsonin the user profile folder (~/Library/Application Support/Code/User/on macOS), per the docs — not the home~/.vscode/folder (which is for extensions +argv.json). - Verified on a real machine with two active user-level gallery MCPs: VS Code wrote them to
~/Library/Application Support/Code/User/mcp.json(+ aCode/User/mcp/runtime dir);~/.vscode/mcp.jsonwas never created. - Net effect as written: install silently no-ops (line 144) and "Currently installed" always reads empty (line 379).
Correct user-level paths — macOS ~/Library/Application Support/Code/User/mcp.json, Windows %APPDATA%\Code\User\mcp.json, Linux ~/.config/Code/User/mcp.json. Workspace .vscode/mcp.json is correct and stays.
One-step confirmation: run MCP: Open User Configuration and read the path in the editor tab. If it's …/Code/User/mcp.json, this needs the fix; if it genuinely opens ~/.vscode/mcp.json, I'm wrong — say so on the thread and I'll drop it.
Process notes (carried forward, unchanged):
marketplace.jsonnot bumped —plugins[0].versionis still1.0.3on both head andmain; should be1.0.4per convention.- PR description is stale: it lists "Add a Managed Settings section," but there's no such section in the template (the earlier
## Managed Settingsheading is gone — its removal isn't reflected in the description); and it still omits the injector rewrite (ensure-instructions.sh/.ps1→inject-instructions.mjs), the largest structural change in the PR.
- Replace wrong user-level path (~/.vscode/mcp.json) with correct platform-specific VS Code user-profile paths in 7 template locations: macOS ~/Library/Application Support/Code/User/mcp.json, Linux ~/.config/Code/User/mcp.json, Windows %APPDATA%\Code\User\mcp.json. Step 1 "Target config file" is the single source of truth; other sections back-reference it. - Add "timeout": 7 to hooks.json to match claude-plugin reference and provide a hard kill-switch above the injector's 5s fetch timeout. - Document create-only .github/copilot-instructions.md lifecycle in both the script comment and a new Troubleshooting entry so users know to start a new Claude Code session after deleting for a refresh. - Bump marketplace.json version 1.0.3 → 1.0.4 so the updated template and hook actually ship to users. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…jection, fix token leak Apply davida-jfrog's review feedback on the VS Code agent-guard plugin: - Rename templates/copilot-instructions.md -> templates/jfrog-mcp-management.md for consistency with the Claude and Cursor plugins, and update the read path in inject-instructions.mjs to match. - Deprecate the .github/copilot-instructions.md materialization. Copilot consumes hookSpecificOutput.additionalContext directly, so writing the file as well duplicated the instructions. The SessionStart additionalContext payload is now the sole injection mechanism; remove the now-unused writeFileSync/mkdirSync/existsSync imports and the obsolete "Copilot instructions look outdated" troubleshooting bullet. - Stop instructing the agent to prepend JFROG_ACCESS_TOKEN inline on the command line (leaks the secret into shell history / process listings). Credentials now resolve from already-exported env vars or via --server reading jfrog-cli.conf.v6; only the non-secret JFROG_URL may be prepended. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ctor comment - Drop the "Credentials must be present in the command's OWN environment / bare-JFROG_URL" Pre-flight block from the template (davida-jfrog: not VS Code-specific; the underlying /ui->HTML footgun is tracked for the shared Claude/Cursor instructions instead). Credential resolution is still covered by the <SERVER_ID> Pre-flight bullets. - Reword the injection comment to drop the now-irrelevant Copilot / copilot-instructions.md references. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…/Cursor - Bump plugin.json to 1.0.4 (in tandem with marketplace.json). - Drop the sandbox/full-network wording (VS Code has no command sandbox) in the Pre-flight, Step 5 --login note, and the 403 troubleshooting entry; reframe as network/proxy/registry guidance. - Clarify agent-vs-user actions in the "0 tools" troubleshooting entry (the agent cannot operate the VS Code UI) and add a framing note. - Revert the lines 63-68 wording to match the Claude/Cursor templates so the shared prose stays aligned. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… CLI config
Per David's review: stop hand-parsing ~/.jfrog/jfrog-cli.conf.v6 (its format
varies across CLI versions). Env vars still take precedence; the CLI fallback
now runs 'jf config export' (default server) and decodes the base64 Config
Token for {url, accessToken}, letting the CLI own all config-format parsing.
Falls back to injecting nothing when jf is absent or no server is configured.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| Once you have a name, run a SINGLE command — no Fetch/WebFetch, no | ||
| custom curl/Python, no direct JFrog API calls: |
There was a problem hiding this comment.
Why is this differnt from cursor?
There was a problem hiding this comment.
already resolved
| Writing the entry to `mcp.json` is not enough — the server has | ||
| to start and actually expose tools. | ||
|
|
||
| 1. VS Code detects the edited `mcp.json` and offers a **Start** action |
There was a problem hiding this comment.
The agent cant do it so this should say what the agent should ask the user to do more explicitly.
There was a problem hiding this comment.
already resolved
| 1. Open `MCP: List Servers` for connection status (one row per | ||
| server: Running / Stopped / Failed). |
There was a problem hiding this comment.
It looks like the agent cant execute this.
There was a problem hiding this comment.
I dont think there is a need for the user to list the mcp servers manually in the normal case. the agent can do it by themselfes.
For troubleshooting - fine.
There was a problem hiding this comment.
already resolved
Template: - Match Claude/Cursor verbatim where wording had drifted: Step 1 "Once chosen" server rule, Step 2 lead-in, Step 2 error handling, "Available to install" item 3, the Pre-flight live-execution bullet. - Rename the server-key placeholder PACKAGE_ID -> spec.packageName and drop the now-redundant identifier note. - Step 4 inputs example now shows one secret + one non-secret input. - 4a reframed: starting/verifying are user actions; agent asks and acts on what the user reports. - "Currently installed" reads config files directly (no agent-runnable MCP: List Servers); UI status deferred to troubleshooting. Injector: - Trim history-referencing comments per review. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
| "add an MCP", "what can I install" — your FIRST action is to show | ||
| them the catalog so they can pick: | ||
|
|
||
| 1. Resolve server (Server ID`<SERVER_ID>` or URL `JFROG_URL`) |
There was a problem hiding this comment.
Two carried-over typos from the references: missing space in Server ID before <SERVER_ID> here, and line 66 says "not env vars" (should be "no env vars"). They match claude/cursor so byte-equivalence holds, but they're real typos in all three - worth one cleanup pass across the plugins.
Adds scripts/validate-template.mjs and a Validate Template workflow,
mirroring claude-plugin / cursor-plugin which already ship validators.
The test guards the failure mode that recurred 3× on this PR: a
template-filename / read-path mismatch makes the injector silently emit
nothing (it catches the read error and exits 0). Checks:
- injector parses (node --check)
- the templates/<file> the injector reads actually exists and is non-empty
- force-enable emits valid JSON with non-empty hookSpecificOutput.additionalContext
- force-disable emits {}
- hooks.json wires SessionStart to inject-instructions.mjs
Verified it goes red on a simulated filename drift and green once fixed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…idator comments
- Bound `jf config export` with { timeout: 3000 } so it self-limits
instead of relying only on the 7s hook timeout.
- Write {} on the template-read failure path so all fail-closed paths
are uniform.
- Trim validator comments.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…est lint - Wrap checks in a main() entry point. - Group output into Syntax / Lint / Format / Injection logic; split the force-enable check into payload-format vs injection-logic. - Add manifest lint (marketplace.json <-> plugin.json name + version match, source/hooks paths exist), adapted from YhonatanArbel's validation. - Workflow: rename to "Validate hook injection", trigger on the manifest paths the validator now reads, drop the workflow self-reference path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Describe the user-level config as "personal, not committed" and the workspace config as "commit / share", matching the vocabulary Claude and Cursor use for the same scopes. User-level stays the default (installed MCPs follow the user across all workspaces) — only the default choice differs, intentionally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Server-ID resolution (Pre-flight + Step 1) now lists servers with `jf config show --format=json` instead of parsing ~/.jfrog/jfrog-cli.conf.v6; the CLI masks tokens, so the "don't print secrets" caveat is dropped. Picks the server with "isDefault": true. Keeps the two sections consistent. - 4a: drop the meta-narration; add a gate that skips steps 1-3 when the server is already enabled and running; tighten the steps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Jira Ticket Path: https://jfrog-int.atlassian.net/browse/AX-1694
The VS Code MCP-management instructions had drifted from the updated Claude and Cursor agent-guard instructions, and the plugin still shipped them via the legacy platform-specific shell scripts. This PR aligns the template with the same structure and rules as Claude/Cursor and replaces the shell scripts with a single cross-platform Node injector, while preserving the VS Code-native mechanics that intentionally differ from Claude/Cursor.
Changes
scripts/ensure-instructions.shandscripts/ensure-instructions.ps1; addedscripts/inject-instructions.mjs. The injector resolves JFrog credentials (env varsJFROG_URL/JF_URL+ token, falling back to the JFrog CLI's default server viajf config export), checks whether Agent Guard is enabled for the account, and — when enabled — emits the template viahookSpecificOutput.additionalContextfor theSessionStarthook. Honors_JF_AGENT_GUARD_FORCE_DISABLE/JF_AGENT_GUARD_FORCE_ENABLE. Fails closed (emits{}and exits 0) on any error.additionalContext-only. The injector no longer writes a workspace instructions file; the instructions are delivered solely through theSessionStarthook payload, which the IDE consumes directly.hooks.jsonto theSessionStartshape and point it atnode inject-instructions.mjs(timeout 7s).templates/jfrog-mcp-management.md) to match the Claude/Cursor layout: Pre-flight section (live-execution rule, mandatory<PROJECT>, auto-resolvable<SERVER_ID>, network note), catalog-first "Adding an MCP" flow, numbered Steps 1–5 with explicit start+verify (4a) and OAuth login (5), the Listing routing table, and expanded Key Rules / Troubleshooting. Wording that had drifted is now aligned verbatim with the references.inputs+${input:...}substitution + OS-keychain prompt-on-first-start (not shell env-var export), CodeLens /MCP: List Serversmechanics, the real VS Code MCP config locations (workspace.vscode/mcp.jsonand the user-profile.../Code/User/mcp.json), and orphaned-inputscleanup on removal.1.0.4(marketplace.jsonandplugin/.claude-plugin/plugin.json) so the new instructions ship.scripts/validate-template.mjs(run by aValidate Templateworkflow on every PR) asserts the injector parses, force-enable emits valid JSON with a non-emptyhookSpecificOutput.additionalContext, force-disable emits{}, the template the injector reads resolves, andhooks.jsonwiresSessionStartto the injector — guarding the template-filename/read-path drift that recurred during review. Mirrors the validators in claude-plugin/cursor-plugin.Runtime note
For CLI-credential users (no
JFROG_URL/JFROG_ACCESS_TOKENset), the injector spawnsjf config export(bounded by a 3s timeout) plus one settings network call on everySessionStart; env-var users skip thejfspawn. All paths fail closed (emit{}, exit 0).Intentional divergences from Claude/Cursor
These differ on purpose because the IDE requires it or by product decision — they are not drift:
.../Code/User/mcp.json), with the workspace.vscode/mcp.jsonas the "for this project / commit / share" opt-in. Claude/Cursor default to the project file; VS Code defaults to user-level so installed MCPs follow the user across all workspaces.mcp list. Claude/Cursor have CLI list commands (claude mcp list/cursor agent mcp list); VS Code'sMCP: List Serversis UI-only, so "Currently installed" reads the config files directly and defers live status to a user-ask.inputs/${input:...}/keychain model replaces Claude/Cursor's shell${VAR}/${env:VAR}exports entirely.align to:
claude-plugin commit_id: 97e25cc7db106c7fb6e2343968cbfe8fe5e5963a
cursor-plugin commit_id: 72bd39a7c2cec02fea39dbe97e51f039cc4bada7
Tests
Automated:
scripts/validate-template.mjsruns on every PR via theValidate Templateworkflow (verified it goes red on a simulated template-filename drift and green once fixed).Manual: exercised the injector across force-disable / force-enable / env-var creds /
jf config exportdecode / malformed-token / missing-jfpaths — all emit valid JSON and fail closed. Template reviewed section-by-section against the Claude/Cursor references.🤖 Generated with Claude Code