Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{
"name": "jfrog",
"description": "JFrog Platform integration with MCP, security skills, and supply-chain best practices",
"version": "1.0.16",
"version": "1.0.17",
"license": "Apache-2.0",
"source": "plugin",
"categories": [
Expand Down
2 changes: 1 addition & 1 deletion plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "jfrog",
"description": "JFrog Platform integration with MCP, security skills, and supply-chain best practices",
"version": "1.0.16",
"version": "1.0.17",
"license": "Apache-2.0",
"author": {
"name": "JFrog",
Expand Down
2 changes: 2 additions & 0 deletions plugin/skills/jfrog-ai-catalog-skills/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ description: >-
search/browse the catalog, to install/update/uninstall a skill, to see a
skill's versions, or to publish/upload/release a skill to JFrog /
Artifactory / the AI Catalog.
NOT for managing MCP servers (use jfrog-mcp-management) or downloading
packages/artifacts (use jfrog-package-safety-and-download).
metadata:
role: workflow
---
Expand Down
2 changes: 2 additions & 0 deletions plugin/skills/jfrog-mcp-management/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ description: >-
@jfrog/agent-guard), and browse the JFrog MCP catalog. Use whenever the user
wants to add/enable/list/remove/uninstall an MCP server or tool — even without
saying "MCP" — and never install one any other way.
NOT for installing agent skills (use jfrog-ai-catalog-skills) or running JFrog
platform operations such as Artifactory/Xray/AppTrust (use the base jfrog skill).
compatibility: >-
Requires network access to the npm registry and the JFrog platform, and
~/.jfrog/ write access for OAuth login and cache cleanup.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Claude Code-specific config for the `jfrog-mcp-management` skill. Read this
together with [harness-common.md](harness-common.md) (shared entry shape and
success criterion). You reached this file because the harness is Claude Code
(`CLAUDECODE` / `CLAUDE_CODE_ENTRYPOINT`).
(`CLAUDE_CODE_CHILD_SESSION`, or system prompt identifies Claude Code).

## Config files

Expand Down
56 changes: 33 additions & 23 deletions plugin/skills/jfrog-mcp-management/references/harness-common.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,46 @@ plus **exactly one** harness file; do NOT open the others.

## Step A — detect the harness and open ONE file

The `CLAUDECODE` / `CURSOR_*` / `CODEX_*` / `OPENCODE` signals below
mirror `../../jfrog/scripts/check-environment.sh` `detect_harness()`; the
`TERM_PROGRAM=vscode` editor hint is **not** in that script, and Devin is
**not** detected by the script. Each row's signal is **self-contained and
non-overlapping**, so detection does not depend on evaluation order. The VS
Code harness file targets the **VS Code editor** (Copilot MCP support), not
the standalone GitHub Copilot terminal CLI — the CLI (`COPILOT_CLI`) has no
editor UI or `mcp.json`, so it falls through to the Fallback section.

1. Call `../../jfrog/scripts/check-environment.sh` and parse `tool=<name>` from
the User-Agent line. When `tool` is `claude` or `cursor`, that matches the
Claude or Cursor row below — open that harness file. This call also
satisfies the Prerequisites environment check — capture/export
`JFROG_CLI_USER_AGENT` from it here too, rather than calling the script
again later.
2. Otherwise other `tool` values, `unknown`, or a missing `tool` are not enough
— **match this table**. Use how your system prompt identifies you plus any
The session-marker signals below mirror
`../../jfrog/scripts/check-environment.sh` `detect_harness()` (lockstep with
jfrog-cli-core `agentEnvDetectors`); the `TERM_PROGRAM=vscode` editor hint is
**not** in that script, and Devin is **not** detected by the script. Signals can
overlap — when more than one is set, UA / census naming uses the first matching
branch in `detect_harness()` (see the Agent identity table in
`ARCHITECTURE.md` for that precedence; e.g. `GEMINI_CLI` wins over
`CURSOR_AGENT`). The MCP routing table below lists only harnesses that have a
dedicated config file — it is **not** ordered like `detect_harness()`, and must
not be used as UA precedence. The VS Code harness file targets the **VS Code
editor** (Copilot MCP support), not the standalone GitHub Copilot terminal CLI
— the CLI (`COPILOT_CLI` / `COPILOT_AGENT_SESSION_ID`) has no editor UI or
`mcp.json`, so it falls through to the Fallback section.

1. Prefer this table (env + system prompt). On jf ≥ 2.120.0 the skill UA often
omits `tool=` because the CLI emits `ai-agent/<name>` instead — do not rely
on parsing `tool=` alone.
2. Optionally call `../../jfrog/scripts/check-environment.sh <model-slug>` and,
when present, parse `tool=<name>` from the UA (or `ai-agent/<name>` after
`jfrog-cli-go/`). The UA also carries `trigger=skill` (APR hooks use
`trigger=hook` when they spawn `jf`). When the name is `claude`, `cursor`,
or `opencode`, open that harness file. This call also satisfies the
Prerequisites environment check — capture/export `JFROG_CLI_USER_AGENT` and
`JFROG_CLI_AI_MODEL='<model-slug>'` (same slug passed to the script) here
too, rather than calling the script again later.
3. Other `tool` values, `unknown`, or a missing `tool` are not enough —
**match this table**. Use how your system prompt identifies you plus any
environment variables that matching row lists. If row matches → open that file.
Unsure → step 3. Sure none apply → Fallback.
3. If detection is still not conclusive, ASK the user which agent/editor they
Unsure → step 4. Sure none apply → Fallback.
4. If detection is still not conclusive, ASK the user which agent/editor they
are in — do not guess, and do not read multiple harness files.

| Detected harness | Signal (self-contained) | Read THIS file (and no other harness file) |
| --- | --- | --- |
| Claude Code | `CLAUDECODE` or `CLAUDE_CODE_ENTRYPOINT` env var | [harness-claude.md](harness-claude.md) |
| Claude Code | `CLAUDE_CODE_CHILD_SESSION` env var (or system prompt identifies Claude Code) | [harness-claude.md](harness-claude.md) |
| Codex | `CODEX_SANDBOX` / `CODEX_THREAD_ID` / `CODEX_CI` | [harness-codex.md](harness-codex.md) |
| Cursor | `CURSOR_AGENT` / `CURSOR_CLI` / `CURSOR_TRACE_ID` env var | [harness-cursor.md](harness-cursor.md) |
| OpenCode | `OPENCODE` | [harness-opencode.md](harness-opencode.md) |
| Cursor | `CURSOR_AGENT` / `CURSOR_EXTENSION_HOST_ROLE=agent-exec` | [harness-cursor.md](harness-cursor.md) |
| OpenCode | `OPENCODE` / `OPENCODE_SESSION_ID` | [harness-opencode.md](harness-opencode.md) |
| Devin Desktop | Your system prompt / system instructions identify you as **Devin** (Devin Desktop / Devin Local / Cognition). That alone is enough. Optionally confirm with `VSCODE_IPC_HOOK` set to the Devin Desktop IPC socket (full path), e.g. macOS: `~/Library/Application Support/Devin/<version>-main.sock` — the expanded path contains `/Devin/`. The path alone is **not** enough. | [harness-devin.md](harness-devin.md) |
| VS Code editor | `TERM_PROGRAM=vscode` **and no `CURSOR_*` var is set** **and no `OPENCODE` var is set** **and no `CODEX_*` var is set** **and no `CLAUDECODE`/`CLAUDE_CODE_ENTRYPOINT` var is set** **and no `GEMINI_CLI` / `GOOSE_TERMINAL` / `COPILOT_CLI` var is set** **and** your system prompt / system instructions do **not** identify you as Devin | [harness-vscode.md](harness-vscode.md) |
| VS Code editor | `TERM_PROGRAM=vscode` **and no** `CURSOR_AGENT` / `CURSOR_EXTENSION_HOST_ROLE=agent-exec` **and no** `CLAUDE_CODE_CHILD_SESSION` **and no** `OPENCODE` / `OPENCODE_SESSION_ID` **and no** `CODEX_SANDBOX` / `CODEX_THREAD_ID` / `CODEX_CI` **and no** `GEMINI_CLI` / `GOOSE_TERMINAL` / `COPILOT_CLI` / `COPILOT_AGENT_SESSION_ID` **and** your system prompt / system instructions do **not** identify you as Devin | [harness-vscode.md](harness-vscode.md) |
| anything else | none of the above | **Fallback** section below — no harness file exists |

Once you know your harness, use ONLY these fields from its file: `Config files`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Cursor-specific config for the `jfrog-mcp-management` skill. Read this together
with [harness-common.md](harness-common.md) (shared entry shape and success
criterion). You reached this file because the harness is Cursor (`CURSOR_AGENT`
/ `CURSOR_CLI` / `CURSOR_TRACE_ID`).
/ `CURSOR_EXTENSION_HOST_ROLE=agent-exec`).

## Config files

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

OpenCode-specific config for the `jfrog-mcp-management` skill. Read this together
with [harness-common.md](harness-common.md) (shared entry shape and success
criterion). You reached this file because the harness is OpenCode (`OPENCODE`,
set in the environment at startup). This targets all OpenCode surfaces (TUI, CLI,
Desktop, IDE, web) - they share one backend and the same `opencode.json`.
criterion). You reached this file because the harness is OpenCode (`OPENCODE`
and/or `OPENCODE_SESSION_ID` in the environment). This targets all OpenCode
surfaces (TUI, CLI, Desktop, IDE, web) - they share one backend and the same
`opencode.json`.

