Adapto content upload
Skill adaptocms/adapto-cms-agent-skills/plugin/skills/adapto-content-upload
Push approved content drafts to Adapto — convert each reviewed Markdown draft to HTML, create or update the Article/Page/collection item (one-way push via the ledger id-map), mirror its SEO metadata into _adapto_seo, and drift-guard against out-of-band CMS edits. Schema-gated; everything lands as draft. Plan-then-apply.From its SKILL.md
npx -y skills add adaptocms/adapto-cms-agent-skills --skill adapto-content-uploadAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 8 commands, including `SESSION_ID="agent_$(date -u +%Y-%m-%dT%H-%MZ)_$(printf '%04x' $RANDOM)"` and 7 more.
SKILL.md
7.4 KB, ~1.9k tokens by cl100k_base, as published. Nobody here has run it
adapto:content-upload
The pipeline's gated writer (content-pipeline.md). It takes the
Markdown drafts you've approved and pushes them to Adapto: body md→HTML, create-or-update via the
ledger's local↔CMS id-map (one-way push — local is the source of truth), the SEO metadata mirrored into the
reserved _adapto_seo collection, everything landing as draft. It is schema-gated (every target
type must exist first) and drift-guarded (it won't silently overwrite backoffice edits).
When to use
- "Upload the drafts", "push the approved content to Adapto", "update the content in Adapto".
- After you've reviewed
.adapto/drafts/and want the approved pieces in the CMS.
When not to use
- Writing/revising the drafts →
adapto:content-create. - Taking CMS drafts live →
adapto:publish(upload lands drafts; publish flips them to published). - Rendering metadata on the site →
adapto:seo-wire.
Inputs
- The approved drafts in
.adapto/drafts/(frontmatter per content-pipeline.md §2). The user names which to upload, or "all reviewed". - The ledger (
.adapto/ledger.json) — the local↔CMS id-map (create vs update) + drift fingerprints. .adapto/schema.json— collection +_adapto_seoids (the schema gate).inventory.md— to resolveinternal_links/category_slugs.- The working tenant + language (confirm the tenant).
Outputs
- Created/updated Articles / Pages / collection items in Adapto (
draft), provenance-tagged on Articles. - A mirrored
_adapto_seoitem per piece (meta/OG/JSON-LD),json_ldstringified. - The ledger advanced to
status: uploadedwithcms.content_id,cms.seo_id,last_push_hash,cms_updated_at;calendar.mdrefreshed. - Next step:
adapto:seo-wire(if the render layer isn't wired yet) so the metadata shows on the site; then review on the dev server andadapto:publishto take it live;adapto:translateto localize.
Preconditions
- Preflight with the
adapto:doctorchecks. - Hard-block on an authenticated CLI (
adapto auth me) and a selected tenant (this skill writes); confirm the working tenant. .adapto/schema.jsonmust exist with the targets the drafts need (else the schema gate routes you toadapto:schema-design/adapto:schema-apply).adaptoCLI>= 0.1.3.
Plan phase
Build + validate; no writes yet. Print a machine-parseable plan and ask as a pickable question
(Approve / Change something / Discuss this):
- Per draft: create vs update (from the ledger id-map), its
type/slug/language, and the_adapto_seoitem it will write. - Schema gate: confirm every draft's target type/collection exists in
.adapto/schema.json. Any missing → STOP and route toadapto:schema-design/adapto:schema-apply; don't upload that piece. - Drift check: for each already-uploaded piece, compare the live CMS item's
updated_atto the ledger'scms_updated_at. If it changed, flag it drifted and ask per piece: overwrite / skip / import-CMS — never silently clobber. - Unresolved links: list any
internal_links/category_slugsnot ininventory.md(written but flagged). - The provenance session id that will tag Article writes. No cost/token figures. Nothing to upload → say so and stop.
Apply phase
Runs only after approval. Deterministic CLI calls (--json on each).
SESSION_ID="agent_$(date -u +%Y-%m-%dT%H-%MZ)_$(printf '%04x' $RANDOM)" # for Article --source
For each approved draft:
- Body md→HTML. Convert the Markdown body to HTML (the CMS
contentrenders HTML — cheatsheet §3). Resolveinternal_links+category_slugsagainstinventory.md; warn on unresolved (write anyway). - Create or update the content via the ledger id-map:
- Article —
articles create(new) /articles update <id>(known), with--source '{"type":"ai_generated","name":"'"$SESSION_ID"'"}',--status draft,--author <from draft>; thencategories add-article <cat_id> <article_id>per resolved category. - Page —
pages create/pages update <id>(no--source). - Collection item —
collections items create <cid>/items update <cid> <item_id>,--data-jsonkeyed to the collection's fields,--status draft.
- Article —
- Mirror
_adapto_seo. Upsert one_adapto_seoitem for the piece (keyedtarget_slug+content_type,content_idonce known;json_ldstringified) viaitems create/items updateon the_adapto_seocollection id fromschema.json. - Update the ledger row →
status: uploadedwithcontent_id,seo_id,last_push_hash(sha256 of the draft body),last_push_at,cms_updated_at(the item's returnedupdated_at); refreshcalendar.md. - Drift: if the Plan flagged a piece as drifted and the user didn't choose overwrite, skip it and report.
Loop cleanly — judge success from each call's --json, not the shell exit code; end the loop exit 0 on
success so a created batch never surfaces as a red Error: Exit code 1 (conventions.md §8). Then restart the
dev server (stop→start) and keep it running so the new content appears — never kill it (starters sync at
startup — §14). Finally point to adapto:seo-wire / review + adapto:publish / adapto:translate.
Errors and recovery
- Schema gate fails (target type/collection missing) → stop that piece; route to
adapto:schema-design/adapto:schema-apply; upload the rest. - Drift detected → ask per piece (overwrite / skip / import); never silently overwrite backoffice edits.
- Item
datadoesn't match collection fields → surface which field; don't send unknown keys. - Partial failure mid-loop (Articles/Pages have no batch) → report what uploaded, update those ledger rows, then stop; re-running is safe (the id-map makes it an update, not a duplicate).
_adapto_seowrite fails but content succeeded → report the content id, mark the seo mirror pending, and retry the metadata only (don't re-create the content).- Not authenticated / no tenant → stop; offer both auth paths —
Log inorRegister(conventions §11) — then tenant selection.
Forbidden actions
- Never write without an approved plan (plan-then-apply); never assume the working tenant.
- Never omit
--sourceon an Article write — it mislabels content asinternal/CLI(forbidden-actions.md). - Never silently overwrite a drifted CMS item — drift-guard and ask.
- Never publish — everything lands
draft(draft-first); the user reviews thenadapto:publish. - Never invent collection-item
datakeys,_adapto_seofields, or article/page fields not in the schema. - Never modify the read-client; never blind-retry a non-idempotent write (use the ledger id-map).
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.