Skip to content

Commit acb7e89

Browse files
[patch] chore: sync skills to v0.24.0
1 parent 7ec9222 commit acb7e89

73 files changed

Lines changed: 7484 additions & 1644 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

skills/jfrog-init/SKILL.md

Lines changed: 593 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Running everything at once — jfrog-detect-all.mjs
2+
3+
`node scripts/jfrog-detect-all.mjs [server-id] [project-key]` runs Steps 1–7
4+
in order and stops at the first non-green result — except Step 5 going
5+
red/error, Step 6 going red (ambiguous/404/403), and Step 7 going red
6+
in either of its two non-blocking shapes (exit 1: catalog not hosted /
7+
unreachable / 5xx, or exit 4: reachable but not entitled), all of which
8+
are non-blocking: Steps 1-4 passing is what "green" means here,
9+
and the MCP-plugin, project-resolution, and catalog-availability gaps
10+
are each reported as separate signals. This script makes exactly one
11+
project-resolution attempt per invocation and has no way to tell a
12+
first attempt from a last one, so it always treats a Step 6 red as
13+
non-blocking — the interactive walk (see Step 6 in `SKILL.md`) is what
14+
enforces the one-retry cap before giving up. Steps 5's, 6's, and 7's own
15+
`ask`/`error` outcomes (ambiguous server-id, no project input passed,
16+
`jf` missing/credentials rejected) still block, same as every other
17+
step's genuine stop. If no project key is passed, Step 6 emits `ask`
18+
with candidates and the walk halts; the caller re-invokes with the
19+
picked project as arg 2 — unless that `ask` carries `"unresolved":
20+
"server"`, in which case it's a server pick (see Step 6's branches) and
21+
the re-invocation picks server-id (arg 1) instead.
22+
23+
Exit 0 = Steps 1-4 green (MCP configured or not, project resolved
24+
or not, catalog entitled or not); exit 1 = something needs fixing. The
25+
final JSON line adds `mcpConfigured: true|false`, `projectResolved:
26+
true|false`, and `catalogEntitled: true|false` so a caller can tell the
27+
exit-0 cases apart — plus `catalogReason: "unreachable" | "not_entitled"`
28+
whenever `catalogEntitled` is `false`, so the Final Summary can name the
29+
specific gap instead of a generic one. Writes the `~/.jfrog/setup.json`
30+
state-file hint whenever Steps 1-4 are green, **regardless of
31+
`projectResolved`, `mcpConfigured`, or `catalogEntitled`** — the server
32+
and JPD URL are worth remembering on their own, independent of whether
33+
a project got picked, the MCP plugin is wired up, or the AI Catalog is
34+
reachable/the user is entitled to it. An unresolved project is passed
35+
to `jfrog-state-file.mjs` as an empty key, which leaves any previously
36+
recorded `currentActiveProject` alone rather than erasing it (see
37+
`jfrog-state-file.mjs`); it's never written as a fresh, unvalidated
38+
value.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Step 7 — AI Catalog reachable & entitled: mechanics and branches
2+
3+
Two sub-checks against
4+
`<JPD>/ml/core/api/v1/mcp-registry/ml-projects?pageSize=1` (where
5+
`<JPD>` is the URL stored in `jf config` for the resolved server —
6+
this skill never uses a separate `JFROG_PLATFORM_URL` env var), both
7+
must pass. This step is **purely about AI Catalog access** — no
8+
runtime checks (Node lives in Step 1; `uv` / `docker` are per-MCP
9+
concerns, not this skill's).
10+
11+
1. **Anonymous** GET — proves the endpoint is deployed at this JPD.
12+
`2xx/401/403/405/406` = up; `404` / connection failure = red.
13+
2. **Authenticated** GET to the same path, with the bearer token (or
14+
user+password) extracted from `jf config export` — same credential
15+
source `jf` itself uses (token / user+password / SSO refresh,
16+
whatever's stored), so the skill never asks for or invents
17+
credentials, and the token only lives in memory for this one
18+
request. `2xx` = user is **entitled** to read the AI Catalog on
19+
this JPD; `403` = reachable but **not entitled**, non-blocking.
20+
`401` means the credentials themselves were rejected — that says
21+
nothing about entitlement, so it is treated as a blocking error
22+
instead (see Exit 3 below).
23+
24+
Splitting reachability from entitlement produces two distinct
25+
outcomes: check 1 red = "this JPD doesn't host AI Catalog, or it's
26+
unreachable right now"; check 2's `403` = "catalog is up but your
27+
user isn't entitled." Neither is a setup failure — both are
28+
non-blocking permissions/availability gaps the rest of the walk doesn't
29+
depend on (see the exit-code branches below). Check 2's `401` is
30+
different — it means `jf`'s own credentials are invalid or expired,
31+
which is a genuine setup problem (Exit 3).
32+
33+
**Required branches:**
34+
35+
- **Exit 0 (green)** → done. All checks pass, including entitlement.
36+
- **Exit 1 (red)** → anon probe 404 / connection failure / 5xx — the
37+
platform may not host AI Catalog, or it's unreachable right now.
38+
**Non-blocking** — same reasoning as Exit 4 below: Steps 1-4 are
39+
this skill's core prerequisites, and none of them depend on the AI
40+
Catalog being present. Proceed to the Final Summary, but append a
41+
note naming the gap (`catalogReason: "unreachable"` in
42+
`jfrog-detect-all.mjs`'s summary — see `batch-walk.md`).
43+
- **Exit 2 (ask)** → multiple servers configured, none marked
44+
`isDefault`, no server-id passed. Same handling as Step 4's exit 2:
45+
**stop and read `references/server-picker.md` in full**, then
46+
re-invoke Step 7 with the pick as either the positional argument or
47+
`JF_SERVER_ID`.
48+
- **Exit 3 (error)**`jf` missing, the authed probe returned `401`
49+
(credentials themselves rejected — re-run `jf config add
50+
--interactive`), or an unexpected HTTP code (e.g. a broken `jf`
51+
config surfacing here instead of at Step 4). This is the one genuine
52+
stop this step has — a real error, not a "catalog isn't available"
53+
gap.
54+
- **Exit 4 (not entitled)** → catalog is reachable but the authed probe
55+
returned `403`. **Non-blocking** — proceed to the Final Summary, but
56+
append the entitlement note (`catalogReason:
57+
"not_entitled"`). The detector's `detail` names the specific endpoint
58+
path (`/ml/core/api/v1/mcp-registry`) and the role the admin needs to
59+
grant (typically "AI Catalog Read" or "Application Admin"), so the
60+
user can forward an actionable request rather than a shrug.
61+
62+
Exit 1 and Exit 4 are deliberately handled the same way at the walk
63+
level (see `batch-walk.md`) — both leave `catalogEntitled: false`, and
64+
only differ in `catalogReason`, so the Final Summary can say "no AI
65+
Catalog here" vs. "you're not entitled" accurately instead of collapsing
66+
both into one generic gap.
67+
68+
**Never** grant a role or invent a project.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# /jfrog-init — full flow diagram
2+
3+
Visual companion to the numbered Steps in `SKILL.md`. Every decision
4+
node here is also fully documented — including the exact user-facing
5+
wording — in the corresponding Step section of `SKILL.md`; this diagram
6+
adds nothing new, it's a compressed map of that same prose for
7+
at-a-glance orientation. `SKILL.md`'s Step-by-step text is the
8+
authoritative source for wording and behavior — follow it literally.
9+
10+
```mermaid
11+
flowchart TD
12+
Start(["/jfrog-init"]) --> S1
13+
14+
S1["1. Node.js >= 18 installed? (no script — node --version / npx --version)"]:::stepBox
15+
S1 -->|no| ASKNODE["AskUserQuestion: Install Node.js now? Yes/No"]:::fixBox
16+
ASKNODE -->|Yes, macOS/Linux| NVMINSTALL["Install nvm (pinned version) + nvm install --lts"]:::autoBox
17+
ASKNODE -->|Yes, Windows| WINGETNODE["winget install OpenJS.NodeJS.LTS"]:::autoBox
18+
ASKNODE -->|No| STOP0["STOP: cannot proceed without Node"]:::stopBox
19+
NVMINSTALL -->|failed| F1["Fall back: ask user to install Node.js >= 18 manually"]:::fixBox
20+
NVMINSTALL -->|ok| S2
21+
WINGETNODE --> F1W["Tell user: open a new terminal, re-run /jfrog-init"]:::fixBox
22+
S1 -->|yes| S2
23+
24+
S2["2. jf CLI installed and >= 2.106.0?"]:::stepBox
25+
S2 -->|missing| ASKJF["AskUserQuestion: Install JFrog CLI? Yes/No"]:::fixBox
26+
S2 -->|outdated| ASKJFU["AskUserQuestion: Update JFrog CLI? Yes/No"]:::fixBox
27+
ASKJF -->|Yes| INSTJF["jfrog-install-jf-cli.mjs: Plan A npm install -g jfrog-cli-v2-jf"]:::autoBox
28+
ASKJFU -->|Yes| INSTJF
29+
ASKJF -->|No| STOP0J["STOP: cannot proceed without jf"]:::stopBox
30+
ASKJFU -->|No| STOP0J
31+
INSTJF -->|npm exited 0, but resolving jf is shadowed by an earlier install on PATH| SHADOW["Report shadowing — move npm's bin ahead on PATH, or remove the other install"]:::fixBox
32+
SHADOW --> PLANC
33+
INSTJF -->|npm failed, or exited 0 but jf still isn't resolving up to date and not shadowed, and a private registry is configured| PLANB["Plan B: retry npm install against the public registry"]:::autoBox
34+
PLANB -->|jf now resolves up to date| S2RE
35+
PLANB -->|still not up to date| PLANC
36+
INSTJF -->|npm missing, or Plan A/B failed to leave an up-to-date jf on PATH| PLANC["Plan C: direct binary download to ~/.jfrog/bin, checksum-verified, runs jf --version to confirm"]:::autoBox
37+
PLANC -->|Windows| WINPS["Print PowerShell one-liner — user runs it themselves, then re-runs /jfrog-init"]:::fixBox
38+
PLANC -->|macOS/Linux| S2RE
39+
INSTJF -->|npm succeeded and jf now resolves >= 2.106.0| S2RE["Re-check: installed and >= 2.106.0?"]:::stepBox
40+
S2RE -->|still missing/outdated| STOP1["STOP: show raw install error"]:::stopBox
41+
S2RE -->|ok| S3
42+
S2 -->|yes| S3
43+
44+
S3["3. jf connected to a server?"]:::stepBox
45+
S3 -->|no| ASKMETHOD["AskUserQuestion: Web login or Access token?"]:::fixBox
46+
ASKMETHOD -->|Web login| WEBLOGIN["Register session, show code/link, retrieve + save credentials — all in-session, this skill's own local scripts"]:::autoBox
47+
WEBLOGIN --> S3ASKW["AskUserQuestion: Did you finish logging in? Yes/No"]:::fixBox
48+
S3ASKW -->|Yes| S3
49+
S3ASKW -->|No| STOP0B["STOP: user cancelled"]:::stopBox
50+
ASKMETHOD -->|Access token| F3["Print one command, --url pre-filled — user runs it themselves in their own terminal, pastes the token"]:::fixBox
51+
F3 --> S3ASK["AskUserQuestion: Did you finish running that command? Yes/No"]:::fixBox
52+
S3ASK -->|Yes| S3
53+
S3ASK -->|No| STOP0B
54+
S3 -->|yes| S4
55+
56+
S4["4. Server reachable and credentials valid?"]:::stepBox
57+
S4 -->|multiple servers, no default| ASKSRV["AskUserQuestion: pick server-id"]:::fixBox
58+
ASKSRV --> S4
59+
S4 -->|reachable, but token invalid/expired| F4["Print one command, --url and --server-id pre-filled (token-only, no web option — avoids a duplicate server) — user runs it themselves"]:::fixBox
60+
F4 --> S4ASK["AskUserQuestion: Did you finish running that command? Yes/No"]:::fixBox
61+
S4ASK -->|Yes| S4
62+
S4ASK -->|No| STOP0C["STOP: user cancelled"]:::stopBox
63+
S4 -->|unreachable/timeout/other| STOP2["STOP: show raw error (network/URL hint included)"]:::stopBox
64+
S4 -->|yes| S5
65+
66+
S5["5. Plugin mcp.json has mcpServers.jfrog? (auto-substitutes a JFROG_PLATFORM_URL/JFROG_URL placeholder inline, if present)"]:::stepBox
67+
S5 -->|substitution needed, server-id ambiguous| ASKSRV5["AskUserQuestion: pick server-id"]:::fixBox
68+
ASKSRV5 --> S5
69+
S5 -->|missing/invalid/no entry, incl. substitution failure| F5["Note: reinstall or update the JFrog plugin, or resolve jf config (non-blocking)"]:::fixBox
70+
F5 --> S6
71+
S5 -->|yes, valid url| S6
72+
73+
S6["6. Project resolved?"]:::stepBox
74+
S6 -->|state file has current project| ASKREUSE["AskUserQuestion: reuse CURRENT or pick different"]:::fixBox
75+
ASKREUSE -->|reuse| VALPROJ["Validate via authenticated GET /access/api/v1/projects/KEY"]:::stepBox
76+
ASKREUSE -->|different| ASKPROJ["AskUserQuestion: first 2 projects, or Other to type one"]:::fixBox
77+
S6 -->|no state file| ASKPROJ
78+
ASKPROJ --> RESOLVE["Resolve name-or-key (case-insensitive) against project list from authenticated GET /access/api/v1/projects"]:::stepBox
79+
RESOLVE -->|no match, 1st attempt| ASKPROJ
80+
RESOLVE -->|no match again, 2nd attempt: give up| F6
81+
RESOLVE -->|matched| VALPROJ
82+
VALPROJ -->|404 or 403, 1st attempt| ASKPROJ
83+
VALPROJ -->|404 or 403 again, 2nd attempt: give up| F6
84+
VALPROJ -->|401, credentials rejected| STOPCREDS["STOP: show raw error (re-auth via the Step 3/4 picker)"]:::stopBox
85+
VALPROJ -->|2xx| S7
86+
87+
F6["Note: no project resolved after 1 retry — continue without one (non-blocking)"]:::fixBox
88+
F6 --> S7
89+
90+
S7["7. AI Catalog reachable and user entitled?"]:::stepBox
91+
S7 -->|anon 404 / connection failure / 5xx, exit 1| F7U["Note: catalogReason=unreachable — JPD may not host AI Catalog, or it's down right now (non-blocking)"]:::fixBox
92+
F7U --> WRITE
93+
S7 -->|authed 401 or 403, not entitled, exit 4| F7E["Note: catalogReason=not_entitled — ask JFrog admin for AI Catalog Read role (non-blocking)"]:::fixBox
94+
F7E --> WRITE
95+
S7 -->|ambiguous server-id, exit 2| ASKSRV7["AskUserQuestion: which jf server? (server-picker.md), then re-run"]:::fixBox
96+
ASKSRV7 --> S7
97+
S7 -->|jf missing / credentials rejected / unexpected response shape, exit 3| STOP7["STOP: show raw error — no state file written"]:::stopBox
98+
S7 -->|yes, entitled, exit 0| WRITE["Write state file: server, jpdUrl, and currentActiveProject if resolved (else previous project, if any, is kept) — written on every NON-blocking path out of Step 7"]:::autoBox
99+
100+
WRITE --> S8CHECK{"Step 7 green AND harness == Claude Code? (detectHarness() reused from Step 5)"}:::stepBox
101+
S8CHECK -->|no| DONE
102+
S8CHECK -->|yes| S8["8. Claude agent-plugin marketplace registered?"]:::stepBox
103+
S8 -->|exit 0, success| F8OK["Reply: Added the JFrog marketplace ... — trailing sentence after Final Summary"]:::autoBox
104+
S8 -->|exit 1 or 3, failed| DONE
105+
F8OK --> DONE
106+
107+
DONE(["JFrog init complete"]):::doneBox
108+
109+
classDef stepBox fill:#e8f0fe,stroke:#1a73e8,color:#000
110+
classDef fixBox fill:#fff4e5,stroke:#f9a825,color:#000
111+
classDef autoBox fill:#e6f4ea,stroke:#137333,color:#000
112+
classDef doneBox fill:#e6f4ea,stroke:#137333,color:#000
113+
classDef stopBox fill:#fce8e6,stroke:#c5221f,color:#000
114+
```
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# jfrog-install-jf-cli.mjs — installation internals
2+
3+
Background for Step 2 of `/jfrog-init` (`SKILL.md`). The model doesn't
4+
need this to execute the step — `jfrog-install-jf-cli.mjs` handles all
5+
of it and reports success/failure on stdout and its exit code — but it
6+
explains what the script actually does, for debugging or when a user
7+
asks how the install works.
8+
9+
**Deliberately does not use** the base skill's
10+
[`../jfrog/references/jfrog-cli-install-upgrade.md`](../../jfrog/references/jfrog-cli-install-upgrade.md)
11+
(`brew install jfrog-cli` / a Linux-only curl one-liner, no Windows
12+
guidance). This walk's primary method is one command that behaves
13+
identically across macOS, Linux, and Windows without branching on OS —
14+
`npm install -g jfrog-cli-v2-jf` — so it uses that instead. If npm
15+
itself can't complete the install (missing, or a permissions error like
16+
a global prefix that needs `sudo`), the script falls back to a
17+
checksum-verified direct binary download with its own Windows handling.
18+
19+
`jfrog-install-jf-cli.mjs` tries progressively more self-contained
20+
install methods, falling through only when one genuinely fails:
21+
22+
1. **Plan A — npm** (JFrog's own documented method:
23+
docs.jfrog.com/integrations/docs/download-and-install-the-jfrog-cli#npm):
24+
`npm install -g jfrog-cli-v2-jf` against whatever registry npm is
25+
already configured for. No PATH/shell-rc changes here: npm's global
26+
bin directory is expected to already be on PATH. This works
27+
identically on macOS, Linux, and Windows, so there's no OS-specific
28+
branch for this plan.
29+
2. **Plan B — public registry retry**: triggered whenever Plan A's `npm`
30+
command itself fails, *or* it exits 0 but the `jf` that resolves on
31+
PATH afterward still isn't at the required version — provided that
32+
stale `jf` is npm's own install and not a different, older `jf`
33+
earlier on PATH shadowing it. Shadowing is reported directly and
34+
skips straight to Plan C instead: retrying against a different
35+
registry can't fix a PATH-ordering problem. If npm is configured for
36+
a registry other than the
37+
public one (common on a company machine, pointed at a
38+
private/corporate mirror), the exact same install is retried with
39+
`--registry=https://registry.npmjs.org/` — this one command only,
40+
never touching the user's saved npm config. `jfrog-cli-v2-jf` is a
41+
public package, so a private registry's own (possibly stale) auth
42+
says nothing about whether the package itself is reachable.
43+
3. **Plan C — direct binary download**: if npm is missing, or both A
44+
and B failed for any other reason (observed in practice: a global
45+
npm prefix that requires `sudo`), downloads the first-party `jf`
46+
binary from `releases.jfrog.io` straight to `~/.jfrog/bin` — a
47+
user-owned prefix that never needs elevated permissions — and
48+
verifies it against the SHA-256 checksum Artifactory reports for that
49+
same artifact (catches a truncated/corrupted transfer, not an
50+
independent signature). Unlike Plans A/B, `~/.jfrog/bin` isn't on
51+
PATH by default, so a successful Plan C also appends a PATH line to
52+
the user's shell rc file (idempotent) and prints one for the caller
53+
to `eval` immediately, so `jf` resolves both in future terminals and
54+
in the *current* process without the user doing anything.
55+
**Windows**: Plan C's direct-download path isn't reliable there, so
56+
it instead prints a PowerShell one-liner — installing to a user-owned
57+
path and prepending to the user-scope `Path` via
58+
`[Environment]::SetEnvironmentVariable(..., 'User')`, no elevation
59+
needed. Reads the existing user-scope value first rather than using
60+
`setx PATH "...;$env:Path"`, which would copy the *combined*
61+
machine+user PATH into the user variable (duplicating every
62+
machine-level entry into it, permanently) and silently truncate past
63+
`setx`'s 1024-character limit. The whole script exits 1 so Step 2 can
64+
relay it to the user.
65+
66+
Only if all three plans fail does the script print the plain
67+
`npm install -g jfrog-cli-v2-jf` command and exit 1, for the user to
68+
diagnose and run themselves.
69+
70+
**Known trade-off of Plans A/B, called out in JFrog's own docs and not
71+
something this script can detect or fix**: if the user relies on a
72+
shim-based version manager (`nvm` / Volta) alongside another `jf`
73+
install (Homebrew, curl, or Plan C itself), the version manager's
74+
`bin/` takes PATH priority, so the npm-installed `jf` silently wins
75+
regardless of what those other installs report.

0 commit comments

Comments
 (0)