> **How OpenCode stores the entry:** config is **JSON / JSONC** under the
> top-level **`mcp`** key; each server is a **`type: "local"`** entry whose
Expand Down
64 changes: 57 additions & 7 deletions plugin/skills/jfrog-setup-package-managers/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ description: >-
already has the same repo key. Never pick a repo by discovery; use resolver
output only (unless the user names or asks to browse repos). On unresolved
or failed setup, ask with the failure verbatim — never switch servers.
NOT for installing packages, general Artifactory repo operations (use the base
jfrog skill), or MCP server setup (use jfrog-mcp-management).
metadata:
role: workflow
---
Expand All @@ -20,6 +22,33 @@ then record it in [`.jfrog/local/package-resolution.json`](references/workspace-
`jf setup` writes package-manager-native config (`.npmrc`, `pip.conf`, `uv.toml`, …); the binding
lets the hook re-apply on later sessions.

## At a glance (always-read core)

Every `jf setup` this session:

- **Cover base [`../jfrog/SKILL.md`](../jfrog/SKILL.md) At-a-glance / Tier A**
(Step 0.1) → `<UA>`, `--server-id` placement, single-server, stop-don't-switch.
Prefer full base SKILL.md when you can; Tier B (`cli-gotchas` / `jf-api` / …)
only if the next action needs `jf api` / advanced CLI
- **Always `--repo` + `--server-id`.** `<repoKey>` ← [Step 2](#step-2--get-the-resolved-repo)
(table / binding / global-cache) or user override / unresolved AskQuestion;
never self-discover. `<SID>` ← resolver only (never user-selected)
- **Confirm** before first `jf setup` unless user asked silent / non-interactive
- **Exit 0 → merge binding**; non-zero → stop, surface CLI verbatim, offer
alternate repo or `abort` (2-answer cap)
- **Binding = decisions, not creds** — never write tokens into
`.jfrog/local/package-resolution.json`
- **Unresolved / failed:** ask with failure verbatim — never switch servers
- **Never skip** [Gotchas](#gotchas--hard-rules-never-skip) + base Tier A hard
rules (`../jfrog/SKILL.md` Cautious execution / Server selection / Tier A
gotcha floor). Full `cli-gotchas.md` is Tier B — not required for `jf setup`

Steps: [0](#step-0--read-the-base-skill-then-ensure-jf-is-ready) →
[1](#step-1--identify-package-managers-to-bind) →
[2](#step-2--get-the-resolved-repo) →
[3](#step-3--confirm-run-jf-setup-persist-binding) →
[4](#step-4--load-the-routing-policy)

## Scope (this skill vs session hook)

**Session-start hook:** resolves repo keys per package type, injects the
Expand All @@ -42,11 +71,17 @@ unlisted package manager apply as usual).
- `jf setup` **mutates user state** (`~/.npmrc`, `~/.docker/config.json`, …).
Confirm before the first `jf setup` in a session unless the user explicitly
requests silent/non-interactive setup.
- Reading [`../jfrog/SKILL.md`](../jfrog/SKILL.md) is required — done as Step 0.1 below.
- Covering base At-a-glance / Tier A is required — done as Step 0.1 below.

**Out of scope:** CLI install/login (`../jfrog/references/…`).

## Gotchas
## Gotchas — hard rules (never skip)

**Not tips.** Do/don'ts and known traps for `jf setup` — follow every bullet
before binding. Also honor base **Tier A** hard rules from
[`../jfrog/SKILL.md`](../jfrog/SKILL.md) (Cautious execution, Server selection,
Tier A gotcha floor). Full `cli-gotchas.md` is Tier B — load only if this
session also needs `jf api` / advanced CLI.

- **Always pass `--repo` and `--server-id`** — omitting `--repo` fails when
multiple repos match. See [`jf-setup-command.md`](references/jf-setup-command.md).
Expand All @@ -70,11 +105,13 @@ unlisted package manager apply as usual).

## Step 0 — Read the base skill, then ensure `jf` is ready

1. **Read [`../jfrog/SKILL.md`](../jfrog/SKILL.md) fully first — always, before any
`jf` command, even when `jf` is already configured.** It carries the `jf`
invariants this skill relies on. After reading, run that skill's
*Environment check* (and export `JFROG_CLI_USER_AGENT`) before the first
`jf` call.
1. **Cover base skill At-a-glance / Tier A before the first non-exempt `jf`
(even when `jf` is already configured).** Prefer reading
[`../jfrog/SKILL.md`](../jfrog/SKILL.md) in full when you can; the At-a-glance
Tier A floor is enough for `jf setup` / package-manager binding. Load Tier B
(`cli-gotchas.md`, `jf-api.md`, …) only if the next action needs `jf api` /
advanced CLI. Then run that skill's *Environment check* (and export
`JFROG_CLI_USER_AGENT`) before the first `jf` call.
2. Ensure `jf` + a configured server (`<SID>`). If `jf config show` already
succeeds, skip to Step 1; otherwise:
- **`jf --version`** missing → install per
Expand Down Expand Up @@ -198,3 +235,16 @@ hard rules. Continue the original request using those URLs.
If the command prints nothing, routing is off by config
(`packageResolution.enabled` is not `true`) — an admin opt-in. Report that to
the user and let them decide whether to enable it.

## Before you run `jf setup` — checklist

[At a glance](#at-a-glance-always-read-core) invariants:

- [ ] base At-a-glance / Tier A covered; `<UA>` exported
- [ ] `<repoKey>` ← Step 2 or user override; `<SID>` ← resolver only
- [ ] confirmed (or explicit silent-setup)
- [ ] `jf setup <pm> --server-id <SID> --repo <repoKey>`
- [ ] exit 0 → merge binding (no creds); non-zero → stop + report verbatim;
never switch servers
- [ ] **never skip** Gotchas (this skill) + base Tier A hard rules (full
`cli-gotchas.md` only if Tier B path)
Loading
Loading