From portaljs
Adds a resource file (e.g., data dictionary, methodology, additional data) to an existing dataset in a PortalJS portal. Converts single-file datasets to multi-resource for browsing per resource.
How this skill is triggered — by the user, by Claude, or both
Slash command
/portaljs:portaljs-add-resourceThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Add a resource — an additional file — to a dataset that already exists in a
Add a resource — an additional file — to a dataset that already exists in a
portaljs-catalog portal. Where /portaljs-add-dataset creates a new dataset
(one file), this skill adds a file to an existing one: a data dictionary, a
methodology document, or another data file (e.g. a second year's figures).
Mirrors the Frictionless Data Package model: a dataset holds a resources[] array,
and the showcase at /@<namespace>/<slug> renders one section per resource (preview,
schema, download). A single-file dataset migrates to resources[] automatically the
first time a second file is added — no data is lost.
portaljs-catalog template) with datasets.json,
package.json, and pages/[owner]/[slug].tsx present.datasets.json.npx next build for verification.The canonical, full step-by-step workflow lives in
.claude/commands/portaljs-add-resource.md
in this repository — that file is the single source of truth. Read and follow it. Summary:
DATASET (slug or namespace/slug), SOURCE
(path or URL), PORTAL_DIR (default .), RESOURCE_NAME, RESOURCE_TITLE,
DESCRIPTION. If DATASET or SOURCE is missing, list datasets from
datasets.json and ask./portaljs-add-dataset instead.PORTAL_DIR/public/data/ under a
non-colliding filename.datasets.json: if the dataset has no resources yet, migrate its
top-level file/format/schema into the first resource (lossless), then
append the new resource; if resources already exists, just append, keeping
name unique within the array.npx next build, capturing output to a log file; fix
malformed JSON before reporting success.✓ Resource added to DATASET: RESOURCE_TITLE (RESOURCE_NAME.EXT)
- Data file: public/data/RESOURCE_NAME.EXT
- Manifest: datasets.json (dataset now has <n> resources)
- Showcase: /@<namespace>/<slug> renders a section per resource
If this was the first migration to multi-resource, note that the dataset's single
file was moved into resources[] with no data lost.
| Symptom | Cause | Fix |
|---|---|---|
| "Dataset not found" | DATASET slug/namespace doesn't match any entry in datasets.json | List datasets from datasets.json and ask the user to pick, or run /portaljs-add-dataset to create it |
npx next build fails with a JSON parse error | Manually edited datasets.json has a trailing comma or unescaped character | Re-open the file, fix the JSON, and rebuild before reporting success |
| Resource file fails to fetch (non-2xx) | SOURCE URL is wrong, private, or the host is down | Confirm the URL in a browser or with curl -I SOURCE; ask for a corrected URL or a local path |
New resource's filename collides with an existing one in /public/data | Auto-derived RESOURCE_NAME matches an existing file stem | Pick a distinct RESOURCE_NAME, or let the skill append a numeric suffix |
| Showcase doesn't render the new section after build | name in the new resource object duplicates an existing resource's name | Rename the resource's name to something unique within that dataset's resources[] |
/portaljs-add-resource orders ./data/orders-data-dictionary.csv --title "Data dictionary"
orders was a single CSV. It is migrated to a two-resource dataset (the original
data plus the dictionary), and its showcase now renders a section for each.
/portaljs-add-resource climate-observations https://example.org/data/methodology.json --name methodology --title "Methodology notes"
The skill fetches the URL, checks the HTTP status, copies it to
public/data/methodology.json, and appends it to the existing resources[] array.
/portaljs-add-resource
With no arguments, the skill lists datasets from datasets.json, asks which one to
extend and for the new file's path or URL, then proceeds through steps 2-6 above.
.claude/commands/portaljs-add-resource.md — canonical workflow this skill followsreferences/reference.md — resource entry fields, single-to-multi-resource layout, troubleshooting/portaljs-add-dataset (create a new dataset), /portaljs-define-schema (describe a resource's fields)npx claudepluginhub datopian/portaljs --plugin portaljsRegisters a dataset (CSV/TSV/JSON/GeoJSON) in a PortalJS portal by appending to datasets.json, routing local files to R2 via Git LFS and remote URLs as passthrough.
Publishes and manages hosted assets (HTML sites, docs, file bundles) on the Octave assets service with privacy controls, share links, versioning, and access requests.
Finds and validates datasets for Data2Story blogs. Accepts a topic, URL, or category; downloads and checks against 4 completeness gates. Local-first with support for full re-fetch or validate-only audit.