Install
$ agentstack add skill-adaptocms-adapto-cms-agent-skills-adapto-schema-apply ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
adapto:schema-apply
The gated writer of the schema pair. It reads .adapto/schema-plan.json (produced by adapto:schema-design) and creates the Article categories and custom collections it describes via the adapto CLI. It is idempotent and re-runnable — existing collections/categories are reused or updated, never duplicated.
When to use
- After
adapto:schema-designproduced (and you've eyeballed or hand-edited).adapto/schema-plan.json, and
you're ready to create those collections + categories in Adapto.
- Triggers: "apply the schema", "create the collections", "build my schema in Adapto".
When not to use
- No plan file yet → run
adapto:schema-designfirst. - Seeding content rows into the collections →
adapto:content-seed.
Inputs
.adapto/schema-plan.json— the approved plan (collections, categories, language). Missing/invalid →
stop and route to adapto:schema-design.
- The working tenant — confirm it explicitly (CLAUDE.md §3.5); never assume the saved/active one. With
2+ tenants, have the user pick; with one, state it and proceed.
Outputs
- The plan's Article categories and custom collections created (or updated) in the CMS,
draft
unless the plan says otherwise.
- The reserved
_adapto_seocollection ensured (the CMS home for per-piece SEO metadata —
[reserved-slugs.md](../../shared/reserved-slugs.md)), so adapto:content-upload can write metadata.
- A realized
.adapto/schema.json— a{"": "", …}map of every collection's slug to its CMS
id (incl. _adapto_seo) — for adapto:content-upload (and adapto:content-seed) to target.
- A report: which collections/categories were created vs reused, with ids.
- Next step: suggest
adapto:content-researchto start a content cycle (research → plan → create →
upload), or adapto:content-seed for a quick set of starter drafts. Both read .adapto/schema.json.
Preconditions
- Preflight with the
adapto:doctorchecks (CLAUDE.md §3.14). - Hard-block on an authenticated CLI (
adapto auth me) and a selected tenant — this skill writes. .adapto/schema-plan.jsonmust exist (else route toadapto:schema-design).adaptoCLI>= 0.0.7.
Plan phase
Read and validate .adapto/schema-plan.json, then print a machine-parseable plan and wait for an explicit approve:
- For each category and collection: whether it will be created or reused (resolved live via
get-by-slug), plus its fields, the target language, and draft status.
- The realized
.adapto/schema.jsonit will write. - That the reserved
_adapto_seocollection will be ensured (created if absent) for content metadata. - No cost/token figures (CLAUDE.md §3.10). If the plan is empty, say so and stop — nothing to apply.
Validate before proposing: every field type is in the safe vocabulary (cheatsheet §5), and every reference field's related_collection slug exists in the plan. Surface any problem here, before writing.
Apply phase
Runs only after approval. Deterministic CLI calls — --json on every one.
- Resolve language. Use the plan's
languageif the tenant has it enabled; otherwise fall back to the
tenant's first enabled code and note the substitution. Discover with: ``bash adapto auth orgs --json ``
- Categories — idempotent (no
--statusflag on categories):
``bash adapto categories get-by-slug --json # reuse the id on a hit adapto categories create --name "" --slug --language [--description ""] --json ``
- Collections — TWO PASS (robust even to circular references):
- Pass 1 — create each collection with its non-reference fields only; capture each
slug → id.
On a get-by-slug hit, reuse the id (and update if fields differ): ``bash adapto collections get-by-slug --json adapto collections create --name "" --slug \ --description "" --language --status \ --fields-json '' --json ``
- Pass 2 — add the
referencefields now that their targets exist, resolving each
related_collection slug → the real id captured in Pass 1: ``bash adapto collections update --fields-json '' --json ` 3b. **Ensure the reserved adaptoseo collection** (idempotent) — the CMS home for per-piece SEO metadata that adapto:content-upload writes and adapto:seo-wire reads ([reserved-slugs.md](../../shared/reserved-slugs.md)): `bash adapto collections get-by-slug _adapto_seo --json # reuse the id on a hit adapto collections create --name "Adapto SEO" --slug _adapto_seo \ --description "Per-piece SEO metadata for Adapto content" --language --status draft \ --fields-json '' --json ` ⚠️ **Reserved-slug fallback:** if adapto is rejected, retry once with adapto-seo; record which slug worked. Capture its id into .adapto/schema.json` alongside the user collections.
- Report + persist. Print created-vs-reused with ids, then write
.adapto/schema.jsonas
{"": "", …} (incl. _adapto_seo) for adapto:content-upload. Loop cleanly — judge success from each call's --json, not the shell exit code, and make the loop/function exit 0 on success so a created batch never surfaces as a red Error: Exit code 1 (conventions §8). Then restart the dev server (stop→start) and keep it running so the new collections/categories appear — never kill it (starters sync content at startup — conventions §14).
--fields-json is a FieldDefinitionModel[]. No --source — collections and categories carry no provenance.
Errors and recovery
- Plan missing/invalid → stop; tell the user to run
adapto:schema-design. - Server rejects a field
type→ surface which collection/field, and suggest a safe-vocabulary type
(cheatsheet §5); don't retry blindly.
- A
reference'srelated_collectionslug isn't in the plan → stop before writing; the plan is
inconsistent.
- Collection/category already exists → reuse/update via
get-by-slug; never create a duplicate. - Partial failure mid-apply (collections have no batch — they're per-call) → report what was created so
far, then stop. Re-running is safe (idempotent).
- Not authenticated / no tenant → stop; route to
adapto auth loginand tenant selection. - Language discovery fails → ask the user for a language code the tenant has enabled; don't guess.
Forbidden actions
- Never write without an approved plan (plan-then-apply, CLAUDE.md §3.8).
- Never pass
--sourcehere — collections/categories have no provenance field. - Never create built-in Articles/Pages — the plan's
advisorymap is documentation only. - Never assume the working tenant — confirm it before any write (CLAUDE.md §3.5).
- Never modify the scaffolded read-client (CLAUDE.md §3.11 / [forbidden-actions.md](../../shared/forbidden-actions.md)).
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: adaptocms
- Source: adaptocms/adapto-cms-agent-skills
- License: MIT
- Homepage: https://adaptocms.com/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.