feat(templates): promote examples/ to templates/<author>/<name>/ catalog layout

Set up the catalog directory structure this branch will fill with
community templates. The existing site-status-checker example moves
from examples/templates/ to templates/awizemann/site-status-checker/
(tracked by git as a rename so history is preserved). The examples/
directory is removed.

New top-level docs:
- templates/README.md — landing for folks browsing the catalog on
  github.com. Lists the current templates and points at the live site.
- templates/CONTRIBUTING.md — author-facing submission walkthrough.
  Requires AGENTS.md, pre-flight with tools/build-catalog.py --check
  (added in the next commit), one template per PR, don't edit
  catalog.json (maintainer regenerates it post-merge).

ProjectTemplateExampleTemplateTests.locateExample updated to search
templates/<author>/<name>/ instead of examples/templates/ — the test
still walks up from #filePath to find the repo root so it works in
both xcodebuild and Xcode IDE test runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alan Wizemann
2026-04-22 22:52:42 +01:00
parent 38c075d61d
commit d8a0a89db2
10 changed files with 201 additions and 42 deletions
+142
View File
@@ -0,0 +1,142 @@
# Contributing a template to Scarf
Thanks for packaging something up for other Scarf users. This guide walks you through the full submission flow end-to-end.
## Before you start
- You need Scarf 2.2 or later installed to build + test your template.
- Your template must ship a cross-agent **`AGENTS.md`** — that's the Linux Foundation open standard ([agents.md](https://agents.md/)) every major coding agent reads. Templates without one are rejected; Scarf specifically supports agent-portable projects.
- Templates are free and MIT-licensed implicitly by submission. Don't submit anything you don't have rights to.
## What makes a good template
- **Scoped.** One purpose per template. A "does-everything" template is harder to maintain than three focused ones.
- **Agent-first.** The `AGENTS.md` tells any agent how to interact with your project. Spell out the project layout, what each file is for, and what the agent should do when the user asks common questions ("run the X job", "add a Y").
- **Self-contained prompts.** Cron jobs + skills should not assume state the template doesn't ship. If you need a `sites.txt`, have `AGENTS.md` tell the agent to bootstrap it on first run (see `awizemann/site-status-checker` for the pattern).
- **Paused by default.** Every cron job ships disabled — Scarf pauses new jobs on install. Write prompts that work whether fired by cron or invoked directly in chat.
- **No secrets.** No API keys, no hostnames, no paths specific to your machine. The catalog's CI secret-scan will block obvious cases but this is on you.
- **No config writes.** Templates must not modify `~/.hermes/config.yaml`, `auth.json`, or any credential path. The installer refuses v1 bundles that claim to. If you need integration with, say, a specific MCP server, document the prerequisite in your README instead of trying to install it.
## Step-by-step submission
### 1. Fork + clone
```bash
gh repo fork awizemann/scarf --clone && cd scarf
```
### 2. Create your template directory
```bash
mkdir -p templates/<your-github-handle>/<your-template-name>/staging
cd templates/<your-github-handle>/<your-template-name>/staging
```
Directory names are lowercase, hyphenated, stable: people will type them.
### 3. Author the bundle
Minimum required files under `staging/`:
- **`template.json`** — manifest. Schema:
```json
{
"schemaVersion": 1,
"id": "<your-handle>/<your-template-name>",
"name": "Your Template Name",
"version": "1.0.0",
"minScarfVersion": "2.2.0",
"minHermesVersion": "0.9.0",
"author": { "name": "Your Name", "url": "https://…" },
"description": "One-line pitch shown in the catalog.",
"category": "monitoring",
"tags": ["short", "list"],
"contents": {
"dashboard": true,
"agentsMd": true,
"cron": 0,
"instructions": null,
"skills": null,
"memory": null
}
}
```
The `contents` claim must exactly match what's in `staging/` — the validator cross-checks and rejects mismatches.
- **`README.md`** — shown on the catalog detail page. Include: what the project does, what the user has to do after install, how to customize, how to uninstall.
- **`AGENTS.md`** — the cross-agent spec. Include: project layout, first-run bootstrap (if any), what each cron job expects to happen, and answers to common user prompts (`"what's the status"`, `"add a X"`, etc.).
- **`dashboard.json`** — the Scarf dashboard that renders on the catalog detail page and after install. See [awizemann/site-status-checker/staging/dashboard.json](awizemann/site-status-checker/staging/dashboard.json) for the schema in action.
Optional:
- `instructions/CLAUDE.md`, `instructions/GEMINI.md`, `instructions/.cursorrules`, `instructions/.github/copilot-instructions.md` — agent-specific shims beyond `AGENTS.md`.
- `skills/<skill-name>/SKILL.md` — shipped skills, installed into `~/.hermes/skills/templates/<slug>/` on the user's side.
- `cron/jobs.json` — an array of cron job specs. Each has `name`, `schedule` (e.g. `0 9 * * *` or `every 2h`), `prompt`, optional `deliver`, `skills[]`, `repeat`.
- `memory/append.md` — markdown appended to the user's `MEMORY.md` between template-specific markers. Use sparingly — most templates don't need this.
### 4. Build the bundle
From the `staging/` directory:
```bash
cd ..
zip -qq -r <your-template-name>.scarftemplate staging/
mv <your-template-name>.scarftemplate . # end up alongside staging/
```
Or equivalently:
```bash
cd staging && zip -qq -r ../<your-template-name>.scarftemplate . && cd ..
```
### 5. Test locally in Scarf
1. Open Scarf → Projects → Templates → **Install from File…** → select your `.scarftemplate`.
2. Walk through the preview sheet. Make sure every file, cron job, and memory block shown is something you meant to ship.
3. Install into a scratch parent dir. Verify the dashboard renders. Enable the cron job(s) if any and trigger them manually to confirm your `AGENTS.md` drives the right behavior.
4. Right-click the project → **Uninstall Template…** → verify nothing unexpected remains.
### 6. Validate
Before opening the PR, run the catalog validator locally:
```bash
python3 tools/build-catalog.py --check
```
This checks every template in the repo (including yours), verifies the manifest matches the bundle contents, refuses bundles >5 MB, and flags common secret patterns. If it fails, fix the reported issues before pushing.
### 7. Open the PR
```bash
git checkout -b add-<your-template-name>
git add templates/<your-handle>/<your-template-name>
git commit -m "feat(templates): add <your-template-name>"
git push origin add-<your-template-name>
gh pr create
```
**Do not modify `templates/catalog.json`** — the maintainer regenerates it after merge to keep PR diffs small.
GitHub Actions runs the validator on your PR. A green check means the bundle structure is sound; it doesn't mean the content is approved. Expect a maintainer pass for content quality (is the `AGENTS.md` clear, does the prompt do what you describe, is the scope reasonable).
### 8. Iterate + ship
Respond to review feedback. Common requests:
- Sharpen the `README.md` so install/uninstall steps are copy-pasteable.
- Split ambitious cron prompts into smaller, clearly-scoped ones.
- Remove things the template doesn't need (an empty `skills/` dir, an unused `deliver` target, etc.).
Once merged, your template shows up at `https://awizemann.github.io/scarf/templates/<your-handle>-<your-name>/` within a few minutes (the maintainer pushes the site regeneration by hand).
## Updating an existing template
Bump `version` in `template.json`, rebuild the `.scarftemplate`, commit, PR. The Install button on the catalog always points at the latest `main` version — there's no per-version pinning in v1. Users who already installed get no automatic update; they'd have to uninstall + reinstall for v2.
## Questions?
Open a [GitHub Discussion](https://github.com/awizemann/scarf/discussions) — the tag `templates` is watched.
+52
View File
@@ -0,0 +1,52 @@
# Scarf Templates
The community template catalog for [Scarf](https://github.com/awizemann/scarf) — a macOS GUI for the Hermes AI agent. Each subdirectory here is one installable project template. Browse the live catalog with live dashboard previews at **<https://awizemann.github.io/scarf/templates/>**.
## What's a template?
A `.scarftemplate` bundle ships:
- A pre-configured project **dashboard** (widgets for stats, lists, text, charts).
- A cross-agent **`AGENTS.md`** ([agents.md standard](https://agents.md/)) that tells Claude Code, Cursor, Codex, Aider, Jules, Copilot, Zed, etc. how to work with the project.
- Optional **skills**, **cron jobs**, optional per-agent instruction shims (`CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `.github/copilot-instructions.md`), and an optional **memory appendix**.
Users install with one click from the catalog site or by opening a `.scarftemplate` file in Scarf.
## Layout
Each template lives at `templates/<github-handle>/<template-name>/` with:
```
templates/<github-handle>/<template-name>/
├── staging/ source tree
│ ├── template.json manifest (id, name, version, contents claim)
│ ├── README.md shown on catalog detail page
│ ├── AGENTS.md required cross-agent instructions
│ ├── dashboard.json rendered as a live preview on the catalog site
│ ├── instructions/… optional per-agent shims
│ ├── skills/… optional namespaced skills
│ ├── cron/jobs.json optional cron job definitions
│ └── memory/append.md optional memory appendix
├── <template-name>.scarftemplate built bundle (zipped staging/), committed as-is
└── screenshots/ optional PNGs for the detail page
```
The built `.scarftemplate` is served directly from `raw.githubusercontent.com` — the catalog's Install button links at:
```
scarf://install?url=https://raw.githubusercontent.com/awizemann/scarf/main/templates/<author>/<name>/<name>.scarftemplate
```
## Contributing a template
See [CONTRIBUTING.md](CONTRIBUTING.md) for the full submission walkthrough. tl;dr: fork, drop a template under `templates/<your-handle>/<your-name>/`, open a PR. A CI check validates the bundle; a maintainer reviews the content.
## Catalog metadata
`catalog.json` at this directory is the aggregate index that the website reads. It's regenerated by the maintainer on merge — **do not modify it in your PR**, the build script will take care of it.
## Current templates
| Template | Author | Description |
|---|---|---|
| [site-status-checker](awizemann/site-status-checker/) | awizemann | Daily HTTP uptime check for a user-editable list of URLs. Dashboard + cron + AGENTS.md. |
@@ -0,0 +1,66 @@
# Site Status Checker — Agent Instructions
This project maintains a daily uptime check for a short list of URLs. The same instructions apply whether you're Hermes, Claude Code, Cursor, Codex, Aider, or any other agent that reads `AGENTS.md`.
## Project layout
- `sites.txt` — one URL per line. Lines starting with `#` are comments. This is the source of truth for what to check. **Not shipped with the template** — created on first run (see below).
- `status-log.md` — append-only markdown log. Newest run at the top. Each run is a section with the ISO-8601 timestamp as the heading. Also created on first run.
- `.scarf/dashboard.json` — Scarf dashboard. **Only the `value` fields of the three stat widgets and the `items` array of the "Watched Sites" list widget should be updated.** The section titles, widget types, and structure must stay intact.
## First-run bootstrap
If `sites.txt` doesn't exist in the project root, create it with this starter content and tell the user you did:
```
# One URL per line. Lines starting with # are comments.
# Replace these placeholders with the sites you want to watch.
https://example.com
https://example.org
```
If `status-log.md` doesn't exist, create it with a one-line header:
```
# Site Status Log
Newest run at the top. Each section is a single check.
```
## What to do when the cron job fires
The cron job runs this project's "Check site status" prompt. When invoked:
1. Read `sites.txt` in the project root. Ignore empty lines and `#`-prefixed comments. Expect plain URLs; be tolerant of whitespace around them.
2. For each URL, make an HTTP GET request with a 10-second timeout. Follow up to 3 redirects. Treat any 2xx or 3xx response as **up**, anything else (including timeouts and DNS failures) as **down**.
3. Build a results table: URL, status (up/down), HTTP code (or error reason), response time in milliseconds.
4. Prepend a new section to `status-log.md`:
```
## <ISO-8601 timestamp>
| URL | Status | Code | Latency |
|-----|--------|------|---------|
| … | up | 200 | 142 ms |
| … | down | timeout | — |
```
5. Update `.scarf/dashboard.json`:
- `Sites Up` stat widget: `value` = count of up results.
- `Sites Down` stat widget: `value` = count of down results.
- `Last Checked` stat widget: `value` = the ISO-8601 timestamp you just wrote.
- `Watched Sites` list widget `items`: one entry per URL with `text` = URL and `status` = `"up"` or `"down"` (lowercase).
6. If the cron job has a `deliver` target set, emit a one-line summary (`3 up, 1 down — example.com timed out`) as the agent's final response so the delivery mechanism picks it up.
## What not to do
- Don't modify the structure of `dashboard.json` (section titles, widget types, widget titles, `columns`). Only the values listed above are writable.
- Don't truncate `status-log.md` — it's the historical record. If it grows past 1 MB, add a one-line note at the top of the file asking the user to archive it.
- Don't invent URLs. If `sites.txt` is empty or missing, leave the dashboard untouched and write a single `status-log.md` entry noting "no sites configured."
- Don't run browsers or headless Chrome. Plain HTTP GET is sufficient.
## When the user asks you things
- "What's the status of my sites?" — read the top section of `status-log.md` and summarize.
- "Add a site" — append the URL to `sites.txt` on its own line. Don't sort or reorder existing entries. Confirm back to the user which URL you added.
- "Remove a site" — delete the matching line from `sites.txt`. If multiple match, ask before choosing.
- "Run the check now" — do everything in the cron flow above, then summarize the results in chat.
- "Why is [site] down?" — read the last 3-5 entries for that URL in `status-log.md` and report any pattern you see (consistent timeouts, intermittent 5xx, DNS failures, etc.). Don't speculate beyond what the log shows.
@@ -0,0 +1,33 @@
# Site Status Checker
A minimal uptime watchdog that pings a list of URLs once a day, records pass/fail results, and keeps a simple Scarf dashboard up to date.
## What you get
- **`sites.txt`** — one URL per line. This is the source of truth for what the cron job checks. Edit it to add or remove sites.
- **`status-log.md`** — the agent's append-only log of check results. New runs append a section at the top.
- **`.scarf/dashboard.json`** — Scarf dashboard with live stat widgets (sites up, sites down, last checked), the full list of watched sites with their last-known status, and a usage guide.
- **Cron job `Check site status`** — registered (paused) by the installer; tag `[tmpl:awizemann/site-status-checker]`. Runs daily at 9:00 AM when enabled. The prompt tells the agent to read `sites.txt`, check each URL, write results to `status-log.md`, and update the stat widgets in `dashboard.json`.
## First steps
1. Open the **Cron** sidebar and enable the `[tmpl:awizemann/site-status-checker] Check site status` job. It's paused on install so nothing runs without your explicit say-so.
2. Edit `sites.txt` in your project root — replace the two placeholder URLs with the sites you actually want to watch.
3. From the project's dashboard, ask your agent to run the job now: "Run the site status check and update the dashboard."
4. Future runs happen automatically at 9 AM daily.
## Customizing
- **Change the schedule.** Edit the cron job in the Cron sidebar — the schedule field accepts `30m`, `every 2h`, or standard cron expressions like `0 9 * * *`.
- **Change what "down" means.** By default the agent treats any non-2xx HTTP response as down. If you want to check for specific strings in the body (e.g. "Maintenance"), tell the agent in `AGENTS.md` and it will adapt.
- **Add alerting.** Set a `deliver` target on the cron job (Discord, Slack, Telegram) — the agent will post the run summary there instead of just writing to `status-log.md`.
## Uninstalling
Templates don't auto-uninstall in Scarf 2.2. To remove this one by hand:
1. Delete this project directory (removes the dashboard, AGENTS.md, sites.txt, status-log.md).
2. Remove the project entry from the Scarf sidebar (click the `` next to the project name).
3. Delete the `[tmpl:awizemann/site-status-checker] Check site status` cron job from the Cron sidebar.
No memory appendix or skills were installed, so nothing else needs cleanup.
@@ -0,0 +1,7 @@
[
{
"name": "Check site status",
"schedule": "0 9 * * *",
"prompt": "Run the site status check for this project. Follow the instructions in AGENTS.md: read sites.txt, HTTP GET each URL, prepend a results section to status-log.md, and update the three stat widgets plus the Watched Sites list items in .scarf/dashboard.json. When done, reply with a one-line summary like '3 up, 1 down — example.com timed out'."
}
]
@@ -0,0 +1,64 @@
{
"version": 1,
"title": "Site Status",
"description": "Daily uptime check for your watched URLs. The stat widgets and list update automatically when the cron job runs.",
"theme": { "accent": "green" },
"sections": [
{
"title": "Current Status",
"columns": 3,
"widgets": [
{
"type": "stat",
"title": "Sites Up",
"value": 0,
"icon": "checkmark.circle.fill",
"color": "green",
"subtitle": "responded 2xx/3xx"
},
{
"type": "stat",
"title": "Sites Down",
"value": 0,
"icon": "xmark.circle.fill",
"color": "red",
"subtitle": "non-2xx, timeout, DNS"
},
{
"type": "stat",
"title": "Last Checked",
"value": "never",
"icon": "clock",
"color": "blue",
"subtitle": "ISO-8601 timestamp"
}
]
},
{
"title": "Watched Sites",
"columns": 1,
"widgets": [
{
"type": "list",
"title": "Configured Sites (from sites.txt)",
"items": [
{ "text": "https://example.com", "status": "unknown" },
{ "text": "https://example.org", "status": "unknown" }
]
}
]
},
{
"title": "How to Use",
"columns": 1,
"widgets": [
{
"type": "text",
"title": "Quick Start",
"format": "markdown",
"content": "**1.** Enable the `[tmpl:awizemann/site-status-checker] Check site status` cron job in the Cron sidebar. It ships paused — nothing runs until you say so.\n\n**2.** Edit `sites.txt` in this project's folder to replace the placeholder URLs with the sites you actually want to watch.\n\n**3.** Ask your agent: *\"Run the site status check now.\"* The dashboard refreshes and a new entry appears at the top of `status-log.md`.\n\n**4.** Daily at 9 AM the cron job fires automatically. Change the schedule in the Cron sidebar if you want a different cadence.\n\nSee `README.md` and `AGENTS.md` in the project root for the full spec."
}
]
}
]
}
@@ -0,0 +1,20 @@
{
"schemaVersion": 1,
"id": "awizemann/site-status-checker",
"name": "Site Status Checker",
"version": "1.0.0",
"minScarfVersion": "2.2.0",
"minHermesVersion": "0.9.0",
"author": {
"name": "Alan Wizemann",
"url": "https://github.com/awizemann/scarf"
},
"description": "A daily uptime check for a short list of URLs. Writes status to status-log.md and updates the dashboard with current counts.",
"category": "monitoring",
"tags": ["monitoring", "uptime", "cron", "starter"],
"contents": {
"dashboard": true,
"agentsMd": true,
"cron": 1
}
}