@jfrog/opencode-jfrog-plugin 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +105 -51
  2. package/dist/index.js +30 -238
  3. package/package.json +6 -6
  4. package/skills/jfrog/SKILL.md +529 -0
  5. package/skills/jfrog/assets/.gitkeep +0 -0
  6. package/skills/jfrog/references/apptrust-entities.md +154 -0
  7. package/skills/jfrog/references/artifactory-api-gaps.md +206 -0
  8. package/skills/jfrog/references/artifactory-aql-syntax.md +656 -0
  9. package/skills/jfrog/references/artifactory-entities.md +236 -0
  10. package/skills/jfrog/references/artifactory-operations.md +178 -0
  11. package/skills/jfrog/references/catalog-entities.md +219 -0
  12. package/skills/jfrog/references/general-bulk-operations-and-agent-patterns.md +93 -0
  13. package/skills/jfrog/references/general-parallel-execution.md +131 -0
  14. package/skills/jfrog/references/general-use-case-hints.md +27 -0
  15. package/skills/jfrog/references/jfrog-brand-html-report.md +98 -0
  16. package/skills/jfrog/references/jfrog-cli-install-upgrade.md +30 -0
  17. package/skills/jfrog/references/jfrog-entity-index.md +112 -0
  18. package/skills/jfrog/references/jfrog-login-flow.md +132 -0
  19. package/skills/jfrog/references/jfrog-url-references.md +51 -0
  20. package/skills/jfrog/references/onemodel-common-patterns.md +323 -0
  21. package/skills/jfrog/references/onemodel-graphql.md +446 -0
  22. package/skills/jfrog/references/onemodel-query-examples.md +753 -0
  23. package/skills/jfrog/references/platform-access-entities.md +200 -0
  24. package/skills/jfrog/references/platform-admin-api-gaps.md +164 -0
  25. package/skills/jfrog/references/platform-admin-operations.md +58 -0
  26. package/skills/jfrog/references/projects-api.md +241 -0
  27. package/skills/jfrog/references/release-lifecycle-entities.md +180 -0
  28. package/skills/jfrog/references/stored-packages-entities.md +165 -0
  29. package/skills/jfrog/references/xray-entities.md +740 -0
  30. package/skills/jfrog/scripts/check-environment.sh +224 -0
  31. package/skills/jfrog/scripts/jfrog-login-register-session.sh +84 -0
  32. package/skills/jfrog/scripts/jfrog-login-save-credentials.sh +128 -0
  33. package/skills/jfrog-package-safety-and-download/SKILL.md +275 -0
  34. package/sync-skills-vendor.json +5 -0
