@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,446 @@
1
+ # OneModel GraphQL (JFrog Platform)
2
+
3
+ Run OneModel GraphQL queries against the JFrog Platform to fetch information
4
+ about applications, release bundles, artifacts, builds, evidence, packages,
5
+ catalog data, and more through the unified OneModel endpoint.
6
+
7
+ **When to read this file:** Any OneModel GraphQL query, schema discovery, or
8
+ when the user asks to list or search platform entities via GraphQL. For
9
+ domain-specific query shapes, read `onemodel-query-examples.md`. For
10
+ pagination, variables, and date formatting, read `onemodel-common-patterns.md`.
11
+
12
+ In examples below, `<skill_path>` is this skill's directory (parent of
13
+ `references/`).
14
+
15
+ ## `~/.jfrog/skills-cache/` policy
16
+
17
+ The skill cache lives under `${JFROG_CLI_HOME_DIR:-$HOME/.jfrog}/skills-cache/`
18
+ (co-located with `jf config`, **not** inside the installed skill tree). It holds
19
+ **only**:
20
+
21
+ 1. **`onemodel-schema-${JFROG_SERVER_ID}.graphql`** — this workflow (supergraph
22
+ SDL cache). **Always** use the path in [Fetch the schema](#2-fetch-the-schema);
23
+ do not mirror the schema under `/tmp`.
24
+ 2. **`jfrog-skill-state.json`** — environment check (see main SKILL.md); scripts
25
+ manage it; do not delete or replace it casually.
26
+
27
+ **Never** store GraphQL **query responses**, REST bodies, reports, or other
28
+ scratch files under `skills-cache/`. For responses, use `/tmp` with a unique name
29
+ (`$$`, `mktemp -d`) as in [Execute the query](#6-execute-the-query) — the
30
+ example `RESPONSE_FILE` paths must stay outside `skills-cache/`.
31
+
32
+ ## Prerequisites
33
+
34
+ - **JFrog CLI** (`jf`) configured with at least one server — follow the main
35
+ SKILL.md environment check and **Server selection rules** before querying.
36
+ - **Artifactory 7.104.1+** — OneModel GraphQL requires this minimum version.
37
+ - **`jq`** on `PATH` (same as the base skill). HTTP calls go through
38
+ `jf api`; no standalone `curl` is needed.
39
+
40
+ ## Workflow
41
+
42
+ Follow these steps in order. Skipping the schema fetch (step 2) is the most
43
+ common source of errors — queries built from assumptions or cached knowledge
44
+ will fail on servers whose schema differs from what you expect.
45
+
46
+ 1. **Resolve the target server** — derive `JFROG_SERVER_ID` from `jf config`
47
+ 2. **Fetch the schema** — always fetch the supergraph schema from the server
48
+ 3. **Understand the query intent** — map the user's request to domains and types
49
+ 4. **Construct the GraphQL query** — build from the resolved schema only
50
+ 5. **Validate the query against the schema** — verify every field and type
51
+ 6. **Execute the query** — POST to the OneModel endpoint; save response to a file
52
+ 7. **Handle the response** — paginate if needed; present results clearly
53
+
54
+ ### 1. Resolve the target server
55
+
56
+ Authentication is handled automatically by `jf api` against the active (or
57
+ `--server-id`-specified) server. You only need the server-id locally — for
58
+ caching the schema file per server. Derive it from `jf config`:
59
+
60
+ ```bash
61
+ # User-specified server:
62
+ JFROG_SERVER_ID="<server-id>"
63
+
64
+ # Or the current default:
65
+ JFROG_SERVER_ID=$(jf config show --server-id 2>/dev/null \
66
+ || jf config export | base64 -d | jq -r '.servers[] | select(.isDefault==true).serverId')
67
+ ```
68
+
69
+ If the user named a specific server, pass `--server-id "$JFROG_SERVER_ID"` to
70
+ every `jf api` invocation in steps 2 and 6 so the query hits that server
71
+ (see SKILL.md § *Server selection rules*).
72
+
73
+ ### 2. Fetch the schema
74
+
75
+ **This step is mandatory for custom or novel queries.** You need the supergraph
76
+ schema from the specific JFrog server you are working with.
77
+
78
+ #### Shortcut for well-known query patterns
79
+
80
+ When using a query shape that comes directly from `onemodel-query-examples.md`
81
+ **without modifications** (same fields, same filters, same argument types), you
82
+ may skip the full schema fetch and execute immediately. The example queries in
83
+ that file are maintained against real servers and are unlikely to drift for
84
+ stable domains like `publicPackages`, `storedPackages`, and `evidence`.
85
+
86
+ **Fallback rule:** If the query returns `GRAPHQL_VALIDATION_FAILED` or
87
+ unexpected empty results, fetch the schema (as described below), verify the
88
+ query against it, and retry. Do not attempt more than one execution without
89
+ schema verification.
90
+
91
+ The schema is large. Cache it under the skill cache directory (the JFrog CLI
92
+ home — outside the installed skill tree) keyed by the concrete
93
+ `JFROG_SERVER_ID` from step 1 (the CLI `serverId`, never a placeholder like
94
+ `default`).
95
+
96
+ **Always use this exact path** — do not save the schema to `/tmp/` or any other
97
+ location. The cache path is:
98
+
99
+ `${JFROG_CLI_HOME_DIR:-$HOME/.jfrog}/skills-cache/onemodel-schema-${JFROG_SERVER_ID}.graphql`
100
+
101
+ Run the following block as-is. It checks for an existing cached file and only
102
+ fetches when missing:
103
+
104
+ ```bash
105
+ SCHEMA_FILE="${JFROG_CLI_HOME_DIR:-$HOME/.jfrog}/skills-cache/onemodel-schema-${JFROG_SERVER_ID}.graphql"
106
+ if [ -s "$SCHEMA_FILE" ]; then
107
+ echo "Schema cache hit: $SCHEMA_FILE ($(wc -l < "$SCHEMA_FILE") lines)"
108
+ else
109
+ mkdir -p "$(dirname "$SCHEMA_FILE")"
110
+ jf api /onemodel/api/v1/supergraph/schema \
111
+ --server-id "$JFROG_SERVER_ID" \
112
+ > "$SCHEMA_FILE"
113
+ echo "Schema fetched: $SCHEMA_FILE ($(wc -l < "$SCHEMA_FILE") lines)"
114
+ fi
115
+ ```
116
+
117
+ (Omit `--server-id "$JFROG_SERVER_ID"` to target the active default server.)
118
+
119
+ After the block runs, **read `$SCHEMA_FILE` from disk** for all subsequent
120
+ schema lookups — never re-fetch to a different path.
121
+
122
+ If the fetch fails (HTTP 401/403, empty file, or network error), verify the
123
+ access token, wildcard audience, base URL (no trailing path beyond the host), and
124
+ server version. If the schema file is empty or contains an HTML error page,
125
+ delete it and retry the block above.
126
+
127
+ The schema file is SDL — namespaces, types, fields, arguments, enums, and
128
+ directives for **this** server.
129
+
130
+ #### Navigating the schema
131
+
132
+ The schema is large (typically 10,000+ lines). Do not read it in full. Use
133
+ targeted searches:
134
+
135
+ 1. **Find available namespaces** — search for lines matching `: ...Queries!`
136
+ near the root `Query` definition (e.g. `applications: ApplicationsQueries!`).
137
+ 2. **Find operations for a namespace** — search for the `...Queries` type name
138
+ to see `get...` and `search...` methods.
139
+ 3. **Find input/filter types** — from the operation signature, look up the
140
+ `WhereInput` type to see available filters.
141
+ 4. **Find output fields** — look up the node type to see which fields you can
142
+ request.
143
+
144
+ When reading the schema, **ignore types and fields annotated with
145
+ `@inaccessible`.** These are internal federation artifacts and are not queryable
146
+ through the OneModel endpoint.
147
+
148
+ #### Never assume — always verify in the schema
149
+
150
+ Before constructing any query, look up every type you intend to use. Common
151
+ mistakes:
152
+
153
+ - **Scalars vs enums** — A name like `FooType` may be a `scalar` (string)
154
+ or an `enum`. Search for `scalar FooType` vs `enum FooType` to know
155
+ whether to pass a quoted string (`"something"`) or a bare identifier.
156
+ - **Connection fields vs plain fields** — Look for `...Connection` naming;
157
+ verify exact field names and required arguments on the parent type.
158
+ - **Nested types** — When a field returns a complex type, look up that type's
159
+ definition for subfields; do not guess names.
160
+
161
+ #### Read the descriptions
162
+
163
+ Schema descriptions (`"""..."""` above types, fields, and arguments) encode
164
+ accepted values, matching behavior, and constraints. Read a few lines above
165
+ each definition you use.
166
+
167
+ **Why this matters:** The OneModel supergraph is composed per server from
168
+ products, entitlements, and license. Different servers expose different domains.
169
+ The resolved schema is the only reliable source of truth.
170
+
171
+ **Do NOT rely on:**
172
+
173
+ - Public documentation alone — it may not list every domain on your server.
174
+ - Hardcoded examples without schema verification — see
175
+ `onemodel-query-examples.md` as patterns only.
176
+ - Legacy metadata GraphiQL (`/metadata/api/v1/query/graphiql`) — deprecated;
177
+ it does not reflect the OneModel schema.
178
+
179
+ ### 3. Understand the query intent
180
+
181
+ Using the schema from step 2, map the user's request to available domains.
182
+ Search for root `Query` and `: ...Queries!` lines to see namespaces on this
183
+ server.
184
+
185
+ Common domains you **may** find (always verify in the schema):
186
+
187
+ - **Applications** — applications, versions, bound package versions
188
+ - **Release lifecycle** — release bundle versions, artifacts, source builds
189
+ - **Evidence** — evidence on artifacts, repos, or release bundles
190
+ - **Stored packages** — packages and versions in Artifactory repos
191
+ - **Public / custom catalog** — public registry metadata, catalog packages,
192
+ security/legal/operational info
193
+
194
+ If no matching types exist, tell the user the capability is not exposed on this
195
+ server.
196
+
197
+ **Note:** Legacy metadata GraphQL (`packages` at `/metadata/api/v1/query`) is
198
+ deprecated and **not** part of OneModel. Use `/onemodel/api/v1/graphql` only.
199
+
200
+ ### 4. Construct the GraphQL query
201
+
202
+ Build the query using **only** types, fields, and arguments from the resolved
203
+ schema.
204
+
205
+ #### Pre-construction checklist
206
+
207
+ 1. Look up every argument type (`where`, `orderBy`, etc.).
208
+ 2. Look up every output type and required subfield selections for object types.
209
+ 3. Look up every `WhereInput` and nested filter shape.
210
+ 4. Trace the full path from root to leaf and confirm each hop exists.
211
+
212
+ #### Principles
213
+
214
+ - Prefer **one query** that returns what the user needs (nested fields,
215
+ filters) to minimize round-trips.
216
+ - Request **only needed fields**.
217
+ - On validation errors, **simplify** the query (e.g. one scalar field per
218
+ connection) to isolate the bad filter or field. Request `totalCount` only if
219
+ that connection type defines it in the schema (many metadata connections do
220
+ not).
221
+ - Use **`where`** in the query instead of fetching everything client-side.
222
+ - Use **pagination** — include `first` (or `last`) and
223
+ `pageInfo { hasNextPage endCursor }` for large sets.
224
+ - Use **GraphQL variables** for dynamic values (see `onemodel-common-patterns.md`).
225
+
226
+ #### Naming convention
227
+
228
+ - `get...` — single item
229
+ - `search...` — list / connection-style results
230
+
231
+ ### 5. Validate the query against the schema
232
+
233
+ Before executing, verify:
234
+
235
+ 1. Every field name matches the schema (casing, suffixes like `...Connection`).
236
+ 2. Every object-typed field has a subfield selection.
237
+ 3. Every argument value matches scalar vs enum vs input rules.
238
+ 4. Nested `where` paths exist end-to-end on the corresponding input types.
239
+ 5. Connection fields include pagination arguments as required.
240
+ 6. **Brace balance** — every `{` in the document (selection sets and input
241
+ objects) has exactly one matching `}`. Deep nesting is easy to get wrong in
242
+ a single-line shell string; prefer a `.graphql` file or heredoc so structure
243
+ is visible (see below).
244
+
245
+ ### 6. Execute the query
246
+
247
+ POST to `/onemodel/api/v1/graphql`:
248
+
249
+ ```bash
250
+ jf api /onemodel/api/v1/graphql \
251
+ -X POST -H "Content-Type: application/json" \
252
+ --input "$PAYLOAD_FILE" \
253
+ --server-id "$JFROG_SERVER_ID" \
254
+ > "$RESPONSE_FILE"
255
+ ```
256
+
257
+ #### Always save the response to a file
258
+
259
+ Redirect `jf api`'s stdout to `$RESPONSE_FILE` so you can re-`jq` without
260
+ re-querying. **Do not pipe `jf api` directly to `jq`** — a wrong filter
261
+ loses the response. **Do not** set `RESPONSE_FILE` under
262
+ `~/.jfrog/skills-cache/` — that directory is only for the schema cache and
263
+ `jfrog-skill-state.json` (see [`~/.jfrog/skills-cache/` policy](#jfrogskills-cache-policy)
264
+ above).
265
+
266
+ For multiple queries in one shell session, use a temp directory under `/tmp` and
267
+ sequential names:
268
+
269
+ ```bash
270
+ ONEMODEL_TMPDIR=$(mktemp -d)
271
+ ONEMODEL_QUERY_NUM=0
272
+ ```
273
+
274
+ Before each query:
275
+
276
+ ```bash
277
+ ONEMODEL_QUERY_NUM=$((ONEMODEL_QUERY_NUM + 1))
278
+ RESPONSE_FILE="$ONEMODEL_TMPDIR/response-$ONEMODEL_QUERY_NUM.json"
279
+ ```
280
+
281
+ #### Always use `jq` to build the JSON payload
282
+
283
+ Do **not** hand-embed the GraphQL string inside a JSON literal — escaping breaks
284
+ easily. Build the payload JSON with `jq`, write it to a **file**, and pass the
285
+ file to `jf api` with `--input`. `jf api` does not accept stdin for `--data`;
286
+ `--input` expects a file path.
287
+
288
+ ##### Avoid `PARSING_ERROR` (broken GraphQL documents)
289
+
290
+ A response with `extensions.code: PARSING_ERROR` (often `expected a StringValue,
291
+ Name or OperationDefinition` at **line 1, column N**) means the **document
292
+ text** is invalid — usually **too many or too few `}`** — before the server
293
+ checks fields against the schema. This happens most often when a long query is
294
+ pasted into `QUERY='...'` as **one bash line**: braces are hard to count, and a
295
+ typo near the end surfaces as an error at a **high column number**.
296
+
297
+ **Do this instead:**
298
+
299
+ | Query size | How to build the payload |
300
+ |------------|-------------------------|
301
+ | Tiny (few fields, one level) | `QUERY='...'` plus `jq -n --arg q "$QUERY"` into a file is OK. |
302
+ | Anything nested (connections, `where: { ... }`, multiple roots) | Put the document in a **`.graphql` file** (or a **quoted heredoc**) and use **`jq --rawfile`**. Never maintain a 400+ character one-liner in bash. |
303
+
304
+ Example — **small** query with `jq --arg`:
305
+
306
+ ```bash
307
+ QUERY='{ evidence { searchEvidence(first: 5, where: { hasSubjectWith: { repositoryKey: "my-repo-local" } }) { totalCount } } }'
308
+ PAYLOAD_FILE="$ONEMODEL_TMPDIR/payload-$ONEMODEL_QUERY_NUM.json"
309
+ jq -n --arg q "$QUERY" '{"query": $q}' > "$PAYLOAD_FILE"
310
+
311
+ jf api /onemodel/api/v1/graphql \
312
+ -X POST -H "Content-Type: application/json" \
313
+ --input "$PAYLOAD_FILE" \
314
+ --server-id "$JFROG_SERVER_ID" \
315
+ > "$RESPONSE_FILE"
316
+
317
+ jq . "$RESPONSE_FILE"
318
+ ```
319
+
320
+ Example — **nested** query from a file (preferred for real OneModel calls):
321
+
322
+ ```bash
323
+ # my-query.graphql contains a normal multi-line GraphQL document
324
+ PAYLOAD_FILE="$ONEMODEL_TMPDIR/payload-$ONEMODEL_QUERY_NUM.json"
325
+ jq -n --rawfile q my-query.graphql \
326
+ '{"query": ($q | gsub("#.*"; "") | gsub("\\s+"; " ") | sub("^ +"; "") | sub(" +$"; ""))}' \
327
+ > "$PAYLOAD_FILE"
328
+
329
+ jf api /onemodel/api/v1/graphql \
330
+ -X POST -H "Content-Type: application/json" \
331
+ --input "$PAYLOAD_FILE" \
332
+ --server-id "$JFROG_SERVER_ID" \
333
+ > "$RESPONSE_FILE"
334
+ ```
335
+
336
+ Strip `#` comments and collapse whitespace only if you need a single-line
337
+ payload; often you can pass the file content as-is if it has no comments.
338
+
339
+ With variables, add more `--arg` flags and a `variables` object (see
340
+ `onemodel-common-patterns.md`).
341
+
342
+ ### 7. Handle the response
343
+
344
+ Always read from `$RESPONSE_FILE` for further extraction or formatting.
345
+
346
+ #### Success shape
347
+
348
+ ```json
349
+ {
350
+ "data": {
351
+ "<namespace>": {
352
+ "<queryName>": { ... }
353
+ }
354
+ }
355
+ }
356
+ ```
357
+
358
+ #### Errors
359
+
360
+ Errors appear in an `errors` array. Partial data may coexist with errors.
361
+
362
+ | Symptom | Likely cause | Action |
363
+ |--------|---------------|--------|
364
+ | 401 | Invalid or expired token | Re-run the login flow (`references/jfrog-login-flow.md`) for the same server |
365
+ | 403 | Insufficient permissions | User/token lacks access to the resource |
366
+ | `GRAPHQL_VALIDATION_FAILED` | Bad field or argument | Re-check schema |
367
+ | `PARSING_ERROR` / syntax at **line 1, column N** | Invalid document (often extra/missing `}`); common with long `QUERY='...'` one-liners | Reformat in a `.graphql` file or heredoc; verify brace balance; use `jq --rawfile` |
368
+ | Empty results | Filters or no data | Broaden filters or verify data exists |
369
+
370
+ #### Pagination
371
+
372
+ If `pageInfo.hasNextPage` is true, pass `endCursor` as `after` on the next
373
+ request. Save each page to a new `response-N.json`. Details:
374
+ `onemodel-common-patterns.md`.
375
+
376
+ ## GraphQL Playground
377
+
378
+ The Platform UI includes a GraphQL Playground: **Integrations > GraphQL
379
+ Playground**, or:
380
+
381
+ `$JFROG_URL/ui/onemodel/playground`
382
+
383
+ Suggest it when:
384
+
385
+ - Queries are deeply nested or cross-domain and hard to get right in one turn
386
+ - Multiple attempts failed and autocomplete would help
387
+ - The user wants to explore capabilities rather than run one fixed query
388
+ - The user asks for a UI or visual GraphQL explorer
389
+
390
+ Include the resolved base URL so they can open it immediately.
391
+
392
+ ### Official documentation
393
+
394
+ - [JFrog OneModel GraphQL](https://jfrog.com/help/r/jfrog-rest-apis/jfrog-one-model-graphql)
395
+ - [OneModel common patterns](https://jfrog.com/help/r/jfrog-rest-apis/one-model-graphql-common-patterns-and-conventions)
396
+ - [Release lifecycle GraphQL examples](https://jfrog.com/help/r/jfrog-rest-apis/get-release-bundle-v2-version-graphql-use-cases-examples)
397
+ - [GraphQL introduction](https://graphql.org/learn/)
398
+
399
+ ## Gotchas
400
+
401
+ - **`PARSING_ERROR` at a high column** — almost always mismatched `{` / `}` in
402
+ the document. Use a `.graphql` file and `jq --rawfile`, not a long
403
+ `QUERY='...'` one-liner (see step 6).
404
+ - **Schema varies per server** — never assume a domain or field exists; verify in
405
+ the fetched supergraph schema.
406
+ - **Ignore `@inaccessible`** — not queryable through OneModel.
407
+ - **Scalars vs enums** — wrong literal form can yield empty results without a
408
+ clear error; check the type definition and descriptions.
409
+ - **`PackageType` vs `StoredPackageRepositoryType`** — these are both "package
410
+ type" fields but they differ in kind and purpose.
411
+ `PackageType` is a **scalar** (a quoted string like `"npm"`, `"maven"`,
412
+ `"docker"`). It identifies the **package or version** itself and appears on
413
+ `StoredPackage.type`, `PublicPackage.type`, `getPackage(type:)`,
414
+ `searchPackages`, and `searchPackageVersions` where-inputs.
415
+ `StoredPackageRepositoryType` is an **enum** (bare uppercase identifiers like
416
+ `NPM`, `MAVEN`, `DOCKER`). It identifies the **Artifactory repository type**
417
+ that hosts stored packages and appears on `StoredPackage.repositoryPackageType`
418
+ and as an alternative argument on `storedPackages.getPackage(repositoryPackageType:)`.
419
+ The `getPackage` operation on `storedPackages` accepts either — its schema
420
+ description says "At least one of type or repositoryPackageType must be
421
+ provided." Using an enum value where a string is expected (or vice versa) causes
422
+ `GRAPHQL_VALIDATION_FAILED` errors, so always verify which field you are
423
+ targeting before choosing the literal form.
424
+ - **OneModel endpoint only:** `POST /onemodel/api/v1/graphql` (full path
425
+ passed to `jf api`). Do not use legacy
426
+ `/metadata/api/v1/query` or its `packages` root for OneModel.
427
+ - **Token audience** — wildcard `*@*` is required for typical OneModel use;
428
+ narrow tokens may fail with auth errors.
429
+ - **`jf api` handles auth and URL** — it authenticates against the active
430
+ (or `--server-id`-named) server and prepends the configured platform base
431
+ URL. Do not construct OneModel URLs manually or attach bearer tokens
432
+ yourself.
433
+ - **Content-Type** — `application/json` on POST.
434
+ - **Pagination** — do not mix `first/after` with `last/before` in the same field.
435
+ - **Dates** — fields ending in `...At` default to ISO-8601 UTC; `@dateFormat`
436
+ can change output (see `onemodel-common-patterns.md`).
437
+ - **`@experimental` / `@deprecated`** — treat per schema directives.
438
+ - **Save responses before `jq`** — same rule as SKILL.md *Preserving command
439
+ output* for network-backed calls.
440
+
441
+ ## Related reference files
442
+
443
+ - `onemodel-query-examples.md` — illustrative templates per domain (verify
444
+ against schema before use).
445
+ - `onemodel-common-patterns.md` — Relay-style pagination, filters, variables,
446
+ date formatting, response shapes.