# Authoring

> Write focused instructions. Add catalog metadata and check the file format.

A contribution has two parts: an instruction file and a catalog record. The website does not generate its catalog by scanning Markdown files. Adding only a file makes it available to the shell installer, but does not add a web catalog entry.

## Prerequisites

Work in a checkout of `n3wth/n3wth` and read the root and `apps/skills/AGENTS.md` instructions. Use Node 24 and npm 11.19.1 for workspace development. Run commands below from the repository root unless stated otherwise.

Choose one task, a unique lowercase hyphenated ID, and a matching and unrelated prompt to test. Check the current catalog for overlapping skills before adding another workflow.

## Write the instructions

Use `apps/skills/skills/<id>.md` for a self-contained file or `apps/skills/skills/<id>/SKILL.md` for a folder. Prefer a folder when the instructions need sibling references, templates, or scripts. The shell installer copies the folder; direct downloads and CLI installs copy only the Markdown content.

For example, create `apps/skills/skills/release-notes.md`:

```markdown
---
name: release-notes
description: Draft release notes from a supplied Git diff when the user asks to summarize a release.
version: 1.0.0
author: your-name
category: development
tags:
  - releases
  - documentation
compatibility:
  - gemini
---

# Release notes

## Triggers

Use when the user supplies a diff and requests release notes.
Do not use for a general code review or a release with no source evidence.

## Instructions

1. Identify user-visible changes in the supplied diff.
2. Group them under Added, Changed, and Fixed; omit empty groups.
3. Link each claim to a changed file or supplied issue.
4. Flag missing migration details instead of inventing them.

## Example

Input: A diff adds a CSV export button to the reports page.
Output: Added — Reports can now be exported as CSV.

## Constraints

Draft text only. Do not publish a release or change Git state.
```

`name` and `description` express identity and when to use the skill. Existing catalog files also use version, author, category, tags, and compatibility metadata. These files are not uniformly governed by the stricter Python package validator described below.

Keep tool prerequisites and expected output in the body. Include failure handling for missing inputs. Test whether a relevant request follows the instructions and whether an unrelated request stays outside the skill's scope.

## Add the web catalog record

Insert an object into the exported `skills` array in `apps/skills/src/data/skills.ts`. This example uses the existing `GITHUB_RAW_BASE` constant:

```typescript
{
  id: 'release-notes',
  name: 'Release Notes',
  description: 'Draft release notes from a supplied Git diff.',
  category: 'development',
  tags: ['releases', 'documentation'],
  icon: 'R',
  color: 'oklch(0.70 0.15 280)',
  compatibility: ['gemini'],
  version: '1.0.0',
  lastUpdated: '2026-09-17',
  skillFile: `${GITHUB_RAW_BASE}/release-notes.md`,
},
```

Use your actual update date. For a folder, set `skillFile` to `${GITHUB_RAW_BASE}/release-notes/SKILL.md`. The raw URL points at `main`, so a new file on a feature branch will not be downloadable from that URL until merged.

| Field | Requirement and use |
| --- | --- |
| `id` | Required string; unique, matching the file or folder ID |
| `name`, `description` | Required strings; display text and search inputs |
| `category` | Required; `development`, `documents`, `creative`, `productivity`, or `business` |
| `tags` | Required string array; searchable keywords |
| `icon`, `color` | Required strings; use a simple symbol or letter and an OKLCH color |
| `version`, `lastUpdated` | Required strings; follow semantic-version and `YYYY-MM-DD` conventions |
| `skillFile` | Optional in the type; required for a standard website download command |
| `compatibility` | Optional array; the configured assistant ID is `gemini` |
| `features`, `useCases`, `samplePrompts` | Optional descriptive content; keep claims grounded in the instructions |
| `contributor` | Optional object with `name`, and optional `github` and `url` |
| `relatedSkillIds`, `faq`, `extraInstallCommands` | Optional detail-page content; see the exported interface for structure |

If the contribution also needs to appear in the CLI, maintain its separate catalog in `apps/skills/cli/src/utils/skills.ts`. A web catalog edit alone does not update the CLI. Do not claim a download URL exists until the instruction file is committed at that path.

## Validate a catalog contribution

The existing catalog tests check structure, unique IDs, category counts, configured compatibility, and whether advertised local download paths exist. In a development checkout with dependencies installed, run:

```bash
npm run test:unit --workspace @n3wth/skills -- \
  src/data/skills.test.ts src/data/skills-files.test.ts
```

For the full app check, the repository documents `npm run check --workspace @n3wth/skills`. It includes typecheck, lint, unit tests, and a production build; run it only in a checkout where generating build outputs is appropriate.

Tests that confirm a local file exists do not verify the deployed URL, assistant discovery, or behavior of the instructions. Review those separately after publication.

## The Python validator uses a different schema

`apps/skills/scripts/validate-skill.py` accepts a **directory containing `SKILL.md`**, despite its usage text showing a flat `pdf.md` example. It requires Python 3 and the `yaml` module supplied by PyYAML.

Its required frontmatter keys are `name`, `slug`, `description`, `author`, `version`, `categories`, `platforms`, and `status`. To intentionally use this package format, start with:

```yaml
---
name: Release Notes
slug: release-notes
description: Draft release notes from a supplied Git diff.
author: your-name
version: 1.0.0
categories: [development]
platforms: [gemini-cli]
status: experimental
---
```

Then validate the directory:

```bash
python3 apps/skills/scripts/validate-skill.py apps/skills/skills/release-notes
```

Accepted statuses are `experimental`, `beta`, `stable`, and `deprecated`. Missing `scripts`, `templates`, or `references` directories produce warnings. Unknown platform values also produce warnings; `gemini-cli` is the recognized value here, distinct from the catalog's `gemini` ID.

Do not treat a failure against this schema as proof that a flat catalog skill is invalid. Choose the validation appropriate to the layout you are authoring.

## Troubleshooting

| Problem | Likely cause |
| --- | --- |
| New file does not appear on the website | Missing record in the web `skills` array |
| Catalog test reports a missing download | `skillFile` suffix does not match a committed file path |
| New branch's download returns 404 | Raw URL targets `main`, where the file is not yet merged |
| Validator says path is not a directory | A flat file was passed to the package-only Python validator |
| Validator reports missing metadata | Catalog metadata and package-validator metadata use different fields |
| References disappear after installation | A single-file download was used for a folder with sibling resources |

## Sources

- [Skill interface and web catalog](https://github.com/n3wth/n3wth/blob/main/apps/skills/src/data/skills.ts)
- [Contributor template](https://github.com/n3wth/n3wth/blob/main/apps/skills/src/data/skillTemplate.ts)
- [Skill Creator instructions](https://github.com/n3wth/n3wth/blob/main/apps/skills/skills/skill-creator.md)
- [Download-path tests](https://github.com/n3wth/n3wth/blob/main/apps/skills/src/data/skills-files.test.ts)
- [Package validator](https://github.com/n3wth/n3wth/blob/main/apps/skills/scripts/validate-skill.py)
