changelog-site
Manage changelog entries, subscribers, and site settings for a self-hosted changelog publishing tool.
Best use case
changelog-site is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Manage changelog entries, subscribers, and site settings for a self-hosted changelog publishing tool.
Teams using changelog-site should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/changelog-site/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How changelog-site Compares
| Feature / Agent | changelog-site | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Manage changelog entries, subscribers, and site settings for a self-hosted changelog publishing tool.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Changelog Site Skill
## When to use
Use this skill to:
- Create, update, and publish changelog entries
- Manage the draft/published workflow
- List and remove email subscribers
- Configure site settings and SMTP credentials
- Retrieve entries for display or export
## Base URL
```
http://localhost:3000
```
No authentication is required. This API is intended for single-user local/self-hosted deployment.
## Quick Reference
| Action | Method | Path |
|---|---|---|
| List all entries | GET | /api/entries |
| Get single entry | GET | /api/entries/:slug |
| Create entry | POST | /api/entries |
| Update entry | PUT | /api/entries/:slug |
| Delete entry | DELETE | /api/entries/:slug |
| Publish entry | POST | /api/entries/:slug/publish |
| List subscribers | GET | /api/subscribers |
| Remove subscriber | DELETE | /api/subscribers/:id |
| Get settings | GET | /api/settings |
| Update settings | PUT | /api/settings |
## API Reference
### GET /api/entries
List entries. Defaults to published only.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
| status | string | published | "published", "draft", or "all" |
| category | string | - | Filter by category slug |
| limit | integer | 20 | Max entries per page |
| offset | integer | 0 | Pagination offset |
Example:
```bash
curl http://localhost:3000/api/entries?status=all&limit=10
```
Response:
```json
{
"entries": [
{
"id": 1,
"slug": "dark-mode-support",
"title": "Dark mode support across all pages",
"category": "added",
"version": "v3.4.0",
"is_draft": false,
"published_at": "2026-03-20T10:00:00.000Z",
"created_at": "2026-03-19T14:22:00.000Z"
}
],
"total": 18,
"offset": 0,
"limit": 20
}
```
### GET /api/entries/:slug
Get a single entry with full body content.
```bash
curl http://localhost:3000/api/entries/dark-mode-support
```
Response:
```json
{
"id": 1,
"slug": "dark-mode-support",
"title": "Dark mode support across all pages",
"category": "added",
"version": "v3.4.0",
"body_md": "We've added a full dark mode...\n\n## What's new\n\n- ...",
"body_html": "<p>We've added a full dark mode...</p>",
"is_draft": false,
"published_at": "2026-03-20T10:00:00.000Z",
"created_at": "2026-03-19T14:22:00.000Z",
"updated_at": "2026-03-20T09:55:00.000Z"
}
```
### POST /api/entries
Create a new entry. Saved as draft by default.
```bash
curl -X POST http://localhost:3000/api/entries \
-H "Content-Type: application/json" \
-d '{
"title": "Bulk export for all data types",
"category": "added",
"version": "v3.5.0",
"body_md": "You can now export data in bulk...\n\n## Formats\n\n- CSV\n- JSON"
}'
```
Response: `201 Created` with the created entry object including generated `slug`.
### PUT /api/entries/:slug
Update an existing entry (draft or published).
```bash
curl -X PUT http://localhost:3000/api/entries/bulk-export-for-all-data-types \
-H "Content-Type: application/json" \
-d '{
"title": "Bulk export for all data types",
"category": "added",
"version": "v3.5.0",
"body_md": "Updated body content..."
}'
```
### POST /api/entries/:slug/publish
Publish a draft entry. Sends email notifications to all confirmed subscribers and updates the RSS feed.
```bash
curl -X POST http://localhost:3000/api/entries/bulk-export-for-all-data-types/publish
```
Response:
```json
{
"slug": "bulk-export-for-all-data-types",
"published_at": "2026-03-20T11:30:00.000Z",
"notifications_sent": 247
}
```
### DELETE /api/entries/:slug
Delete an entry permanently.
```bash
curl -X DELETE http://localhost:3000/api/entries/dark-mode-support
```
Response: `204 No Content`
### GET /api/subscribers
List all subscribers.
Parameters:
| Name | Type | Default | Description |
|---|---|---|---|
| status | string | all | "confirmed", "pending", or "all" |
| limit | integer | 50 | Max per page |
| offset | integer | 0 | Pagination offset |
```bash
curl http://localhost:3000/api/subscribers?status=confirmed
```
Response:
```json
{
"subscribers": [
{
"id": 1,
"email": "alex.morgan@company.io",
"status": "confirmed",
"subscribed_at": "2026-03-18T08:00:00.000Z",
"last_notified_at": "2026-03-20T11:30:00.000Z"
}
],
"total": 247
}
```
### DELETE /api/subscribers/:id
Remove a subscriber immediately.
```bash
curl -X DELETE http://localhost:3000/api/subscribers/42
```
### GET /api/settings
Retrieve current site settings.
```bash
curl http://localhost:3000/api/settings
```
Response:
```json
{
"product_name": "Acme App",
"description": "Product updates, bug fixes, and new features.",
"public_url": "https://changelog.acmeapp.com",
"entries_per_page": 20,
"rss_enabled": true,
"email_notifications": true,
"smtp_host": "smtp.postmarkapp.com",
"smtp_port": 587,
"smtp_user": "api-key-abc123",
"from_address": "changelog@acmeapp.com"
}
```
Note: `smtp_password` is never returned by the API.
### PUT /api/settings
Update site settings.
```bash
curl -X PUT http://localhost:3000/api/settings \
-H "Content-Type: application/json" \
-d '{
"product_name": "Acme App",
"smtp_host": "smtp.postmarkapp.com",
"smtp_port": 587,
"smtp_user": "api-key-abc123",
"smtp_password": "new-secret",
"from_address": "changelog@acmeapp.com",
"email_notifications": true
}'
```
### POST /api/settings/test-email
Send a test email to verify SMTP configuration. Uses currently saved SMTP settings.
```bash
curl -X POST http://localhost:3000/api/settings/test-email \
-H "Content-Type: application/json" \
-d '{"to": "you@example.com"}'
```
## Entry Object
```typescript
interface Entry {
id: number;
slug: string; // URL-safe, auto-generated from title
title: string;
category: Category;
version: string | null; // e.g. "v3.4.0"
body_md: string; // Raw markdown source
body_html: string; // Sanitized HTML rendered from body_md
is_draft: boolean;
published_at: string | null; // ISO 8601
created_at: string;
updated_at: string;
}
type Category = "added" | "fixed" | "changed" | "deprecated" | "security" | "removed";
```
## Category values
| Value | Badge color | Use for |
|---|---|---|
| added | Green | New features and capabilities |
| fixed | Blue | Bug fixes and error corrections |
| changed | Amber | Behavior or configuration changes |
| deprecated | Orange | Features marked for future removal |
| security | Red | Vulnerability patches, CVEs |
| removed | Gray | Features fully removed |
## Error responses
All errors return JSON with a consistent shape:
```json
{
"error": "Entry not found",
"code": "NOT_FOUND"
}
```
| HTTP status | code | Meaning |
|---|---|---|
| 400 | VALIDATION_ERROR | Invalid input fields |
| 404 | NOT_FOUND | Entry or subscriber does not exist |
| 409 | CONFLICT | Slug already in use |
| 500 | INTERNAL_ERROR | Unexpected server error |
## Environment variables
| Variable | Default | Description |
|---|---|---|
| PORT | 3000 | HTTP server port |
| DATA_DIR | ./data | Directory for SQLite file |
| PUBLIC_URL | - | Full URL of the public changelog page |Related Skills
Skill: Uptime Monitoring
## Overview
Skill: Status Page
## Overview
Skill: unit-conversion
## Overview
Skill: recipe-scaler
## Overview
reading-list
Operate the reading-list API to save, manage, tag, search, and export articles.
email-digest
Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.
websocket-realtime
Use the WebSocket connection in poll-builder to receive live vote updates. Use when you need to stream real-time poll results, monitor a poll for new votes, or build a live dashboard. Triggers include "live results", "real-time updates", "stream votes", "watch poll", or "WebSocket".
poll-builder
Self-hosted poll creation tool with real-time results. Use when you need to create a poll, check vote counts, close a poll, export results, or get the shareable link for a poll. Triggers include "create poll", "vote", "poll results", "survey", "collect votes", "share poll", or any task involving polling or voting.
Skill: personal-finance
## Overview
Skill: csv-import
## Overview
Skill: Syntax Highlighting
## Purpose
Skill: Pastebin Core
## Purpose