From ea4032766b0901774ff2d5d8750e99bb98daeff9 Mon Sep 17 00:00:00 2001 From: Alan Wizemann Date: Thu, 23 Apr 2026 19:41:50 +0200 Subject: [PATCH] feat(templates): ship awizemann/template-author skill bundle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A new .scarftemplate in the public catalog whose only content is a Hermes skill that teaches an agent how to scaffold a new Scarf-compatible project — dashboard, optional configuration schema, optional cron job, AGENTS.md — from a short conversational interview. Scaffolded projects are usable locally and cleanly exportable as .scarftemplate bundles later. The skill itself (~400 lines of structured markdown at skills/scarf-template-author/SKILL.md) covers: - When to invoke vs. when to answer inline - The on-disk project shape Scarf expects - A 5-question interview flow - Full widget catalog (all 7 widget types) with JSON shapes - Config schema design + hard invariants (no defaults on secrets, `contents.config` must match field count, etc.) - Cron-job design including the {{PROJECT_DIR}} gotcha - Step-by-step file writing (dashboard, manifest, AGENTS.md, README) - Testing + catalog validation instructions - Common pitfalls + source-of-truth references Delivered as a .scarftemplate so the install flow's normal safeguards apply: preview sheet shows one project + one skill + zero cron jobs + no config step, uninstall drops both the project dir and the namespaced skill folder via the existing lock-file mechanism. Scope per user sign-off: blank-slate / fully conversational for v1. Pre-baked archetypes (`monitor`, `dev-dashboard`, etc.) are deferred to v1.1 pending real usage data on what shapes users actually ask for. New Swift test exercises the bundle through the installer's plan builder — asserts manifest shape, that the skill lands at ~/.hermes/skills/templates/awizemann-template-author/scarf-template-author/SKILL.md, and that no-config templates correctly skip the manifest cache. 58/58 Swift tests pass; 24/24 Python tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) --- scarf/scarfTests/ProjectTemplateTests.swift | 62 +++ .../template-author/staging/AGENTS.md | 55 +++ .../template-author/staging/README.md | 46 ++ .../template-author/staging/dashboard.json | 33 ++ .../skills/scarf-template-author/SKILL.md | 392 ++++++++++++++++++ .../template-author/staging/template.json | 19 + .../template-author.scarftemplate | Bin 0 -> 13889 bytes templates/catalog.json | 31 ++ 8 files changed, 638 insertions(+) create mode 100644 templates/awizemann/template-author/staging/AGENTS.md create mode 100644 templates/awizemann/template-author/staging/README.md create mode 100644 templates/awizemann/template-author/staging/dashboard.json create mode 100644 templates/awizemann/template-author/staging/skills/scarf-template-author/SKILL.md create mode 100644 templates/awizemann/template-author/staging/template.json create mode 100644 templates/awizemann/template-author/template-author.scarftemplate diff --git a/scarf/scarfTests/ProjectTemplateTests.swift b/scarf/scarfTests/ProjectTemplateTests.swift index 6b14205..3e68fb4 100644 --- a/scarf/scarfTests/ProjectTemplateTests.swift +++ b/scarf/scarfTests/ProjectTemplateTests.swift @@ -1063,6 +1063,68 @@ final class TestRegistryLock: @unchecked Sendable { #expect(cronPrompt.contains("{{PROJECT_DIR}}")) } + /// Exercises the second shipped template — `awizemann/template-author` — + /// which is a skill-only bundle (no config, no cron, no memory). The + /// shape is deliberately different from site-status-checker so a + /// regression in the installer's "no config, no cron" path can't hide + /// behind the richer example template. Also asserts the skill lands + /// under the expected namespaced path so Hermes's recursive skill + /// discovery finds it. + @Test func templateAuthorParsesAndPlans() throws { + let bundle = try Self.locateExample(author: "awizemann", name: "template-author") + + let service = ProjectTemplateService(context: .local) + let inspection = try service.inspect(zipPath: bundle) + defer { service.cleanupTempDir(inspection.unpackedDir) } + + // Manifest shape: schemaVersion 2 (contains `skills` claim, which + // wasn't part of v1), no config, no cron, one skill. + #expect(inspection.manifest.id == "awizemann/template-author") + #expect(inspection.manifest.name == "Scarf Template Author") + #expect(inspection.manifest.version == "1.0.0") + #expect(inspection.manifest.schemaVersion == 2) + #expect(inspection.manifest.contents.dashboard) + #expect(inspection.manifest.contents.agentsMd) + #expect(inspection.manifest.contents.cron == nil) + #expect(inspection.manifest.contents.config == nil) + #expect(inspection.manifest.contents.memory == nil) + #expect(inspection.manifest.contents.skills == ["scarf-template-author"]) + #expect(inspection.manifest.config == nil) + #expect(inspection.cronJobs.isEmpty) + + // Plan: empty config, empty cron, but one skill queued for install + // under the template's namespaced dir. The namespace path has to + // match what the uninstaller wipes — `skills/templates/` — + // or uninstall leaves orphan skill files. + let scratch = try ProjectTemplateServiceTests.makeTempDir() + defer { try? FileManager.default.removeItem(atPath: scratch) } + let plan = try service.buildPlan(inspection: inspection, parentDir: scratch) + #expect(plan.projectDir.hasSuffix("awizemann-template-author")) + #expect(plan.cronJobs.isEmpty) + #expect(plan.configSchema == nil) + #expect(plan.configValues.isEmpty) + #expect(plan.memoryAppendix == nil) + + // The skill should land at + // `~/.hermes/skills/templates/awizemann-template-author/scarf-template-author/SKILL.md` + // — namespace dir + skill folder + SKILL.md. Anything else + // breaks Hermes's recursive discovery or the uninstaller's + // `rm -rf` on the namespace dir. + let namespaceDir = try #require(plan.skillsNamespaceDir) + #expect(namespaceDir.hasSuffix("/skills/templates/awizemann-template-author")) + #expect(plan.skillsFiles.count == 1) + let skillDest = try #require(plan.skillsFiles.first?.destinationPath) + #expect(skillDest.hasSuffix("/scarf-template-author/SKILL.md")) + #expect(skillDest.hasPrefix(namespaceDir)) + + // No-config templates deliberately skip the manifest cache — + // the dashboard's Configuration button only shows up when + // `.scarf/manifest.json` exists, so a skill-only template + // like this one correctly doesn't surface that button. + // (See ProjectTemplateService.buildPlan lines 198–227.) + #expect(plan.manifestCachePath == nil) + } + /// Resolve the example bundle path robustly. Unit-test working dirs /// differ between `xcodebuild test` (project root) and an Xcode IDE /// run (build-output dir), so we walk up from this source file until diff --git a/templates/awizemann/template-author/staging/AGENTS.md b/templates/awizemann/template-author/staging/AGENTS.md new file mode 100644 index 0000000..54c0fe6 --- /dev/null +++ b/templates/awizemann/template-author/staging/AGENTS.md @@ -0,0 +1,55 @@ +# Template Author — Agent Instructions + +This project is a help surface for the `scarf-template-author` Hermes skill. The same instructions apply whether you're Claude Code, Cursor, Codex, Aider, or any other agent that reads `AGENTS.md`. + +## What this project is + +Two things: + +1. A minimal dashboard (`.scarf/dashboard.json`) the user lands on after install. It's a Quick Start text widget + an empty list widget. The list is an optional scratchpad where you can log projects you've scaffolded for the user, giving them a running audit trail. That's nice-to-have, not mandatory. +2. A skill at `~/.hermes/skills/templates/awizemann-template-author/scarf-template-author/SKILL.md`. The skill is the real value — it teaches you how to interview the user and scaffold a new Scarf-compatible project. + +## What this project is NOT + +- Not a running service. No cron jobs, no background tasks, no secrets. +- Not a dashboard you need to keep updated. The dashboard is documentation; the only mutation worth doing is appending to the Scaffolded Projects list after you scaffold something. + +## When the user asks to create a Scarf project + +The primary trigger. Phrases that should activate the full scaffolding flow: + +- "Create a new Scarf project that …" +- "Scaffold a dashboard for …" +- "Set up a project to watch / track / report on …" +- "Help me author a Scarf template." +- "Build me a project that runs daily and …" + +When you hear those: + +1. Load the skill at `~/.hermes/skills/templates/awizemann-template-author/scarf-template-author/SKILL.md` and follow its interview flow. Do not improvise — the skill encodes the specific invariants Scarf enforces (widget types, field-type constraints, the `{{PROJECT_DIR}}` token, the paused-on-install cron rule, the secret-fields-have-no-defaults rule). +2. Scaffold into a directory the user picks. Use absolute paths. +3. After writing files, tell the user to register the project: click **+** in Scarf's Projects sidebar and pick the directory. Do not try to edit `~/.hermes/scarf/projects.json` yourself — Scarf reloads the registry on its own and the UI path is safer. +4. Optionally append to the Scaffolded Projects list in this project's `dashboard.json` so the user has a local record of what you've built for them. Preserve every other field in the dashboard as-is. + +## When the user asks reference questions + +If the user asks something like "what widget types does Scarf support?" or "how do I add a secret field?", you don't need to scaffold anything — answer inline. The skill's reference sections cover: + +- The seven widget types (`stat`, `progress`, `text`, `table`, `chart`, `list`, `webview`) and their required fields. +- The seven config field types (`string`, `text`, `number`, `bool`, `enum`, `list`, `secret`) and their constraint keys. +- The `AGENTS.md` contract that every scaffolded project should honour. + +Point them at the skill file if they want to read it directly. It's ~400 lines of structured markdown. + +## What not to do + +- Don't scaffold without asking the user where the project should live. The interview always asks for a parent directory. +- Don't register secrets in `/.scarf/config.json`. Secret field values go through the macOS Keychain at install time; `config.json` stores `keychain://…` URIs, never plaintext. A scaffolded project that hasn't been installed yet has no secrets on disk at all. +- Don't claim dashboard widget titles the cron job doesn't actually update. The scaffolded `AGENTS.md` is a contract — if it says "the cron updates Sites Up / Sites Down", the cron prompt must match. +- Don't skip `{{PROJECT_DIR}}` token substitution in cron prompts. Hermes doesn't set a CWD for cron runs, so relative paths resolve against the agent's own dir — the installer swaps `{{PROJECT_DIR}}` for the absolute project path at install time. + +## Reference + +- `SKILL.md` at `~/.hermes/skills/templates/awizemann-template-author/scarf-template-author/SKILL.md` — the full scaffolding playbook. +- [Project Templates wiki page](https://github.com/awizemann/scarf/wiki/Project-Templates) — user-facing docs. +- [`awizemann/site-status-checker`](https://awizemann.github.io/scarf/templates/awizemann-site-status-checker/) — a complete working example covering dashboard stats, a configurable list, a cron job, a Site-tab webview, and a full AGENTS.md contract. Read it when you're unsure how a piece should look. diff --git a/templates/awizemann/template-author/staging/README.md b/templates/awizemann/template-author/staging/README.md new file mode 100644 index 0000000..fa4e8d6 --- /dev/null +++ b/templates/awizemann/template-author/staging/README.md @@ -0,0 +1,46 @@ +# Scarf Template Author + +A Hermes skill that teaches your agent how to scaffold a new Scarf project — and, because Scarf's `.scarftemplate` format is symmetric with a live project on disk, how to shape it so you can publish it to the catalog later if you want. + +## What you get + +Installing this template drops a skill at `~/.hermes/skills/templates/awizemann-template-author/scarf-template-author/SKILL.md` and a minimal "how to use" project in a folder of your choice. Every agent that reads the standard `~/.hermes/skills/` directory — Claude Code, Cursor, Codex, Aider, and the rest of the [agents.md](https://agents.md/) family — picks the skill up automatically. + +## How to use it + +After install, open your agent in any directory and say something like: + +- *"Create a new Scarf project that watches the number of open PRs in my GitHub repo."* +- *"Scaffold a Scarf dashboard that tracks daily focus time from my Toggl logs."* +- *"Set up a project that runs a cron job to summarise my inbox each morning."* +- *"Help me author a Scarf template I can share."* + +The agent will ask four or five questions (purpose, data source, cadence, what to display, any secrets) and then write: + +- `/.scarf/dashboard.json` +- `/.scarf/manifest.json` — only if you're going to use a configuration form or want to export later +- `/AGENTS.md` +- `/README.md` +- Optionally a cron job registered via `hermes cron create` (always created paused — you enable it from Scarf's Cron sidebar when ready). + +When it's done, click **+** in Scarf's Projects sidebar and pick the directory. Your dashboard appears. Iterate on it by asking your agent to tweak widgets or add fields. + +## Turning a local project into a shareable template + +Once you're happy with the result, Scarf → Projects → Templates → *Export "<name>" as Template…* produces a `.scarftemplate` anyone can install. The exporter carries the configuration *schema* but never your filled-in values — so your secrets and personal settings stay local. + +## About this template's own dashboard + +The installed project itself is tiny — a single Quick Start text widget and an empty list widget meant to serve as a scratchpad for tracking which scaffolded projects you've created. Its only purpose is to give you a place to land after install and a reminder of the trigger phrases above. The real value is the skill. + +## Reference + +- [Project Templates wiki page](https://github.com/awizemann/scarf/wiki/Project-Templates) — full spec + troubleshooting. +- [`awizemann/site-status-checker`](https://awizemann.github.io/scarf/templates/awizemann-site-status-checker/) — a complete, non-trivial example the skill studies and references. +- Dashboard / configuration schemas are Swift-authoritative at `scarf/scarf/Core/Models/ProjectDashboard.swift` and `scarf/scarf/Core/Models/TemplateConfig.swift` in the Scarf repo. + +## What this template intentionally is not + +- Not an archetype picker. v1 is blank-slate conversational; pre-baked starters (`monitor`, `dev-dashboard`, `personal-log`, etc.) may land in v1.1 once we see what shapes people ask for most often. +- Not a graphical wizard. The conversational agent path is strictly richer than a fixed form, and dogfoods Scarf's agent-first philosophy. +- Not a remote-scaffolding tool. It writes files into a directory on the machine where the agent runs; pair with Scarf's remote-server mode if you want to scaffold onto another box. diff --git a/templates/awizemann/template-author/staging/dashboard.json b/templates/awizemann/template-author/staging/dashboard.json new file mode 100644 index 0000000..63e9bc8 --- /dev/null +++ b/templates/awizemann/template-author/staging/dashboard.json @@ -0,0 +1,33 @@ +{ + "version": 1, + "title": "Template Author", + "description": "A Hermes skill that helps your agent scaffold new Scarf projects — ask in chat, answer a short interview, and land a working dashboard with the right shape to export as a .scarftemplate later. The Scaffolded Projects list below grows as you use the skill.", + "theme": { "accent": "blue" }, + "sections": [ + { + "title": "Quick Start", + "columns": 1, + "widgets": [ + { + "type": "text", + "title": "Ask your agent", + "format": "markdown", + "content": "**This project gives you a skill, not a service.** There are no cron jobs running, no dashboards to maintain. The real value lives at `~/.hermes/skills/templates/awizemann-template-author/scarf-template-author/SKILL.md`.\n\n**Trigger phrases** your agent listens for:\n\n- *\"Create a new Scarf project that watches …\"*\n- *\"Scaffold a dashboard to track …\"*\n- *\"Set up a project that runs a daily check on …\"*\n- *\"Help me author a Scarf template.\"*\n\nThe agent will interview you (purpose → data source → cadence → widgets → config → secrets), write `/.scarf/dashboard.json`, `/.scarf/manifest.json`, `/AGENTS.md`, and `/README.md`, then tell you to click **+** in Scarf's Projects sidebar to register the directory.\n\nWhen you're happy with the result, **Projects → Templates → Export** turns it into a `.scarftemplate` you can share.\n\nSee the [Project Templates wiki page](https://github.com/awizemann/scarf/wiki/Project-Templates) for the full spec." + } + ] + }, + { + "title": "Scaffolded Projects", + "columns": 1, + "widgets": [ + { + "type": "list", + "title": "Projects this skill has built for you", + "items": [ + { "text": "Nothing yet — ask your agent to scaffold a project and it'll optionally log entries here.", "status": "pending" } + ] + } + ] + } + ] +} diff --git a/templates/awizemann/template-author/staging/skills/scarf-template-author/SKILL.md b/templates/awizemann/template-author/staging/skills/scarf-template-author/SKILL.md new file mode 100644 index 0000000..455b33f --- /dev/null +++ b/templates/awizemann/template-author/staging/skills/scarf-template-author/SKILL.md @@ -0,0 +1,392 @@ +--- +name: scarf-template-author +description: Scaffold a new Scarf project — dashboard, optional configuration schema, optional cron job, and AGENTS.md — from a short conversational interview with the user. Output is immediately usable locally and cleanly exportable as a .scarftemplate bundle. +version: 1.0.0 +author: Alan Wizemann +license: MIT +platforms: [macos] +metadata: + hermes: + tags: [Scarf, templates, scaffolding, dashboard, authoring] + homepage: https://github.com/awizemann/scarf/wiki/Project-Templates +prerequisites: + commands: [hermes] +--- + +# Scarf Template Author + +Scaffold a new Scarf-compatible project from a conversational interview. The output is both (a) a working project on disk the user can register with Scarf and use immediately, and (b) correctly shaped to be exported as a `.scarftemplate` bundle via Scarf's Export flow later. + +## When to invoke this skill + +Activate when the user says things like: + +- *"Create a new Scarf project that watches / tracks / reports on …"* +- *"Scaffold a dashboard for …"* +- *"Set up a project that runs a daily check on …"* +- *"Help me author a Scarf template."* +- *"Build me a Scarf project to monitor …"* + +Do **not** activate for pure reference questions like *"what widget types does Scarf support?"* or *"how does Scarf handle secrets?"* — answer those inline from the reference sections below. + +Also do not activate when the user explicitly wants to edit an existing project's dashboard — that's a plain file edit, not a scaffold. + +## How a Scarf project is shaped on disk + +A Scarf project is just a directory registered in `~/.hermes/scarf/projects.json`. For Scarf to render a useful dashboard and for the project to be exportable as a `.scarftemplate`, it needs these files at minimum: + +``` +/ +├── .scarf/ +│ ├── dashboard.json # REQUIRED for dashboard rendering +│ └── manifest.json # OPTIONAL — required only if the project declares a config schema or you want to export cleanly +├── AGENTS.md # Cross-agent instructions (agents.md standard) — ship this for every project +└── README.md # User-facing explanation +``` + +If the project will have a scheduled job, ALSO register a cron entry via `hermes cron create`. For an exportable bundle, also author `cron/jobs.json` in the staging directory — that's where Scarf's exporter will pick jobs up from. + +Secrets never land in `dashboard.json` or `config.json`. At install time, Scarf routes secret-type config values to the macOS Keychain; `config.json` stores `keychain://service/account` URIs. When scaffolding from scratch (no install), the user either manages secrets via the post-install Configuration editor after export, or stashes them in their `~/.hermes/config.yaml` if they're Hermes-level secrets rather than project-level. + +## The interview + +Ask these questions in order. Don't batch. Each answer shapes the next question. + +### 1. Purpose and data source + +- *"In one sentence — what does this project do?"* +- *"Where does its data come from? Files, a URL, a shell command's output, an API call, a database, a spreadsheet?"* + +Goal: figure out whether the project is **passive** (user maintains some files, dashboard reflects them), **pull-based** (we fetch from an HTTP endpoint or CLI tool on a schedule), or **push-based** (something external writes to a file we watch). + +### 2. Refresh cadence + +- *"How often should it refresh? Every hour? Daily? Weekly? Only when I ask?"* + +If "only when I ask" → no cron job; user invokes the agent manually. If any scheduled cadence → cron job. + +Map to cron expressions: +- Every hour: `0 * * * *` +- Daily at 9 AM: `0 9 * * *` +- Weekly Monday 9 AM: `0 9 * * 1` +- Every 15 minutes: `*/15 * * * *` + +### 3. What the dashboard shows + +Explain the seven widget types (see Widget Catalog below) in plain English, then ask which ones feel right. Offer concrete suggestions based on the purpose: + +- Counting things (open PRs, failing tests, up/down sites) → `stat` widgets. +- A list of items with status → `list` with `text` + `status` per item. +- Time-series data → `chart` with `line` or `bar` type. +- Rows × columns of heterogeneous data → `table`. +- A live URL (useful for monitoring a site) → `webview`. **Including a webview widget exposes a Site tab** next to the Dashboard tab — worth noting to the user. +- A progress bar for something with a clear 0-to-N scale → `progress`. +- Static help / markdown → `text` with `format: "markdown"`. + +### 4. Configuration needs + +- *"Does this project need anything configurable by the user — URLs to watch, API tokens, thresholds, a list of accounts?"* + +If yes → design a config schema. Fields map to seven types (see Config Schema Design below). Remember: **secret fields never have defaults**; that's a hard validator rule. + +If no → skip `.scarf/manifest.json`; the project works but won't have a Configuration form. + +### 5. Target agents + +- *"Which agents will operate this project? Just Claude Code? Also Cursor / Codex / Aider / other?"* + +For v1 just write `AGENTS.md` — every modern agent reads it, and if you need a specific shim (CLAUDE.md, GEMINI.md, .cursorrules), add it as a symlink to AGENTS.md so content stays in sync. + +## Widget Catalog (JSON shapes) + +All widgets require `type` and `title`. Type-specific fields: + +### `stat` — single metric +```json +{ "type": "stat", "title": "Sites Up", "value": 0, + "icon": "checkmark.circle.fill", "color": "green", "subtitle": "responded 2xx/3xx" } +``` +`value` accepts number OR string (`WidgetValue` enum). `icon` is an SF Symbol name. `color` is one of: `green`, `red`, `blue`, `orange`, `yellow`, `purple`, `gray`. + +### `progress` — 0.0 to 1.0 progress bar +```json +{ "type": "progress", "title": "Test Coverage", "value": 0.72, "label": "72% of statements" } +``` + +### `text` — markdown or plain text block +```json +{ "type": "text", "title": "Quick Start", "format": "markdown", + "content": "**1.** Click + in the Projects sidebar.\n\n**2.** ..." } +``` +`format` is `"markdown"` or `"plain"`. + +### `table` — columns × rows of strings +```json +{ "type": "table", "title": "Failing Tests", + "columns": ["Test", "Duration", "Last Passed"], + "rows": [["testFoo", "4.2s", "Apr 20"], ["testBar", "0.9s", "Apr 18"]] } +``` +Every row MUST have the same length as `columns`. + +### `chart` — line / bar / area / pie with series +```json +{ "type": "chart", "title": "Requests / day", "chartType": "line", + "xLabel": "Date", "yLabel": "Count", + "series": [{ + "name": "staging", + "color": "blue", + "data": [{"x": "Apr 20", "y": 142}, {"x": "Apr 21", "y": 189}] + }] +} +``` +`chartType` is `"line"`, `"bar"`, `"area"`, or `"pie"`. + +### `list` — items with optional status badge +```json +{ "type": "list", "title": "Watched Sites", + "items": [ + { "text": "https://example.com", "status": "up" }, + { "text": "https://example.org", "status": "down" } + ] +} +``` +`status` values: `"up"`, `"down"`, `"pending"`, `"ok"`, `"warn"`, `"error"` — render as coloured badges. + +### `webview` — embedded live URL +```json +{ "type": "webview", "title": "First Watched Site", + "url": "https://awizemann.github.io/scarf/", "height": 420 } +``` +**Important:** including any `webview` widget in a dashboard exposes a **Site** tab next to the Dashboard tab in the project view. Useful for templates that watch something renderable. The agent can update `url` on cron runs to keep the Site tab in sync with config (e.g., set it to `values.sites[0]`). + +## Config Schema Design + +If the project needs user-configurable values, design a schema. Put it in `/.scarf/manifest.json` with this shape: + +```json +{ + "schemaVersion": 2, + "id": "author/project", + "name": "My Project", + "version": "1.0.0", + "description": "Short one-liner.", + "contents": { "dashboard": true, "agentsMd": true, "config": 2 }, + "config": { + "schema": [ + { "key": "sites", "type": "list", "itemType": "string", "label": "Sites", + "required": true, "minItems": 1, "maxItems": 25, + "default": ["https://example.com"] }, + { "key": "api_token", "type": "secret", "label": "API Token", "required": true } + ], + "modelRecommendation": { + "preferred": "claude-haiku-4", + "rationale": "Short-running, tool-light workload — haiku is plenty." + } + } +} +``` + +Note: `contents.config` is the **count of schema fields**, not a boolean. In the example above it's `2` because there are two fields. + +### Field types and constraints + +| Type | Rendered as | Constraint keys | +|---|---|---| +| `string` | Text field | `pattern` (regex), `minLength`, `maxLength` | +| `text` | Multi-line editor | `minLength`, `maxLength` | +| `number` | Number field | `min`, `max` | +| `bool` | Toggle | — | +| `enum` | Segmented (≤4) / Dropdown (>4) | `options: [{value, label}]` (REQUIRED) | +| `list` | Repeatable rows | `itemType: "string"` (required), `minItems`, `maxItems` | +| `secret` | Password field, routes to Keychain | — | + +Every field takes `key` (required), `label` (required), `description` (optional — markdown), `required` (bool), `default` (optional; type matches the field type). + +### Hard rules + +- **Secret fields MUST NOT have a `default`.** The validator rejects the manifest if they do — a default makes no sense because the Keychain entry doesn't exist yet at install time. +- **Enum fields MUST have non-empty `options`.** +- **List fields MUST have `itemType: "string"`** in v1 (only itemType supported). +- **Field keys MUST be unique** within a schema. +- **`schemaVersion` MUST be 2** when a `config` block is present; it stays 1 if there's no config. +- **`contents.config`** must equal the actual count of schema fields — a claim mismatch is rejected. + +## Cron Job Design + +If the project has a scheduled task, register a cron job via `hermes cron create` AND — if you expect the user to export this as a `.scarftemplate` — author a `cron/jobs.json` in the staging layout so the exporter picks it up. + +### Staging shape (for exportable templates) + +``` +/ +├── .scarf/ +├── AGENTS.md +├── README.md +└── cron/ + └── jobs.json +``` + +Where `cron/jobs.json` is: + +```json +[ + { + "name": "Check site status", + "schedule": "0 9 * * *", + "prompt": "Read {{PROJECT_DIR}}/.scarf/config.json — get values.sites and values.timeout_seconds — then HTTP GET each URL with that timeout, write the results to {{PROJECT_DIR}}/status-log.md, and update {{PROJECT_DIR}}/.scarf/dashboard.json's stat widgets by title (Sites Up, Sites Down, Last Checked). Reply with a one-line summary." + } +] +``` + +### Gotchas + +- **Hermes does not set a CWD when firing cron jobs.** Relative paths in the prompt resolve against wherever the Hermes process happens to be running, not the project. Always use `{{PROJECT_DIR}}` in the prompt — the installer substitutes the absolute path at install time. This is THE most common template-author mistake. +- **Cron jobs created by the installer start paused.** Their name is auto-prefixed with `[tmpl:]`. The user enables them from Scarf's Cron sidebar when ready. +- **Registering a cron job for a user's local (non-exported) project:** run `hermes cron create --name "" "" ""` directly, substituting the absolute `` path for `{{PROJECT_DIR}}` yourself. Then `hermes cron pause ` so it doesn't run until the user opts in. + +### Schedule quick reference + +| Cadence | Expression | +|---|---| +| Every 15 minutes | `*/15 * * * *` | +| Hourly at :00 | `0 * * * *` | +| Daily at 9 AM | `0 9 * * *` | +| Weekly Monday 9 AM | `0 9 * * 1` | +| First of the month, 9 AM | `0 9 1 * *` | + +## Writing the files + +After the interview, write files in this order. + +### Step 1 — confirm parent directory + +Ask: *"Where should I create the project? Give me an absolute path — I'll make a `` directory inside it."* + +Make sure the parent exists and is writable. Make sure `/` does NOT already exist. If it does, ask whether to pick a different name or bail. + +### Step 2 — create the skeleton + +```bash +mkdir -p //.scarf +``` + +### Step 3 — write `dashboard.json` + +Use the Widget Catalog above. Always include: + +- `version: 1` +- `title` (the project's display name) +- `description` (a one-liner shown under the title) +- `sections` (array; each has `title`, optional `columns` (1–4, default 3), `widgets`) + +Keep section titles short. Group related widgets. First section is usually "Current Status" or similar with the key stats. + +### Step 4 — write `manifest.json` (only if the project has a config schema) + +Put the full manifest shape from Config Schema Design above. Use `schemaVersion: 2`, match `contents.config` to the actual field count, and ensure every secret field has no `default`. + +If there's no config schema, skip this file — the project still works, it just won't have a Configuration button. You can add it later. + +### Step 5 — write `AGENTS.md` + +Every scaffolded project needs an `AGENTS.md` that covers: + +- **Purpose** — what the project does. +- **Layout** — which files exist and what they're for. +- **Configuration** — if there's a config schema, document every field: what it's for, what valid values look like, what happens when it's missing. +- **Dashboard** — list every widget the cron job (if any) updates, by title. If the cron updates a webview widget's URL, document that explicitly. +- **Cron behaviour** — what the cron job does, what it reads, what it writes, what its exit criteria are. +- **Chat prompts** — common user questions and how to answer them (e.g., *"What's the status of my sites?"* → "read the top section of `status-log.md` and summarise"). +- **What NOT to do** — e.g., *don't modify `.scarf/config.json` yourself; tell the user to open the Configuration button.* + +Use `{{PROJECT_DIR}}` placeholders in AGENTS.md only if the template will be installed through the installer (which substitutes the token). For a hand-scaffolded local-only project, substitute the absolute path yourself — `{{PROJECT_DIR}}` only resolves at install time. + +### Step 6 — write `README.md` + +User-facing. Keep it short: + +- One-paragraph purpose. +- How to install / first run (for an unexported project: "click + in Scarf's Projects sidebar"). +- How to trigger the cron job manually (Cron sidebar → Run Now). +- A pointer at `AGENTS.md` for agents. + +### Step 7 — register the cron job (if any) + +For a local non-exported project: + +```bash +hermes cron create --name "" "" "" +# Then pause it so it doesn't fire until the user's ready: +hermes cron pause +``` + +Read the id back from `hermes cron list --json` or parse the create output. + +For an exportable template (one you're staging in `templates///staging/`): just author `cron/jobs.json` — the installer registers + pauses at install time, and prefixes the name with `[tmpl:]`. + +### Step 8 — register the project with Scarf + +Tell the user: *"I've written the files. Click the **+** button in Scarf's Projects sidebar and pick ``. The dashboard will appear."* + +Do NOT edit `~/.hermes/scarf/projects.json` directly — Scarf owns that file and reloads it on its own. The UI path is safer. + +### Step 9 (optional) — log to the Template Author project's list + +If the user has the `awizemann/template-author` project installed (the one that shipped this skill), append an entry to its `dashboard.json`'s `Scaffolded Projects` list widget: + +```json +{ "text": "", "status": "ok" } +``` + +This gives the user a running audit trail of everything you've scaffolded for them. Preserve every other field in the dashboard as-is. + +## Testing your scaffold + +### Minimum smoke test + +1. Tell the user to click **+** in Scarf's Projects sidebar and pick the directory. +2. Dashboard appears — sanity check every widget renders correctly. +3. If there's a cron job: click the job in Scarf's Cron sidebar → **Run Now**. The agent executes the prompt; dashboard updates when it finishes. + +### Configuration-form test (only if schema was declared) + +To verify the Configuration form renders, you need to *install* the project as a template — scaffolded projects don't go through the installer, so the form never runs. Export the project first: + +1. Projects → Templates → **Export "<name>" as Template…** → save the `.scarftemplate` somewhere. +2. Projects → Templates → **Install from File…** → pick the bundle → the Configure step should render the form you designed. +3. Cancel the install (the preview sheet has a Cancel button) — you just wanted to verify the form shape. + +### Catalog validation (only if publishing) + +If the user plans to submit this to the public catalog at `awizemann.github.io/scarf/templates/`: + +```bash +# From the repo root +./scripts/catalog.sh check +``` + +Validates every template in `templates///` against the Python validator — the same one the PR CI uses. Catches schema issues, claim mismatches, size violations, common secret patterns. + +## Common pitfalls + +Things to check before declaring the scaffold done: + +- [ ] Every cron prompt uses `{{PROJECT_DIR}}` (for exported) OR an absolute path (for local-only). Relative paths will fail. +- [ ] `contents.config` in the manifest equals the actual field count. Claim mismatch = rejected. +- [ ] No `default` on any `secret` field. +- [ ] Every enum field has non-empty `options`. +- [ ] Every list field has `itemType: "string"`. +- [ ] Every table widget has rows of length equal to `columns`. +- [ ] Every webview widget has an https URL that renders something meaningful even pre-first-run (Scarf homepage is a decent placeholder). +- [ ] `dashboard.json` has `version: 1` at the top. +- [ ] `AGENTS.md` documents every config field, every updated widget, and the cron behaviour — the user relies on it as the source of truth when things drift. + +## Reference — source of truth files + +- **Dashboard widget schema** — `scarf/scarf/Core/Models/ProjectDashboard.swift` in the Scarf repo. If you need exact field types or defaults, read it. +- **Config schema + validation** — `scarf/scarf/Core/Models/TemplateConfig.swift` and `scarf/scarf/Core/Services/ProjectConfigService.swift`. +- **Exporter behaviour** — `scarf/scarf/Core/Services/ProjectTemplateExporter.swift`. Verifies what files the exporter will pick up from a live project and what it'll carry into a bundle. +- **Installer contract** — `scarf/scarf/Core/Services/ProjectTemplateInstaller.swift`. Verifies what `{{PROJECT_DIR}}` substitution covers and where installed files land. +- **Catalog validator** — `tools/build-catalog.py` in the Scarf repo. Run with `./scripts/catalog.sh check` for the same rules CI uses. +- **Worked example** — `templates/awizemann/site-status-checker/staging/` in the Scarf repo. Complete end-to-end: dashboard with stats + list + webview, a config schema with a list + a number, a cron job, an AGENTS.md that documents every moving part. Read it first whenever you're unsure how a piece should look. +- **User-facing docs** — [Project Templates wiki page](https://github.com/awizemann/scarf/wiki/Project-Templates). diff --git a/templates/awizemann/template-author/staging/template.json b/templates/awizemann/template-author/staging/template.json new file mode 100644 index 0000000..1241e18 --- /dev/null +++ b/templates/awizemann/template-author/staging/template.json @@ -0,0 +1,19 @@ +{ + "schemaVersion": 2, + "id": "awizemann/template-author", + "name": "Scarf Template Author", + "version": "1.0.0", + "description": "Install this to give your agent a skill that scaffolds new Scarf projects — dashboards, optional configuration schemas, cron jobs, and AGENTS.md — from a short conversational interview. Scaffolded projects are usable locally and cleanly exportable as .scarftemplate bundles.", + "minScarfVersion": "2.2.0", + "author": { + "name": "Alan Wizemann", + "url": "https://github.com/awizemann" + }, + "category": "developer-tools", + "tags": ["meta", "authoring", "skill", "scaffolding"], + "contents": { + "dashboard": true, + "agentsMd": true, + "skills": ["scarf-template-author"] + } +} diff --git a/templates/awizemann/template-author/template-author.scarftemplate b/templates/awizemann/template-author/template-author.scarftemplate new file mode 100644 index 0000000000000000000000000000000000000000..59571405b209d8b42b28510f5cc1a943f87e8606 GIT binary patch literal 13889 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 literal 0 HcmV?d00001 diff --git a/templates/catalog.json b/templates/catalog.json index 7abaeb5..f303b5d 100644 --- a/templates/catalog.json +++ b/templates/catalog.json @@ -63,6 +63,37 @@ "configurable" ], "version": "1.1.0" + }, + { + "author": { + "name": "Alan Wizemann", + "url": "https://github.com/awizemann" + }, + "bundleSha256": "670b2e07ad9bb327c11fa64db1beacf86614a3d388de6fe6e2a19ac957e1346b", + "bundleSize": 13889, + "category": "developer-tools", + "config": null, + "contents": { + "agentsMd": true, + "dashboard": true, + "skills": [ + "scarf-template-author" + ] + }, + "description": "Install this to give your agent a skill that scaffolds new Scarf projects \u2014 dashboards, optional configuration schemas, cron jobs, and AGENTS.md \u2014 from a short conversational interview. Scaffolded projects are usable locally and cleanly exportable as .scarftemplate bundles.", + "detailSlug": "awizemann-template-author", + "id": "awizemann/template-author", + "installUrl": "https://raw.githubusercontent.com/awizemann/scarf/main/templates/awizemann/template-author/template-author.scarftemplate", + "minHermesVersion": null, + "minScarfVersion": "2.2.0", + "name": "Scarf Template Author", + "tags": [ + "meta", + "authoring", + "skill", + "scaffolding" + ], + "version": "1.0.0" } ] }