plugins/data-serialization/skills/data-serialization/SKILL.md
Data format conversion and querying utilities for YAML, JSON, TOON, and XML/HTML. Includes special handling for Playwright accessibility snapshots and comprehensive querying guidance using jq, yq, and native tools. TOON provides 30-60% token reduction for LLM contexts.
npx skillsauth add nsheaps/ai-mktpl data-serializationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are a data transformation specialist. Your job is to help convert between data formats and query structured data efficiently, with a focus on token efficiency for LLM contexts.
| Format | Extension | Best For | Tools |
| -------- | --------------- | ------------------------------------------- | -------------------- |
| JSON | .json | Data interchange, APIs, tooling | jq |
| YAML | .yaml, .yml | Human editing, config files | yq |
| TOON | .toon | LLM prompts (30-60% fewer tokens) | Python toon_format |
| XML | .xml | Legacy systems, SOAP, external requirements | xmllint |
| HTML | .html | Web content conversion | Python xmltodict |
Pros:
Cons:
Use when: API responses, data interchange, tool input/output
Pros:
| or >Cons:
Use when: Config files that humans edit, CI/CD pipelines, Kubernetes
Security Note: Never load untrusted YAML with yaml.load() - use yaml.safe_load()
Pros:
[N] lengths and {fields} headers help LLMs parse reliablyCons:
Use when:
Best for: Uniform arrays of objects (same fields across items)
Pros:
Cons:
Use when: SOAP APIs, enterprise integrations, document formats (Office, SVG)
Objects use key-value pairs with colon-space separation:
name: Alice
age: 30
active: true
Nested objects use indentation:
user:
id: 123
profile:
role: admin
Primitive arrays (inline):
tags[3]: admin,ops,dev
Tabular arrays (uniform objects - TOON's sweet spot):
users[2]{id,name,role}:
1,Alice,admin
2,Bob,user
Expanded lists (mixed types):
tasks[2]:
- Complete report
- Review code
JSON (257 tokens):
{
"users": [
{ "id": 1, "name": "Alice", "role": "admin" },
{ "id": 2, "name": "Bob", "role": "user" },
{ "id": 3, "name": "Carol", "role": "guest" }
]
}
TOON (166 tokens - 35% reduction):
users[3]{id,name,role}:
1,Alice,admin
2,Bob,user
3,Carol,guest
The plugin provides a convert.sh script for format conversion:
# Basic usage
/path/to/plugins/data-serialization/scripts/convert.sh <input-file> <output-format>
# Examples
convert.sh data.json yaml # JSON to YAML
convert.sh config.yaml toon # YAML to TOON
convert.sh data.toon json # TOON to JSON
convert.sh data.xml json # XML to JSON
convert.sh page.html yaml # HTML to YAML
# With explicit source format (if auto-detect fails)
convert.sh data.txt json --from yaml
# Playwright accessibility snapshot conversion
convert.sh playwright-snapshot.md json --playwright
convert.sh playwright-snapshot.md toon --playwright
JSON to YAML:
yq -P '.' input.json > output.yaml
YAML to JSON:
yq -o=json '.' input.yaml > output.json
JSON to TOON:
python3 -c "
from toon_format import encode
import json
with open('input.json') as f:
data = json.load(f)
print(encode(data))
" > output.toon
TOON to JSON:
python3 -c "
from toon_format import decode
import json
with open('input.toon') as f:
data = decode(f.read())
print(json.dumps(data, indent=2))
" > output.json
XML to JSON:
python3 -c "
import json, xmltodict
with open('input.xml') as f:
data = xmltodict.parse(f.read())
print(json.dumps(data, indent=2))
" > output.json
HTML to JSON:
python3 -c "
import json, xmltodict
from html.parser import HTMLParser
with open('input.html') as f:
# Parse HTML as XML-like structure
data = xmltodict.parse(f.read())
print(json.dumps(data, indent=2))
" > output.json
Basic selection:
# Get a field
jq '.fieldName' data.json
# Get nested field
jq '.parent.child' data.json
# Get array element
jq '.[0]' data.json
jq '.items[0]' data.json
Filtering:
# Select objects matching condition
jq '.[] | select(.status == "active")' data.json
# Multiple conditions
jq '.[] | select(.age > 18 and .country == "US")' data.json
# Null-safe filtering
jq '.[] | select(.optional // empty)' data.json
Transformation:
# Extract specific fields
jq '.[] | {name, email}' data.json
# Rename fields
jq '.[] | {userName: .name, userEmail: .email}' data.json
# Create arrays
jq '[.[] | .name]' data.json
Aggregation:
# Count items
jq 'length' data.json
jq '[.[] | select(.active)] | length' data.json
# Sum values
jq '[.[] | .price] | add' data.json
# Group by field
jq 'group_by(.category)' data.json
yq uses the same syntax as jq:
# Basic queries work the same
yq '.fieldName' data.yaml
yq '.[] | select(.status == "active")' data.yaml
# Output as JSON
yq -o=json '.' data.yaml
# Edit in place
yq -i '.version = "2.0"' data.yaml
Using xmllint:
# Get element text
xmllint --xpath '//element/text()' data.xml
# Get attribute
xmllint --xpath 'string(//element/@attr)' data.xml
# Count elements
xmllint --xpath 'count(//item)' data.xml
# Get multiple elements
xmllint --xpath '//item/name/text()' data.xml
For TOON, convert to JSON first, then use jq:
python3 -c "
from toon_format import decode
import json
with open('data.toon') as f:
print(json.dumps(decode(f.read())))
" | jq '.users[] | select(.role == "admin")'
Playwright MCP returns accessibility snapshots in a YAML-like format. These can be converted for querying.
Playwright snapshots look like:
- button "Submit" [ref=s1e2]
- link "Home" [ref=s1e3]
- text "Home"
- textbox "Email" [ref=s1e4]
Use the convert script with --playwright flag:
convert.sh snapshot.md json --playwright
convert.sh snapshot.md toon --playwright # For token efficiency
This produces queryable JSON:
[
{ "role": "button", "name": "Submit", "ref": "s1e2" },
{
"role": "link",
"name": "Home",
"ref": "s1e3",
"children": [{ "role": "text", "name": "Home" }]
},
{ "role": "textbox", "name": "Email", "ref": "s1e4" }
]
Find all buttons:
jq '[.. | objects | select(.role == "button")]' snapshot.json
Find element by name:
jq '.. | objects | select(.name == "Submit")' snapshot.json
Get all refs:
jq '[.. | objects | .ref // empty]' snapshot.json
Find clickable elements:
jq '[.. | objects | select(.role == "button" or .role == "link")]' snapshot.json
Ensure these tools are available:
# macOS
brew install jq yq
# Python dependencies (for TOON and XML)
pip install git+https://github.com/toon-format/toon-python.git xmltodict dicttoxml
# Verify
jq --version
yq --version
python3 -c "from toon_format import encode; print('toon_format OK')"
This skill is part of the data-serialization plugin.
Sources:
https://github.com/nsheaps/ai-mktpl~/src/nsheaps/ai/plugins/data-serializationtools
Reference material for Claude Code internals — the on-disk layout under ~/.claude and project-scope .claude, the plugin cache, session-env propagation, and the full hook lifecycle. Auto-recall when working on Claude-Code-related tasks: writing or debugging hooks, authoring plugins, inspecting session state, troubleshooting why an env var is or isn't visible to a Bash tool call, or when paths under ~/.claude or ~/.claude/plugins/ come up.
development
Manage GitHub App installation tokens in Claude Code sessions. Use when tokens expire, auth errors occur in long-running sessions, or when setting up GitHub App credentials for agent teams. <example>my github token expired</example> <example>refresh the github app token</example> <example>check token status</example> <example>set up github app authentication for this session</example>
tools
Auto-detect project formatting tools and configure edit-utils settings
tools
Use this skill when the user asks about 1Password, secrets management, retrieving credentials, using op CLI, service accounts, secret references, vault operations, or any task involving the 1Password CLI (op). Also use when needing to inject secrets into environment variables, read passwords or API keys from 1Password, or manage 1Password items from the command line.