Define a dataset's metadata profile — infer a Frictionless Table Schema from its data, add Data Package metadata (license, sources, keywords), and write it into datasets.json so the showcase renders a typed field table. Extend or customize via the L0-L3 profile ladder. Use when a registered dataset needs field types, constraints, or catalog metadata before publishing.
npx skills add https://github.com/datopian/portaljs --skill portaljs-define-schema
Define a dataset's metadata profile — the authoring skill for the metadata-profile
contract (lib/metadata). Where portaljs-add-dataset registers *that* a dataset exists,
this skill describes *what its data means*: infer a Frictionless Table Schema (fields,
types, constraints) from sampled data, add the Data Package fields a catalog surfaces
(title, licenses, sources, keywords), and write them onto the dataset's entry in
datasets.json. The showcase at /@<namespace>/<slug> then renders a typed field table
instead of a bare preview. The model is Frictionless-native; DCAT is a serialization layer
built on top later, not authored here.
The skill runs on a profile ladder — reach for higher levels only when needed:
| Level | What it is | When |
| --- | --- | --- |
| L0 | Default frictionless-tabular profile; declare schema + metadata. | Default. Standard tabular CSV/TSV. |
| L1 | L0 plus extra descriptive package fields. | Extra metadata, standard validation is fine. |
| L2 | Fully custom profile (own schema template + validate()). | A dataset type needing custom validation rules. |
| L3 | Multiple registered profiles, resolved per dataset. | A portal mixing dataset types. |
The skill is interactive and never dead-ends: if input is thin it interviews in short
rounds, infers defaults from the data, echoes the schema for confirmation, and accepts
"use defaults" to proceed with the inferred schema as-is.
lib/metadata/types.ts,pages/[owner]/[slug].tsx); see portaljs-new-portal.
datasets.json (see portaljs-add-dataset).PORTAL_DIR/public/data/. JSON/GeoJSON datasets get package metadata only — no fields.
tsx optional, used for the schema-validation check.The canonical, full step-by-step workflow is
.claude/commands/portaljs-define-schema.md —
the single source of truth. Read and follow it when executing. Summary:
PORTAL_DIR, DATASET (slug or namespace/slug), and LEVEL (default L0)from input; if DATASET is missing, list the portal's slugs and ask.
datasets.json, lib/metadata/types.ts,the showcase route); proceed anyway if lib/metadata/ predates the contract.
public/data/<file> and infereach field's type, constraints (required, unique, pattern), and a primary key.
warranted.
datasets.json in place,preserving all other fields; for L2/L3, scaffold and register a custom profile module.
validate().npx next build; fix malformed JSON or an invalid FieldType beforereporting success.
datasets.json (target entry gains profile, schema, licenses,sources, keywords, version — unset fields omitted).
lib/metadata/<profile-id>.ts; lib/metadata/registry.tsupdated with a registerProfile(...) call.
npx next build succeeds./@<namespace>/<slug> renders a typed field table in place of a bare preview.| Symptom | Cause | Fix |
| --- | --- | --- |
| Dataset not found in datasets.json | Wrong slug or missing namespace/ prefix | List available slugs and re-prompt. |
| lib/metadata/ missing | Portal predates the metadata-profile contract | Proceed anyway — schema fields are optional and ignored by older showcases. |
| No fields schema produced | Dataset is JSON/GeoJSON, not tabular | Expected — capture Data Package metadata only. |
| Validation reports type errors | Sampled values don't coerce to the inferred type | Relax the type or drop the offending required/pattern constraint. |
| next build fails on datasets.json | Stray comma or a type outside FieldType | Fix the JSON/type and rebuild before reporting success. |
/portaljs-define-schema population-2022
Infers fields (e.g. country: string, population: integer), drafts titles, asks for a
license and source, and writes the schema under the default frictionless-tabular profile.
/portaljs-define-schema neighborhoods-geo
GeoJSON has no tabular fields; the skill captures license, sources, and keywords onto the
entry and skips schema inference.
/portaljs-define-schema co2-emissions level=L2
Scaffolds lib/metadata/co2-emissions-profile.ts with a custom validate(), registers it
in lib/metadata/registry.ts, and sets "profile": "co2-emissions-profile" on the entry.
.claude/commands/portaljs-define-schema.mdreferences/reference.mdportaljs-add-dataset, portaljs-add-dcat, portaljs-check-data-qualityCombine vector and keyword search for improved retrieval. Use when implementing RAG systems, building search engines, or when neither approach alone provides sufficient recall.
Combine vector and keyword search for improved retrieval. Use when implementing RAG systems, building search engines, or when neither approach alone provides sufficient recall.
Combine vector and keyword search for improved retrieval. Use when implementing RAG systems, building search engines, or when neither approach alone provides sufficient recall.
| Automate Twitter/X with posting, engagement, and user management via inference.sh CLI. social media automation, x automation, tweet scheduler, twitter integration, post tweet, twitter post, x post, send tweet
| Query the Sequence Read Archive (SRA), retrieve scientific publications, and analyze genomics metadata using the SRAgent toolkit. Supports accession conversion (GSE→SRX→SRR), BigQuery metadata queries, manuscript downloads from multiple sources, and scRNA-seq technology identification. Use when working with SRA/GEO datasets, finding publications, or analyzing single-cell sequencing experiments.
Framework for building competitive landscape decks — market positioning, competitor deep-dives, comparative analysis, strategic synthesis. Use when the user asks for a competitive landscape, competitor analysis, peer comparison, market positioning assessment, strategic review, or investment memo deck. Also triggers on "who are the competitors to X", "benchmark X against peers", "build a market map", or any request to systematically evaluate competitive dynamics across an industry.
> Analyzes unit economics by product or service using PayPal merchant insights and QuickBooks cost data, benchmarks against inflation and cost changes, and shows pricing-scenario data (e.g. "a 5% increase historically correlates with ~3% volume drop"). Surfaces analysis only — does not recommend a price. Use when the user asks about raising prices, pricing, margin analysis, what to charge, whether costs are eating into profit, or how a price change might affect their business. Trigger even if the user doesn't say "margin" explicitly — phrases like "am I making enough?", "should I charge more?", or "my costs are going up" all call for this skill.
Help users objectively assess where their product stands on the PMF spectrum by triangulating qualitative feedback, quantitative retention benchmarks, and organic growth signals.
Take datopian/portaljs-define-schema from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npx.
Without those the skill loads but fails at the first command.