NextDNS Skills is a structured knowledge collection for AI agents, enabling complex operations across the NextDNS ecosystem via domain-specific context injection:
- NextDNS API: Programmatic configuration, analytics, and log management.
- NextDNS CLI: Deployment, system configuration, and monitoring.
- NextDNS Web UI: Strategic configuration and dashboard-based management.
- Integrations: Third-party platform connections (OpenWrt, pfSense, Tailscale, and more).
- NextDNS Frontend: Nuxt 4, Next.js 15, Astro, SvelteKit, and React Router v7 patterns.
nextdns-skills/
├── skills/
│ ├── nextdns-api/ # 23 rules — API protocols and endpoints
│ │ ├── SKILL.md
│ │ └── rules/
│ ├── nextdns-cli/ # 24 rules — Deployment and system config
│ │ ├── SKILL.md
│ │ └── rules/
│ ├── nextdns-ui/ # 16 rules — Web dashboard strategy
│ │ ├── SKILL.md
│ │ └── rules/
│ ├── integrations/ # 20 rules — Platform connectivity
│ │ ├── SKILL.md
│ │ └── rules/
│ └── nextdns-frontend/ # 35 rules — Frontend frameworks
│ ├── SKILL.md
│ └── rules/
│ ├── astro/
│ ├── nextjs/
│ ├── nuxt/
│ ├── react-router/
│ └── sveltekit/
├── packages/
│ ├── nextdns-scripts/ # Validation and maintenance scripts
│ │ ├── dist/ # index.mjs, cli.mjs, shared chunks
│ │ ├── src/
│ │ │ ├── cli.ts
│ │ │ ├── index.ts
│ │ │ ├── commands/ # validate-rules, update-counts, checks, audit
│ │ │ ├── core/ # shared utilities and version helpers
│ │ │ └── __tests__/
│ │ ├── tsconfig.json
│ │ ├── vite.config.ts
│ │ └── vitest.config.ts
│ ├── nextdns-markdown/ # Shared remark AST and frontmatter utilities
│ │ ├── dist/ # index.mjs and declarations
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ └── __tests__/
│ │ ├── tsconfig.json
│ │ ├── vite.config.ts
│ │ └── package.json
│ └── nextdns-skills-build/ # Build tooling and programmatic API
│ ├── dist/ # index.mjs, cli.mjs, shared chunks
│ ├── src/
│ │ ├── cli.ts
│ │ ├── index.ts
│ │ ├── commands/ # build, validate, search, export, migrate
│ │ ├── core/ # config, parser, types, markdown, paths
│ │ └── __tests__/
│ ├── tsconfig.json
│ ├── vite.config.ts
│ └── vitest.config.ts
├── templates/
│ ├── rule-template.md
│ └── skill-template.md
├── data/schemas/
│ └── profile.json
├── tsconfig.json
├── pnpm-workspace.yaml
└── turbo.json
The two CLI packages declare their package-manager bin metadata directly as ./dist/cli.mjs; no
checked-in bin/ directory or wrapper is required. The pack step grants execute permission to the
CLI artifact and pnpm creates its .bin shim from the package metadata. Repository automation invokes
node dist/cli.mjs (or the root package's direct packages/*/dist/cli.mjs path) instead of relying on a
self-referential workspace bin shim during fresh CI installs.
The shared nextdns-markdown package owns unified/remark parsing, YAML normalization, MDAST
traversal helpers, and Valibot frontmatter validation. The two CLI packages consume it rather than
maintaining separate line-based frontmatter parsers.
Maintenance scripts: validate rule integrity, sync rule counts, check duplicates and tags, print
statistics, run the combined audit, and expose Valibot schemas for report consumers. Shared modules
are under src/core/; CLI commands are under src/commands/.
Exports:
{
"exports": {
".": { "import": "./dist/index.mjs" }
}
}CLI commands (nextdns-skills-scripts <command>):
| Command | Description |
|---|---|
validate-rules |
Frontmatter and referential integrity |
update-counts |
Sync rule counts in README.md |
check-duplicates |
Duplicate title detection |
check-tags |
Tag hygiene validation |
generate-stats |
Statistics report (--text) |
audit |
Combined structured maintenance audit (--json) |
Package scripts:
| Script | Description |
|---|---|
build |
vp pack — compile only index.mjs, cli.mjs, and required shared chunks to dist/ |
validate-rules |
Run validate-rules through dist/cli.mjs |
update-counts |
Run update-counts through dist/cli.mjs |
check-duplicates |
Run check-duplicates through dist/cli.mjs |
check-tags |
Run check-tags through dist/cli.mjs |
generate-stats |
Run generate-stats through dist/cli.mjs |
test |
vitest run |
test:coverage |
vitest run --coverage |
types:check |
tsc --noEmit |
schema API |
src/core/schemas.ts exports Valibot report schemas and safe parsers |
Build tooling: compile rule files into AGENTS.md, validate, scaffold, search, and export rules.
It validates CLI options with Valibot before filesystem work and exposes the same parsers through its
programmatic API.
Exports:
{
"exports": {
".": { "import": "./dist/index.mjs" }
}
}CLI commands (nextdns-skills-build <command>):
| Command | Description |
|---|---|
build |
Build AGENTS.md (--all or --skill=<name>) |
validate |
Validate rule frontmatter and structure |
search |
Search rules (--query=, --tag=, --skill=, --impact=, --json) |
export |
Export rules to JSON/CSV (--format=, --out=, --skill=) |
extract-tests |
Extract test cases from rules for LLM evaluation |
migrate |
Scaffold a new rule file from template |
Package scripts:
| Script | Description |
|---|---|
build |
vp pack — compile only index.mjs, cli.mjs, and required shared chunks to dist/ |
build-all |
Build AGENTS.md for all skills |
build-api |
Build nextdns-api only |
build-cli |
Build nextdns-cli only |
build-frontend |
Build nextdns-frontend only |
build-integrations |
Build integrations only |
build-ui |
Build nextdns-ui only |
validate |
Validate rule files |
search |
Search rules |
export |
Export rules to JSON or CSV |
extract-tests |
Extract test cases |
migrate |
Scaffold a new rule |
test |
vitest run |
test:coverage |
vitest run --coverage |
types:check |
tsc --noEmit |
Both packages share one root tsconfig.json extended by each package. Reusable modules belong in
src/core/, command implementations belong in src/commands/, and src/cli.ts is the dispatcher.
Enforced settings:
strict: true,noUncheckedIndexedAccess: true,exactOptionalPropertyTypes: trueverbatimModuleSyntax: true— always useimport typefor type-only imports- Array/object index access returns
T | undefined— guard with?? fallbackor check first - Omit optional properties instead of assigning
undefined - Forbidden:
any,object,Function, non-null assertions (!) without a type guard, andas Tcasts without prior narrowing
Run pnpm -F <package> types:check before committing TypeScript changes.
skills/{category}/
SKILL.md # Category manifest with keyword index
rules/
{rule-name}.md # kebab-case filename
Category names and rule filenames are always kebab-case.
Use templates/skill-template.md. Required frontmatter:
name: matches directory name exactlydescription: 2–4 sentences with trigger keywords — critical for AI activationmetadata:author(tuanductran) andversion(semantic)
Every rule file must be registered in either the Capability or Efficiency table in the
manifest. Adding a rule without updating SKILL.md in the same commit is a protocol violation.
Use templates/rule-template.md. Required frontmatter:
| Field | Values |
|---|---|
title |
Exact match with H1 heading |
impact |
HIGH, MEDIUM, or LOW |
impactDescription |
One sentence — consequence of non-compliance |
type |
capability or efficiency |
tags |
3–10 keywords, YAML array format |
Required sections in order: H1 heading (followed by a one-line description), Overview,
Correct usage (✅), Do NOT use (❌), Troubleshooting, Reference.
- Atomic commits: a rule change and its
SKILL.mdupdate must be in the same commit. - Header casing: use
X-Api-Keyonly. Add<!-- @case-police-ignore Api -->at the top of any Markdown file referencing it. - Terminology:
profile(not configuration),blocklist(not blacklist),allowlist(not whitelist). - Zero-PII: never commit real API keys or profile IDs — use
YOUR_API_KEY,abc123,example.com. - Conventional commits:
type(scope): description— for example,feat(api): add rewrite rule. - Schema consistency: sync structural changes with
data/schemas/profile.json.
Applies to skills/nextdns-frontend/ only. Frameworks: Nuxt 4, Next.js 15, Astro, SvelteKit,
React Router v7.
All code examples must compile under:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}Error handling: catch values are unknown — narrow with instanceof Error before accessing
.message. Surface errors via the framework's error mechanism (error(), ErrorBoundary,
useFormState). Never swallow errors silently.
Accessibility: use semantic HTML, add aria-label to interactive elements without visible
text, loading states need aria-live="polite" or role="status", never convey state with color
alone.
Testing: data-fetching or mutation rules must include a Testing subsection with a mock of the NextDNS API call, one happy-path assertion, and one error-path assertion.
Run before finalising any changes:
| Command | Purpose |
|---|---|
pnpm lint:fix |
Auto-fix formatting (oxfmt), code (oxlint), markdown, and syntax |
pnpm lint:rules |
Validate frontmatter and referential integrity via Turbo |
pnpm lint:all |
Full check including external link and duplicate-code validation |
pnpm lint:duplicates |
Detect duplicate production TypeScript blocks using .jscpd.json |
pnpm check-duplicates |
Detect duplicate titles (ERROR within skill, WARN across) |
pnpm check-tags |
Validate tag count (3–10), uniqueness, and casing |
pnpm update-counts |
Sync rule counts in README.md |
pnpm types:check |
Type-check all packages via Turbo |
pnpm test |
Run Vitest across both packages |
pnpm test:coverage |
Run tests with v8 coverage report |
After modifying rule files, rebuild the compiled output:
pnpm build:skills # All skills
pnpm build:api # nextdns-api only
pnpm build:cli # nextdns-cli only
pnpm build:ui # nextdns-ui only
pnpm build:integrations # integrations only
pnpm build:frontend # nextdns-frontend onlyFollow the Atlassian content guidelines.
- Sentence case for all headings
- Active voice — lead with verbs
- No abbreviations (
for example, note.g.;that is, noti.e.) - No trailing catch-alls (
and more, notetc.) - Spell out conjunctions (
and, not&)
Fixed terminology:
| Use | Never use |
|---|---|
profile |
configuration, config |
blocklist |
blacklist, denylist |
allowlist |
whitelist, passlist |
X-Api-Key |
X-API-Key, x-api-key |
Claude Code: cp -r skills/{category} ~/.claude/skills/
claude.ai: attach SKILL.md and relevant rules to the project context.