mirror of
https://github.com/awizemann/scarf.git
synced 2026-05-10 10:36:35 +00:00
docs: ship site-status-checker example template + v2.2.0 release notes
First installable template demonstrating the format: - Dashboard with stat widgets (up/down/last-checked) + configured-sites list + quick-start markdown. - Cross-agent AGENTS.md with the full cron-prompt contract so any agent that reads agents.md (Claude Code, Cursor, Codex, Aider, Jules, Copilot, Zed, …) picks up the behavior on first run. - Cron job (0 9 * * *) that ships paused with the [tmpl:…] tag, pinging a user-editable sites.txt and writing results to status-log.md. - First-run bootstrap logic in AGENTS.md: if sites.txt doesn't exist yet the agent creates it with two placeholder URLs, then proceeds. Plus examples/templates/README.md explaining the staging/ layout, authoring conventions, and how to rebuild a bundle after editing. CI validates the bundle via ProjectTemplateExampleTemplateTests so drift between staging/ and the built .scarftemplate fails on every build. v2.2.0 release notes cover the full feature surface including the install preview sheet, scarf:// + file:// URL handling, skills namespacing, cron-job tagging, memory-block markers, and the lock-driven uninstall flow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
# Example Templates
|
||||
|
||||
This directory holds reference `.scarftemplate` bundles shipped in the Scarf repo. Each subdirectory is one template, laid out as:
|
||||
|
||||
```
|
||||
<template-name>/
|
||||
├── staging/ Source tree — the exact layout of the bundle
|
||||
│ ├── template.json
|
||||
│ ├── README.md
|
||||
│ ├── AGENTS.md
|
||||
│ ├── dashboard.json
|
||||
│ ├── cron/jobs.json (optional)
|
||||
│ ├── skills/<name>/… (optional)
|
||||
│ ├── instructions/… (optional)
|
||||
│ └── memory/append.md (optional)
|
||||
└── <template-name>.scarftemplate Built bundle (zipped staging dir)
|
||||
```
|
||||
|
||||
## Available templates
|
||||
|
||||
- **[site-status-checker](site-status-checker/)** — daily HTTP uptime check for a user-editable list of URLs. Dashboard + cron + AGENTS.md. The simplest example that exercises the full format.
|
||||
|
||||
## Rebuilding a bundle after editing
|
||||
|
||||
```bash
|
||||
cd <template-name>/staging
|
||||
zip -qq -r ../<template-name>.scarftemplate .
|
||||
```
|
||||
|
||||
The Scarf test suite (`ProjectTemplateExampleTemplateTests`) validates each shipped `.scarftemplate` on every build, so a bundle that fails to round-trip through `inspect → buildPlan` will fail CI.
|
||||
|
||||
## Authoring conventions
|
||||
|
||||
- **Always ship `AGENTS.md`.** It's the Linux Foundation cross-agent standard ([agents.md](https://agents.md/)) and every supported agent reads it. Agent-specific shims (`CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `.github/copilot-instructions.md`) go under `instructions/` and only when there's a real per-agent behavior the author needs.
|
||||
- **Cron jobs ship paused.** Don't assume the user wants your job running on install. Write the prompt so running it manually from chat (`"run the X job"`) also works — the cron is just a schedule wrapper.
|
||||
- **Dashboard values that change at runtime should be placeholders.** The agent (not the installer) keeps them fresh. Start with sensible zeros / "never" / "unknown" so an uninstalled, inactive project still renders cleanly.
|
||||
- **Don't claim in the manifest what you don't ship.** The `contents` block is cross-checked against the unpacked files — a mismatch makes the installer refuse the bundle.
|
||||
Binary file not shown.
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
## What's New in 2.2.0
|
||||
|
||||
Scarf projects can now travel. This release introduces **Project Templates** — a shareable `.scarftemplate` bundle format that packages a project's dashboard, agent instructions, skills, and cron jobs into a single file anyone can install with one click from a local file or an `scarf://install?url=…` deep link.
|
||||
|
||||
### Project Templates
|
||||
|
||||
- **Bundle format: `.scarftemplate`.** A zip archive carrying a `template.json` manifest, the project's dashboard, a required `AGENTS.md` (the [Linux Foundation cross-agent instructions standard](https://agents.md/) — reads natively in Claude Code, Cursor, Codex, Aider, Jules, Copilot, Zed, and more), a README shown in the installer, optional per-agent instruction shims (`CLAUDE.md`, `GEMINI.md`, `.cursorrules`, `.github/copilot-instructions.md`), optional namespaced skills, optional cron job definitions, and an optional memory appendix. Every bundle is agent-portable out of the box.
|
||||
- **Install preview sheet.** Before anything touches disk, Scarf shows you the exact project directory that will be created, every file inside it, every skill that will be namespaced under `~/.hermes/skills/templates/<slug>/`, every cron job that will be registered (always paused — you enable each one manually), and a live diff of the memory appendix against your existing `MEMORY.md`. The manifest's content claim is cross-checked against the actual zip entries so a bundle can't hide files from the preview.
|
||||
- **`scarf://install?url=…` deep links.** Register Scarf as the handler for the `scarf` URL scheme so a future catalog site can link one-click installs straight into the app. Only `https://` payloads are accepted; `file://`, `javascript:`, and `http://` are refused on principle. A 50 MB size cap keeps a malicious link from exhausting disk. The URL never auto-installs — the preview sheet is always user-confirmed.
|
||||
- **Export any project as a template.** Select a project, open the new Templates menu in the Projects toolbar, fill in a handful of fields (id, name, version, description, optional author + category + tags), tick the skills and cron jobs you want to include, optionally drop in a memory snippet, and save. The exporter builds the bundle and you can hand it to anyone.
|
||||
- **No-overwrite, reversible by design.** Installed templates drop a `<project>/.scarf/template.lock.json` recording exactly what they wrote — every project file, skill path, cron job name, and memory block id. Installing the same template id twice is refused at the preview step so you don't accidentally double-append to `MEMORY.md`. Uninstalling by hand is a matter of deleting the project directory, the skills namespace folder, and any `[tmpl:<id>] …` cron jobs — no hidden state.
|
||||
- **Safe globals.** Skills install to `~/.hermes/skills/templates/<slug>/<skill-name>/` so they never collide with your own skills. Cron jobs are prefixed with `[tmpl:<id>]` and start paused so nothing unexpected kicks off on install. The installer **never** touches `~/.hermes/config.yaml`, `auth.json`, sessions, or any credential-bearing path.
|
||||
|
||||
### Using templates
|
||||
|
||||
- **Install from file:** Projects → Templates → *Install from File…*, pick a `.scarftemplate` from disk.
|
||||
- **Install from URL:** Projects → Templates → *Install from URL…*, paste an https URL.
|
||||
- **Install from the web:** click any `scarf://install?url=…` link in a browser.
|
||||
- **Export:** select a project → Projects → Templates → *Export "<name>" as Template…*, fill the form, save.
|
||||
|
||||
### Under the hood
|
||||
|
||||
- New models in `Core/Models/ProjectTemplate.swift` (manifest, inspection, install plan, lock, errors).
|
||||
- `Core/Services/ProjectTemplateService.swift` unzips, parses, and validates; `ProjectTemplateInstaller.swift` executes the plan atomically-enough (pre-flights conflicts, then writes); `ProjectTemplateExporter.swift` builds bundles from a live project + selections.
|
||||
- `Core/Services/TemplateURLRouter.swift` is the process-wide landing pad for `scarf://` URLs so a cold-launch browser click still reaches the install sheet.
|
||||
- Installer dispatches cron creation via `hermes cron create` (there's no direct Scarf write path for `cron/jobs.json`), then diffs before/after to pause the newly-registered jobs.
|
||||
- New Swift Testing suites: `ProjectTemplateServiceTests`, `TemplateURLRouterTests`, `ProjectTemplateExportTests`.
|
||||
|
||||
### Uninstall
|
||||
|
||||
- **One-click uninstall** driven by `template.lock.json`. Right-click any template-installed project in the sidebar → **Uninstall Template…**, or click the uninstall button in the dashboard header. A preview sheet lists every file, cron job, and memory block that will be removed, and every user-created file that will be preserved.
|
||||
- **User content is never removed.** Files you (or the agent) added to the project dir after install — like a `sites.txt` or `status-log.md` — are detected and listed as "keep" in the preview. The project directory itself is removed only if nothing user-owned is left inside.
|
||||
- **Clean global state.** The isolated `~/.hermes/skills/templates/<slug>/` namespace is removed wholesale. Tagged cron jobs are removed via `hermes cron remove`. The memory block between the `<!-- scarf-template:<id>:begin/end -->` markers is stripped, leaving the rest of MEMORY.md intact. The project registry entry is removed last.
|
||||
- **No undo.** v1 uninstall is destructive — to reinstall, run the install flow again.
|
||||
|
||||
### Not in this release (planned for v2.3)
|
||||
|
||||
- In-app catalog browser backed by a GitHub Pages `templates.json`.
|
||||
- EdDSA-signed bundles reusing the Sparkle key.
|
||||
- Template updates (compare installed lock against a newer bundle's version, offer a diff).
|
||||
- Installing into remote `ServerContext`s (v1 is local-only).
|
||||
|
||||
### Migrating from 2.1.x
|
||||
|
||||
Sparkle will offer the update automatically. No config migration needed. Existing projects are untouched — templates are additive.
|
||||
Reference in New Issue
Block a user