@@ -0,0 +1,275 @@
1
+ ---
2
+ name: jfrog-package-safety-and-download
3
+ description: >-
4
+ Check JFrog Public Catalog and stored packages for a version, interpret
5
+ catalog security signals, and download through Artifactory (JFrog Platform
6
+ locations, remote cache, curation-aware package managers, or repo proxy).
7
+ Use when the user asks whether a package is safe, allowed, curated, or
8
+ wants to download npm, Maven, PyPI, Go, or similar packages via JFrog.
9
+ Do NOT use for pure CVE or vulnerability lookups (e.g. "details on
10
+ CVE-2021-23337") — those are handled by the jfrog skill's Public security
11
+ domain queries without this workflow.
12
+ metadata:
13
+ role: workflow
14
+ ---
15
+
16
+ # JFrog Package Safety and Download
17
+
18
+ ## Prerequisites
19
+
20
+ - Read `../jfrog/SKILL.md` for JFrog Platform concepts, domain model, CLI setup, and API patterns.
21
+ - **OneModel shapes drift by server version.** Before inventing GraphQL fields or `where` filters, read `../jfrog/references/onemodel-graphql.md` (schema fetch workflow) and `../jfrog/references/onemodel-query-examples.md` (**Public packages**, **Stored packages**). Regenerate or verify queries against `GET "$JFROG_URL/onemodel/api/v1/supergraph/schema"` when examples fail validation.
22
+
23
+ ## Workflow overview
24
+
25
+ ```mermaid
26
+ flowchart TD
27
+ A[User requests package check / download] --> B{Package in Public Catalog?}
28
+ B -->|Yes| C[Get latest version from Catalog]
29
+ B -->|No| D{Package in JFrog Platform Stored Packages?}
30
+ D -->|Yes| E[Get latest version from Stored Packages]
31
+ D -->|No| F[Package not found — stop]
32
+ C --> G{Latest version in JFrog Platform?}
33
+ E --> G
34
+ G -->|Yes| H[Safe — download from JFrog Platform]
35
+ G -->|No| I{Curation entitled?}
36
+ I -->|Yes| J[Check curation policy via API]
37
+ I -->|No| K[Download via remote repo]
38
+ J -->|200 Allowed| K
39
+ J -->|403 Blocked| M[Report curation blocked — stop]
40
+ ```
41
+
42
+ ### Parallelization opportunities
43
+
44
+ Several steps in this workflow are independent and can run in parallel to
45
+ reduce total latency:
46
+
47
+ - **Step 1 + Step 1 fallback**: When package type is known, query both the
48
+ Public Catalog (`getPackage`) and Stored Packages (`getPackage`) in
49
+ parallel. Use whichever returns data; if the Public Catalog returns a hit,
50
+ prefer its `latestVersion` for Step 2.
51
+ - **Step 3 + Step 5**: After determining the version, query stored package
52
+ versions (JFrog Platform check) and curation entitlement
53
+ (`/api/system/version`) in parallel. Both are independent reads — the
54
+ curation result is needed immediately if the JFrog Platform check returns
55
+ empty.
56
+
57
+ When issuing parallel Shell calls, each `jf api` call authenticates
58
+ independently against the active `jf config` server; no shell state needs
59
+ to be passed between calls.
60
+
61
+ ## Step 1: Find the package
62
+
63
+ Search the **Public Catalog** first via OneModel GraphQL, then fall back to
64
+ **Stored Packages** if not found.
65
+
66
+ Execute the query through `jf api` as described in
67
+ `../jfrog/references/onemodel-graphql.md`; refer to
68
+ `../jfrog/references/onemodel-query-examples.md` for concrete query shapes.
69
+
70
+ **When package type is known** (e.g. `npm`, `maven`, `pypi`), use
71
+ `publicPackages.getPackage(type:, name:)` (see *Get a public package*).
72
+ Include the `latestVersion { version }` selection set — `latestVersion` is
73
+ an object, not a scalar.
74
+
75
+ **When type is unknown**, use `publicPackages.searchPackages` with
76
+ `nameContains` (see *Search public packages*). Add `type:` when the user
77
+ narrows the ecosystem.
78
+
79
+ - **Found** → note `type` and `latestVersion.version`. Proceed to Step 2.
80
+ - **Not found** → the package may be 1st/2nd party. Search **Stored Packages**
81
+ using `storedPackages.searchPackages` or `storedPackages.getPackage` (see
82
+ *Stored packages domain* in `onemodel-query-examples.md`). Prefer
83
+ filtering by `type` when known; if not, use `nameContains` alone.
84
+ - **Found** → note `type` and `latestVersionName` (or derive a version from
85
+ `versionsConnection`). Proceed to Step 2.
86
+ - **Not found in either** → report "package not found" and stop.
87
+
88
+ If multiple results with different `type` values, ask the user which package
89
+ type they mean.
90
+
91
+ ## Step 2: Determine latest version
92
+
93
+ | Source | Version field |
94
+ |--------|--------------|
95
+ | Public Catalog | `latestVersion.version` (object selection required) |
96
+ | JFrog Platform Stored Packages | `latestVersionName` on `StoredPackage`, or highest entry from `versionsConnection` |
97
+
98
+ ## Step 3: Check if package + latest version exists in JFrog Platform
99
+
100
+ Query stored package versions using `storedPackages.searchPackageVersions`
101
+ with a `hasPackageWith` filter (see `../jfrog/references/onemodel-query-examples.md`
102
+ → *Search stored package versions*). Add a `version` filter for the specific
103
+ version from Step 2, and request `locationsConnection` to get repository
104
+ details (`repositoryKey`, `repositoryType`, `leadArtifactPath`).
105
+
106
+ Execute the query through `jf api` (see
107
+ `../jfrog/references/onemodel-graphql.md` for the invocation pattern).
108
+
109
+ - **Found with locations** → package is in the JFrog Platform. Report as **safe to
110
+ download**. Proceed to Step 4.
111
+ - **Not found** → proceed to Step 5.
112
+
113
+ ## Step 4: Download from JFrog Platform
114
+
115
+ Use the location info from Step 3. Binary artifact downloads go through
116
+ `jf rt dl` — **not** `jf api`. `jf api` is the unified entry point for the
117
+ JFrog REST APIs (metadata, admin, curation, etc.) and does not expose the
118
+ `-L` / `-o` flags needed to stream binary content through a redirect chain.
119
+
120
+ **`<target>` must be a full file path** (e.g.
121
+ `./downloads/lodash-4.18.1.tgz`), not a bare directory. `jf rt dl --flat`
122
+ treats the target as a file name; passing a directory causes a misleading
123
+ "open path: is a directory" error.
124
+
125
+ | `repositoryType` | Strategy |
126
+ |-------------------|----------|
127
+ | `local` or `federated` | `jf rt dl "<repositoryKey>/<leadArtifactPath>" <target-file> --flat` |
128
+ | `remote` | `jf rt dl` against the **base** remote repo (strip any trailing `-cache`) — it transparently triggers the remote fetch when the artifact is not yet cached |
129
+
130
+ **local / federated / remote download:**
131
+
132
+ ```bash
133
+ jf rt dl "<baseRepoKey>/<leadArtifactPath>" <target-file> --flat
134
+ ```
135
+
136
+ **Resolving the remote repo key:** The `repositoryKey` returned by OneModel
137
+ for remote locations often already ends in `-cache` (e.g.
138
+ `devNPM-remote-cache`). `jf rt dl` needs the **base remote repo name**
139
+ (without `-cache`). Strip the `-cache` suffix when present (e.g.
140
+ `devNPM-remote-cache` → `devNPM-remote`). If the key does not end in
141
+ `-cache`, use it as-is.
142
+
143
+ See the **Protocol endpoints** table below for the package-type-specific
144
+ path format inside the repo.
145
+
146
+ ## Step 5: Check curation entitlement
147
+
148
+ ```bash
149
+ jf api /artifactory/api/system/version \
150
+ | jq '.addons | index("curation") != null'
151
+ ```
152
+
153
+ - `true` → curation is entitled. Proceed to Step 6a.
154
+ - `false` → curation not available. Proceed to Step 6b.
155
+
156
+ ## Step 6a: Check curation policy and download
157
+
158
+ When curation is entitled, use the Xray curation API to check whether the
159
+ package version is allowed across all repositories before downloading.
160
+
161
+ ```bash
162
+ RESPONSE_FILE="/tmp/curation-status-$$.json"
163
+ PAYLOAD_FILE="/tmp/curation-payload-$$.json"
164
+ STDERR_FILE="/tmp/curation-err-$$.log"
165
+
166
+ jq -n \
167
+ --arg type "<TYPE>" \
168
+ --arg name "<NAME>" \
169
+ --arg version "<VERSION>" \
170
+ '{packageType:$type, packageName:$name, packageVersion:$version}' \
171
+ > "$PAYLOAD_FILE"
172
+
173
+ set +e
174
+ jf api /xray/api/v1/curation/package_status/all_repos \
175
+ -X POST -H "Content-Type: application/json" \
176
+ --input "$PAYLOAD_FILE" \
177
+ > "$RESPONSE_FILE" 2> "$STDERR_FILE"
178
+ RC=$?
179
+ set -e
180
+ echo "RC=$RC"; echo "$RESPONSE_FILE"
181
+ ```
182
+
183
+ Supported `packageType` values: `npm`, `pypi`, `maven`, `go`, `nuget`,
184
+ `docker`, `gradle`.
185
+
186
+ **Interpreting the result with `jf api`**: unlike plain `curl`, `jf api`
187
+ surfaces the HTTP result through its **exit code** and a
188
+ `"<hh:mm:ss> [Warn] ... returned 4xx/5xx"` line on **stderr** (not a
189
+ `%{http_code}` suffix in stdout). The response body is always written to
190
+ stdout. Parse both:
191
+
192
+ ```bash
193
+ if [ "$RC" -eq 0 ]; then
194
+ echo "Package is allowed by curation."
195
+ elif grep -q 'returned 403' "$STDERR_FILE"; then
196
+ echo "Blocked by curation policy:"
197
+ cat "$RESPONSE_FILE"
198
+ else
199
+ echo "Curation check failed (rc=$RC):"
200
+ cat "$STDERR_FILE"
201
+ fi
202
+ ```
203
+
204
+ **Evaluate the outcome:**
205
+
206
+ - **exit 0** → package is **allowed** by curation policy. Proceed to
207
+ download via a remote repo (same as Step 6b).
208
+ - **`returned 403` on stderr** → package is **blocked** by a curation
209
+ policy. The response body explains which policy rule blocked it. Report
210
+ the block reason to the user and stop — do not attempt to download.
211
+ - **Any other non-zero exit** → treat as an operational failure (auth, DNS,
212
+ endpoint disabled) and report.
213
+
214
+ ## Step 6b: Download without curation
215
+
216
+ When curation is not entitled and the package is not in the JFrog Platform,
217
+ download directly through a remote repo.
218
+
219
+ 1. **Find a remote repo** of the right package type:
220
+
221
+ ```bash
222
+ jf api \
223
+ "/artifactory/api/repositories?type=remote&packageType=<TYPE>" \
224
+ | jq '.[].key'
225
+ ```
226
+
227
+ 2. **Download** — use `jf rt dl` against the base remote repo (without
228
+ `-cache`); it handles both cached and uncached artifacts:
229
+
230
+ ```bash
231
+ jf rt dl "<repo>/<artifact-path>" <target-file> --flat
232
+ ```
233
+
234
+ ## Artifact paths by package type
235
+
236
+ Use these path patterns when `leadArtifactPath` is not available from
237
+ OneModel. The leading `<repo>/` is the base repo key you pass to `jf rt dl`.
238
+
239
+ | Type | `jf rt dl` target pattern |
240
+ |--------|-------------------------------------------------------------------------|
241
+ | `npm` | `<repo>/<pkg>/-/<pkg>-<version>.tgz` |
242
+ | `pypi` | `<repo>/<pkg>/<version>/<pkg>-<version>.tar.gz` |
243
+ | `maven`| `<repo>/<group-path>/<artifact>/<version>/<artifact>-<version>.jar` |
244
+ | `go` | `<repo>/<module>/@v/<version>.zip` |
245
+
246
+ ## Gotchas
247
+
248
+ - **Binary downloads vs. `jf api`**: `jf api` is for REST APIs, not binary
249
+ content. It does not follow redirects transparently into a binary payload
250
+ and does not expose `-L` / `-o`. Always use `jf rt dl` (against the base
251
+ remote repo, not the `-cache` one) for the actual artifact download.
252
+ - **`jf rt dl` and uncached remotes**: `jf rt dl "<remote>/<path>"` —
253
+ targeting the **base** remote repo rather than `<remote>-cache/<path>` —
254
+ transparently triggers the remote fetch and caches the artifact. Do not
255
+ try to pre-query the proxy via `jf api`.
256
+ - **`jf rt dl --flat` target must be a file path**: When downloading a
257
+ single artifact, pass a full output **file** path (e.g.
258
+ `./downloads/lodash-4.18.1.tgz`), not a directory. The CLI opens the target
259
+ path as a file; a directory causes a cryptic "open path: is a directory"
260
+ error that retries four times before failing. Derive the filename from
261
+ `leadArtifactPath` (take the segment after the last `/`).
262
+ - **Package type detection**: If the user doesn't specify the package type,
263
+ the Public Catalog search by name alone may return multiple types. Ask the
264
+ user to disambiguate before proceeding.
265
+ - **Curation endpoint lives under Xray**: use
266
+ `/xray/api/v1/curation/package_status/all_repos` (via `jf api`). Do not
267
+ prefix it with `/artifactory`.
268
+ - **Curation result discrimination with `jf api`**: the 200/403 signal comes
269
+ from `jf api`'s **exit code** plus a `returned NNN` line on **stderr**,
270
+ not from a `%{http_code}` appended to stdout. Capture stderr to a file
271
+ (`2> "$STDERR_FILE"`) and branch on `RC` + `grep 'returned 403'` as shown
272
+ in Step 6a.
273
+ - **Curation API package type values**: Must be lowercase and match one of
274
+ `npm`, `pypi`, `maven`, `go`, `nuget`, `docker`, `gradle`. Other values
275
+ will return an error.
@@ -0,0 +1,5 @@
1
+ {
2
+ "repo": "jfrog/jfrog-skills",
3
+ "pin": "v0.14.0",
4
+ "paths": ["skills"]
5
+ }