Imported from XYOracleNetwork/xyo-skills (
AGENTS.md). Install upstream withnpx skills add XYOracleNetwork/xyo-skills. Copyright stays with the author.
AGENTS.md
This file provides guidance to Codex and any other agent that reads AGENTS.md when working with code in this repository. Claude Code reads the same guidance from CLAUDE.md; the two files are kept identical apart from this header and the local skill-preview commands below.
Purpose
This repo serves three roles:
- Skill source of truth for XYO/XL1 domain layers —
xyo-knowledgeandxl1-*underskills/. Installed directly by Skills.sh and mirrored to marketplace repos for Claude Code and Codex. Layers 1–2 (xy-development,xy-toolchain) are owned byariestools/ariestools-skills; this repo keeps temporary redirect stubs only. - Scaffold tool —
packages/xl1-scaffold/scaffolds a new XL1 app (React dApp,xl1-servicebackend, plain Node service/CLI, or a full-stack pnpm monorepo) with the correct dep graph, tsconfig, ESLint, and smoke test wired up. - Evaluation test bed —
src/is where a rock-paper-scissors game gets built to test the skill stack's quality.
The skills themselves are the primary artifact. When implementation reveals incorrect or misleading guidance in a skill, update the skill file — not just the application code.
Distribution Model
The Claude Code and Codex marketplaces want incompatible repository layouts, so this repo ships just the source and renders marketplace-shaped trees into two mirror repos on each release:
XYOracleNetwork/xyo-skills(this repo) — source of truth for XYO/XL1 domain skills. Skills.sh installs from here directly.XYOracleNetwork/xyo-claude-plugin— Claude Code marketplace target. Written by release automation; do not edit by hand.XYOracleNetwork/xyo-codex-plugin— Codex marketplace target. Written by release automation; do not edit by hand.
The render pipeline lives at scripts/marketplace-sync/:
metadata.json— single canonical, marketplace-agnostic plugin metadata. Contains version, description, keywords, author, category, brand assets, capabilities. Edit this when changing what's advertised in any marketplace.build-claude.mjs— readsmetadata.jsonand emits the Claude marketplace tree (.claude-plugin/{marketplace,plugin}.json+skills/+assets/+LICENSE).build-codex.mjs— same, for Codex. Codex nests the plugin payload underplugins/xyo-skills/, so the tree is.agents/plugins/marketplace.json+plugins/xyo-skills/.codex-plugin/plugin.json+plugins/xyo-skills/{skills,assets}/+LICENSE.lib.mjs— shared CLI / output / copy plumbing.
When a marketplace changes its required schema, edit the corresponding renderer — metadata.json stays marketplace-neutral. Render locally before pushing:
pnpm sync:claude --out .preview/claude # inspect the would-be Claude tree
pnpm sync:codex --out .preview/codex # inspect the would-be Codex tree
.preview/ is gitignored. Release-please bumps the version field inside metadata.json (its sole extra-files entry) plus each SKILL.md frontmatter; that version is then baked into every rendered manifest via the renderer's --version flag.
Skills use progressive loading — each SKILL.md is a lightweight router that directs you to read sub-files on demand based on context. Layers cascade top-down:
Layer 9: xl1-build/ — Planning wizard: vague build request → concrete dApp spec
Layer 8: xl1-scaffold/ — Bootstrap new XL1 apps (React dApp, xl1-service, Node service, monorepo)
Layer 7: xl1-testing/ — Local dev-chain, headless testnet verification, browser-mode tests
Layer 6: xl1-dapp-kit/ — Headless application contracts (manifest, ports, recovery, hosting)
Layer 5: xl1-patterns/ — Prescriptive patterns (indexing, Statement Graph, wakes, tokens, …)
Layer 4: xl1-knowledge/ — XL1 chain, datalakes, gateway, wallet, FinalizedBlockStream
Layer 3: xyo-knowledge/ — XYO payloads, bound witnesses, modules, identity
Layer 2: xy-toolchain/ — REDIRECT → ariestools/ariestools-skills (do not edit body docs here)
Layer 1: xy-development/ — REDIRECT → ariestools/ariestools-skills (do not edit body docs here)
When building application features on XL1, start with Layer 5's SKILL.md — it provides recipe-style patterns that compose primitives from all lower layers. When adopting @xyo-network/dapp-kit*, also load Layer 6. When working on XL1 infrastructure or need reference docs, start with Layer 4.
Do not expand skills/xy-development or skills/xy-toolchain in this repo. They are redirect stubs; edit and release those skills in ariestools-skills. scripts/validate-skills.mjs enforces the stub allowlist.
Development
Package manager: pnpm (enforced — never use npm or yarn in this repo)
Node version: >=24 required. Volta pins Node 24.15.0 and pnpm 10.33.2. Use corepack enable if Volta isn't available.
Branching: Gitflow with develop as the integration branch. Feature branches use feature/<description> off develop. Never rewrite git history (no amend, rebase, or force push).
Merge method by PR type: the strategy matters for keeping main and develop in sync. required_linear_history is intentionally off on main so the integration PR can be merge-committed.
| PR type | Head | Base | Merge method |
|---|---|---|---|
| Feature/fix PR | feature/* |
develop |
Squash |
| Integration PR | develop |
main |
Merge commit (preserves ancestry; never squash — squashing creates phantom commits in git log main..develop that grow over time) |
| Release-please PR | release-please--* |
main |
Squash (release-please's recommended flow — keeps each release as one tidy commit on main) |
| Sync PR | main |
develop |
Merge commit (already auto-applied by sync-main-to-develop.yml) |
Principle: squash is fine when the source branch is throwaway (feature branches and release-please's auto-generated branch are deleted after merge — there's nowhere for phantom commits to accumulate). Squash is harmful when both source and target are long-lived branches (develop and main), because the originals stay on the source forever without ancestry to the new squash commit on the target. So feature → develop and release-please → main squash; develop ↔ main always merge-commit.
Releases: Automated by release-please.
- Use conventional commit prefixes (
feat:,fix:,docs:,chore:,feat!:for breaking) — release-please reads them forCHANGELOG.mdcontent. Versioning is configuredalways-bump-patch, so any merge tomainproduces a release; the prefix only affects the changelog text. lint-pr-title.ymlenforces conventional titles on PRs into bothmain(onlyfeat:/fix:accepted) anddevelop(any conventional type —feat:,fix:,chore:,docs:,refactor:, etc.). The develop-side lint matters because feature-PR squash commits travel tomainvia the integration PR's merge commit, and release-please scans those individual subjects when building the changelog.- To ship: PR
develop→mainwith afeat:orfix:title and merge using the "Create a merge commit" option (not squash). Release-please then opens a Release PR againstmainthat bumpsversion.txt(the source of truth forrelease-type: "simple") and cascades that version intoscripts/marketplace-sync/metadata.jsonand the per-skillSKILL.mdfrontmatter. Merging that PR tags the release; thesync-marketplacesjob then renders and pushes the new version into the Claude and Codex mirror repos. - After release,
sync-main-to-develop.ymlauto-opens and auto-merges amain → developPR using the merge-commit method. Do not squash this PR if you ever merge it manually — squashing breaks the ancestry link betweenmainanddevelopand makes them drift over time. - Release-please uses a fine-grained PAT (
secrets.RELEASE_PLEASE_TOKEN) so its release PRs trigger downstream workflows; without it, the PR's checks would never report and branch protection would block the merge. Track PAT expiration. - The marketplace sync uses
secrets.MARKETPLACE_SYNC_TOKEN(a PAT or GitHub App token withcontents: writeonxyo-claude-pluginandxyo-codex-plugin). Track its expiration alongsideRELEASE_PLEASE_TOKEN. - Don't bump versions by hand — release-please owns those files. Anchored at
b1bc7eb; olderfeat:/fix:commits are not rolled forward.
CI:
validate-plugins.yml(push/PR tomain/develop) — runs both renderers into tmp dirs and validates the generated manifests pass marketplace structural assertions. Also verifies the scaffold runtime inskills/xl1-scaffold/is in sync with its TS source.release-please.yml(push tomain) — opens/merges release PRs. When release-please tags a release, the follow-upsync-marketplacesjob renders and pushes toxyo-claude-pluginandxyo-codex-plugin(matrix;fail-fast: false).validate-skills.yml,lint-pr-title.yml,sync-main-to-develop.yml— unchanged.
To validate manifest generation locally:
pnpm sync:claude --out .preview/claude && jq empty .preview/claude/.claude-plugin/*.json
pnpm sync:codex --out .preview/codex && jq empty .preview/codex/.agents/plugins/marketplace.json .preview/codex/plugins/xyo-skills/.codex-plugin/plugin.json
Workspace layout (pnpm workspaces):
/— workspace root (package.json,pnpm-workspace.yaml,.npmrc)/packages/xl1-scaffold/— the scaffold CLI (TS source undersrc/, raw template files undertemplates/, compiled output indist/)/src/— target for the scaffolded app. Not a workspace member (pnpm-workspace.yamlonly listspackages/*), sopnpm -wcommands do not recurse into it. The scaffold generatessrc/as a standalone pnpm project; run its scripts from insidesrc/.
Scaffold usage (run from repo root):
pnpm install # install workspace deps
pnpm -w run build # build the scaffold
pnpm -w run scaffold src # scaffold React dApp into ./src (default)
pnpm -w run scaffold src --template=node # scaffold Node service instead
pnpm -w run scaffold:dev src --template=node # skip build, run straight from TS via tsx
Once src/ has a package.json, use its scripts (e.g. pnpm build, pnpm lint, pnpm test, pnpm dev) from inside src/ — never raw tool commands.
Common commands (run from repo root):
pnpm -w run build # build all packages (scaffold → plugin sync)
pnpm -w run lint # lint all packages
pnpm -w run typecheck # type-check all packages
Scaffold package (run from packages/xl1-scaffold/):
pnpm test # run tests (vitest)
pnpm test:watch # watch mode
pnpm vitest run path/to/file.test.ts # run a single test file
pnpm vitest run -t "test name pattern" # run tests matching a name
pnpm lint:fix # auto-fix lint issues
Scaffold build chain: clean → tsc → copy-templates → sync-to-plugin compiles TS, copies template files, and writes the runtime into skills/xl1-scaffold/scripts/scaffold/. CI fails if committed source drifts from the synced runtime.
Editing skills: This repo no longer carries marketplace manifests at its root, so there is no plugin for Codex to load from the repo root. Instead, render a local preview tree and register it as a local marketplace:
pnpm sync:codex --out .preview/codex
codex plugin marketplace add /absolute/path/to/xyo-skills/.preview/codex
codex plugin add xyo-skills@xyo-skills
After each skill or metadata change, re-run pnpm sync:codex --out .preview/codex and then codex plugin add xyo-skills@xyo-skills to reinstall, and start a new Codex thread so the updated skills are picked up. See DEVELOPMENT.md for the Claude-side and persistent local-marketplace options.
Key Conventions (from the skills)
- ESM only — no CommonJS
- Root barrel imports —
@xyo-network/sdk(XYO),@xyo-network/xl1-sdk(XL1 protocol),@xyo-network/chain-sdk(XL1 runtime). Tree shaking handles the rest. The pre-July-2026@xyo-network/sdk-jsand@xylabs/sdk-jsnames are deprecated compatibility shims (@xylabs/sdk-js→@ariestools/sdk) — never add them to new work. - Zod-first types (XL1) — Zod schema is the source of truth, derive TS types from it
- Never rewrite git history — no amend, no rebase, no force push
- Conventional commits —
feat:,fix:,chore:,refactor:, etc.
Evaluation Prompt
The prompt used to test the skill stack:
Build me a two-player rock paper scissors game on XL1. Use commit-reveal so neither player can see the other's move before both have committed. Record moves and outcomes on-chain. Include a UI where anyone can browse past games and results without connecting a wallet, and connected players can start and play games.