portaljs-deploy

portaljs-deploy is a command for Claude Code from datopian/portaljs. It costs 46 tokens per session (4,768 once invoked), scanned B, original, MIT.

A deployment command for publishing a PortalJS portal, a website for browsing datasets, to PortalJS Arc, Datopian's managed static hosting service. It builds the portal, uploads the static files, and returns a live web address.

In plain words
What is it for?
Use it to deploy a Next.js PortalJS catalog to an Arc subdomain. It supports static exports; server-rendered pages are not hosted there.
Why use it?
It packages and publishes an existing PortalJS project without requiring you to handle the hosting upload yourself. Repeating the command updates the portal under the same address.

Command for Claude Code

Part of the portaljs plugin — 14 skills, 25 commands shipped together

About the project

PortalJS is a framework for building data portals that present searchable datasets through a home page, catalog, and dataset showcase. It is for teams that want to choose a data backend, scaffold a Next.js portal, load CSV or JSON data, connect services such as CKAN, and deploy the result. The catalogue entries are agent commands, skills, instructions, and a plugin that guide portal creation and data loading.

datopian/portaljs · 2,349 stars · on GitHub

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add commands/datopian/portaljs/portaljs-deploy
Clone the repo
git clone --depth 1 https://github.com/datopian/portaljs

Made for: Claude Code.

Or install portaljs, the plugin that ships this one along with the rest of its 14 skills, 25 commands.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for portaljs-deploy

README.md
[![agentmods](https://agentmods.dev/badge/commands/datopian/portaljs/portaljs-deploy.svg)](https://agentmods.dev/commands/datopian/portaljs/portaljs-deploy)
Your own site
<a href="https://agentmods.dev/commands/datopian/portaljs/portaljs-deploy"><img src="https://agentmods.dev/badge/commands/datopian/portaljs/portaljs-deploy.svg" alt="Measured on agentmods" height="20"></a>
Per session 46 Only the description is in the session, so the agent can decide to use it. The body loads when it is invoked.
When invoked 4,768 The whole file, excluding the scripts and references it only reads on demand.
Security scan B 3 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00046 $0.04768
Opus 5 $0.00023 $0.02384
Sonnet 5 $0.00009 $0.00954
Haiku 4.5 $0.00005 $0.00477

Measured 5d ago against content hash 1f07a989df14, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade B, and why

portaljs-deploy scanned grade B with 3 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 5d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Asks for rootmediumPrivilege escalation

A mod that escalates privileges can change anything on the machine, not only the project.

HDR=$(mktemp); chmod 600 "$HDR"

Makes network callslowCapability

Not a fault in itself. Listed so you know the mod talks to something, and to what.

# Pass the bearer token via a 0600 curl config file, not argv — so it doesn't leak

Runs shell commandslowCapability

Expected in a hook, worth knowing in a rule or an instructions file.

import { spawn } from 'node:child_process'
.claude/commands/portaljs-deploy.md · 346 lines

How it starts

The opening of the file, as written. The whole thing — 346 lines — stays where its author put it; the contents beside it link to each section on GitHub.

/portaljs-deploy

Publish an existing PortalJS portal to PortalJS Arc — Datopian's managed static hosting. The skill builds a static export of the portal, uploads it to the Arc API, and prints a live https://<slug>.arc.portaljs.com URL. Re-running redeploys the same portal (idempotent on the slug).

This is a single-target skill: it deploys to PortalJS Arc only. If you'd rather host the portal yourself, it's a standard static Next.js export — run npm run build and upload out/ to any static host (Vercel, your own Cloudflare, Netlify, S3, …); you don't need this skill for that.

Static only (for now). Arc serves static exports — the catalog template, /portaljs-add-dataset, /portaljs-migrate, and /portaljs-connect-ckan (SSG) all export cleanly. SSR isn't hosted on Arc yet.

Required input — ask, don't error

  • Portal directory (optional) — the portal project (default: current directory). Must be a Next.js portal (package.json with a next dependency).
  • Slug (optional) — the subdomain to publish under (<slug>.arc.portaljs.com). Default: the project's package.json name (or the directory name), slugified. Override with --slug <name>.
  • Auth — a PortalJS Arc token. Read from PORTALJS_TOKEN, else ~/.portaljs/credentials ({ "token": "…" }). If neither is present, sign in on demand (one browser click — device flow, see step 2) to obtain and store one, then continue. Auth is never a separate step the user runs; /portaljs-deploy handles it. Don't ask the user to copy a token by hand.

Steps

1. Gather input + validate the portal

Extract from $ARGUMENTS:

  • PORTAL_DIR (default .), SLUG (default from package.json name / dir, slugified to a DNS label: lowercase, [a-z0-9-], ≤63 chars).

Confirm PORTAL_DIR/package.json exists and lists next. If not:

ERROR: [deploy] NOT_A_PORTAL No Next.js project in <dir> — run from a portal directory.

Reserved slugs (www, api, admin, staging, arc) are not allowed — if the derived slug is reserved or invalid, ask for a --slug.

Read the full file on GitHub · 346 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 5d ago First seen · 346 lines · 46 tokens per session scan B 1f07a989df14

Subscribe to this mod's changes

portaljs-deploy is a command published in the GitHub repository datopian/portaljs (2,349 stars, last pushed yesterday), licensed MIT. It adds 46 tokens to every session and 4,768 once invoked, about $0.0002 per session on Opus 5. A static security scan graded it B with 3 findings (asks for root, makes network calls, runs shell commands). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.