diff --git a/CLAUDE.md b/CLAUDE.md index cce44d8..74f31a7 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -448,6 +448,43 @@ them in the same change so they don't drift: `src/discoverability.ts` is the source of truth for everything except the skill (`src/skill.ts`) and the patterns catalog (`src/patterns.ts`). +## Two skills, one contract + +There are **two** htmlbin agent skills in the wild — they must stay +aligned but they don't share a file. Both point at the same API, +the same CLI, and the same patterns; updating either should prompt a +look at the other. + +1. **`htmlbin` (comprehensive reference)** — served here at + `/.well-known/agent-skills/htmlbin/SKILL.md`. Source lives in + `src/skill.ts` with `skills/htmlbin/SKILL.md` as the + human-browsable mirror. Every endpoint, every flag, every quality- + floor rule. This is what runtimes following the Agent Skills + Discovery RFC v0.2.0 fetch. +2. **`htmlbin-publish` (focused, installable)** — lives in the + [`utsengar/htmlbin-cli`](https://github.com/utsengar/htmlbin-cli) + repo at `skills/htmlbin-publish/SKILL.md`. Distributed via + [skills.sh](https://skills.sh): + ```bash + npx skills add https://github.com/utsengar/htmlbin-cli --skill htmlbin-publish + ``` + Smaller and opinionated: walks the pattern-before-publish workflow + only. Targets Claude Code / Cursor / Codex / Gemini / Aider via + skills.sh resolution. + +**Cross-references** (keep these mutually pointing): +- `src/views/landing.ts` — third "skill" tab in the prompt block. +- `src/onboard.ts` — `skill:` block in `buildOnboardJson()` and an + "Install as an agent skill" section in `buildOnboardText()`. +- `src/skill.ts` + `skills/htmlbin/SKILL.md` — "Installable companion" + section right after `## Source of truth: /api/onboard`. +- `src/discoverability.ts` — `skill:` field on `agentCard()` and an + install paragraph in `llmsTxt()`. +- `README.md` — top-of-file "For agents — one-command install". + +When the skills.sh install command, repo, or skill name changes, sweep +all of the above in one PR. They are not auto-generated. + ## Patterns — pluggable, file-based Common drop kinds (PR explainers, summary roundups, plan/spec writeups, diff --git a/README.md b/README.md index 5ae4f33..702ec21 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,22 @@ self-contained HTML to a public URL — no human after auth. Built for the HTML-as-output-format era. Hosted entirely on Cloudflare: Workers + D1 + KV. +## For agents — one-command install + +If your agent runtime resolves [skills.sh](https://skills.sh) installs +(Claude Code, Cursor, Codex, Gemini, Aider, …): + +```bash +npx skills add https://github.com/utsengar/htmlbin-cli --skill htmlbin-publish +``` + +That installs the official `htmlbin-publish` skill — pattern-before- +publish workflow, uses the `@htmlbin/cli` under the hood. The skill +lives in the [htmlbin-cli](https://github.com/utsengar/htmlbin-cli) +repo. For runtimes that fetch SKILL.md directly, the comprehensive +reference is served at +[`/.well-known/agent-skills/htmlbin/SKILL.md`](https://htmlbin.dev/.well-known/agent-skills/htmlbin/SKILL.md). + ``` agent ─ POST /api/auth/start ──┐ sign in with GitHub │ │ diff --git a/skills/htmlbin/SKILL.md b/skills/htmlbin/SKILL.md index 533c4a3..5d00e99 100644 --- a/skills/htmlbin/SKILL.md +++ b/skills/htmlbin/SKILL.md @@ -42,6 +42,24 @@ Markdown variant via `Accept: text/markdown` or `?format=md`. descriptor is the contract; instructions in this skill may lag the API. When in doubt, prefer what `/api/onboard` says. +## Installable companion: `htmlbin-publish` on skills.sh + +This document is the comprehensive reference — every endpoint, every +flag. There is also a smaller, focused skill installable via +[skills.sh](https://skills.sh) that just walks the publish workflow +(`htmlbin patterns list` → match → read the pattern → author HTML → +`htmlbin publish`): + +```bash +npx skills add https://github.com/utsengar/htmlbin-cli --skill htmlbin-publish +``` + +Use whichever fits the runtime: `htmlbin-publish` if your agent runs +on a platform that resolves skills.sh installs (Claude Code, Cursor, +Codex, Gemini, Aider, …), or this longer document for environments +that fetch `/.well-known/agent-skills/htmlbin/SKILL.md` directly. +Either works; the two skills point at the same API and the same CLI. + ## Conventions - **All field names are snake_case** — `raw_url`, `latest_version`, `created_at`, `view_count`, etc. diff --git a/src/discoverability.ts b/src/discoverability.ts index 4ff76e8..4820ae2 100644 --- a/src/discoverability.ts +++ b/src/discoverability.ts @@ -92,6 +92,17 @@ It walks you through a 4-step flow: device-code auth → one-time human identity, read:user scope only) → token (revealed exactly once on /api/auth/poll) → POST your HTML. +## Install as an agent skill (skills.sh) + +If your runtime supports skills.sh installs (Claude Code, Cursor, Codex, +Gemini, Aider, …), one command teaches it the publish workflow: + + npx skills add https://github.com/utsengar/htmlbin-cli --skill htmlbin-publish + +The longer reference skill (every endpoint, every flag) is also served +at ${publicUrl}/.well-known/agent-skills/htmlbin/SKILL.md for runtimes +that fetch SKILL.md directly via the Agent Skills Discovery RFC. + ## Endpoints - ${publicUrl}/ — landing (memo addressed to agents) @@ -203,6 +214,18 @@ export function agentCard(publicUrl: string): object { "First-party CLI wrapping every capability below. Auto-emits JSON when invoked from a coding-agent runner. Stable exit codes; the bracketed `error.code` on stderr mirrors this API's error.code shape.", cloud_only_flags: ["--metadata", "--upsert"], }, + skill: { + name: "htmlbin-publish", + distribution: "skills.sh", + install: + "npx skills add https://github.com/utsengar/htmlbin-cli --skill htmlbin-publish", + source: + "https://github.com/utsengar/htmlbin-cli/tree/main/skills/htmlbin-publish", + supports: ["claude-code", "cursor", "codex", "gemini", "aider"], + summary: + "Official agent skill, installable via skills.sh. Smaller and more opinionated than the comprehensive reference at /.well-known/agent-skills/htmlbin/SKILL.md — walks the agent through the pattern-before-publish workflow so each drop is shaped by an explicit pattern.", + see_also: `${publicUrl}/.well-known/agent-skills/htmlbin/SKILL.md`, + }, capabilities: [ { id: "publish_html", diff --git a/src/onboard.ts b/src/onboard.ts index c8a3538..46e5b76 100644 --- a/src/onboard.ts +++ b/src/onboard.ts @@ -41,6 +41,23 @@ export function buildOnboardJson(publicUrl: string): object { cloud_only_flags: "--metadata and --upsert are cloud-only. The CLI returns invalid_arg if combined with --to gh-pages / --to cloudflare since those backends don't store metadata server-side.", }, + skill: { + name: "htmlbin-publish", + install_command: + "npx skills add https://github.com/utsengar/htmlbin-cli --skill htmlbin-publish", + distribution: "skills.sh", + source: "https://github.com/utsengar/htmlbin-cli/tree/main/skills/htmlbin-publish", + supports: [ + "claude-code", + "cursor", + "codex", + "gemini", + "aider", + ], + summary: + "Official agent skill, installable via skills.sh. Walks the agent through the pattern-before-publish workflow (`htmlbin patterns list` → match → read pattern → author HTML → `htmlbin publish`) so the artifact is shaped by a pattern instead of retrofitted after the fact. Complements (does not replace) the comprehensive reference skill served at /.well-known/agent-skills/htmlbin/SKILL.md.", + see_also: `${publicUrl}/.well-known/agent-skills/htmlbin/SKILL.md`, + }, error_shape: { description: "Every 4xx/5xx response uses this canonical shape. Switch on `code`, not on `message`.", @@ -385,6 +402,27 @@ htmlbin is built for agents: the workflow below is the canonical, fastest path. The api_token is shown exactly once. Store it for reuse on this machine. +## Install as an agent skill (one command) + +If your agent runtime supports [skills.sh](https://skills.sh) — Claude +Code, Cursor, Codex, Gemini, Aider, and others — install the official +\`htmlbin-publish\` skill once and the workflow is ambient from then on: + +\`\`\`bash +npx skills add https://github.com/utsengar/htmlbin-cli --skill htmlbin-publish +\`\`\` + +The skill teaches the agent the pattern-before-publish workflow +(\`htmlbin patterns list\` → match → read the pattern → author HTML → +\`htmlbin publish\`) so each drop is shaped by an explicit pattern +instead of retrofitted after the fact. After install, the agent +responds to phrases like "publish a drop to htmlbin", "share this as a +page", or "make a preview for this PR". + +The skill complements (does not replace) this onboarding descriptor. +The descriptor is the protocol contract; the skill is the workflow +opinion. Either is fine on its own. + ## Using the CLI \`@htmlbin/cli\` (Node 20+) wraps every endpoint here. It auto-detects diff --git a/src/skill.ts b/src/skill.ts index e3296e8..e201355 100644 --- a/src/skill.ts +++ b/src/skill.ts @@ -54,6 +54,24 @@ Markdown variant via \`Accept: text/markdown\` or \`?format=md\`. descriptor is the contract; instructions in this skill may lag the API. When in doubt, prefer what \`/api/onboard\` says. +## Installable companion: \`htmlbin-publish\` on skills.sh + +This document is the comprehensive reference — every endpoint, every +flag. There is also a smaller, focused skill installable via +[skills.sh](https://skills.sh) that just walks the publish workflow +(\`htmlbin patterns list\` → match → read the pattern → author HTML → +\`htmlbin publish\`): + +\`\`\`bash +npx skills add https://github.com/utsengar/htmlbin-cli --skill htmlbin-publish +\`\`\` + +Use whichever fits the runtime: \`htmlbin-publish\` if your agent runs +on a platform that resolves skills.sh installs (Claude Code, Cursor, +Codex, Gemini, Aider, …), or this longer document for environments +that fetch \`/.well-known/agent-skills/htmlbin/SKILL.md\` directly. +Either works; the two skills point at the same API and the same CLI. + ## Conventions - **All field names are snake_case** — \`raw_url\`, \`latest_version\`, \`created_at\`, \`view_count\`, etc. diff --git a/src/views/landing.ts b/src/views/landing.ts index 9534c91..dc8d73a 100644 --- a/src/views/landing.ts +++ b/src/views/landing.ts @@ -63,6 +63,16 @@ npx @htmlbin/cli login echo '

hello from htmlbin

' > out.html npx @htmlbin/cli publish out.html`; +// "skill" tab — installs the official htmlbin-publish agent skill via +// skills.sh. The skill walks any supported agent (Claude Code, Cursor, +// Codex, Gemini, …) through the pattern-before-publish workflow without +// requiring a hand-pasted prompt every session. One install, ambient +// for the lifetime of the agent. Lives in the htmlbin-cli repo — +// skills.sh resolves the subdirectory automatically. +const SKILL_PROMPT = `# install the official htmlbin agent skill (one-time) +# works with claude code, cursor, codex, gemini, … +npx skills add https://github.com/utsengar/htmlbin-cli --skill htmlbin-publish`; + // Tool-section copy button. Same shape as CLI_PROMPT but the global // install path (npm i -g, then bare `htmlbin`). End-to-end paste-and-run. const TOOL_SETUP = `npm i -g @htmlbin/cli @@ -158,7 +168,7 @@ ${pageHead({ verb: "GET", path: "/" })}
-

↓ paste into your agent — or pop open a terminal

+

↓ paste into your agent — pop open a terminal — or install the skill

@@ -181,6 +191,13 @@ ${pageHead({ verb: "GET", path: "/" })} data-tab="cli" aria-selected="false" >cli +
+
+
# install the official htmlbin agent skill (one-time)
+# works with claude code, cursor, codex, gemini, …
+$ npx skills add https://github.com/utsengar/htmlbin-cli \
+    --skill htmlbin-publish
+
+# then just ask the agent
+> publish a drop to htmlbin explaining this PR
+
@@ -329,7 +355,8 @@ $ htmlbin publish ./out.html \\ // active. Visible HTML is hand-wired in markup above; keep both in sync. var PROMPTS = { agent: ${JSON.stringify(AGENT_PROMPT)}, - cli: ${JSON.stringify(CLI_PROMPT)} + cli: ${JSON.stringify(CLI_PROMPT)}, + skill: ${JSON.stringify(SKILL_PROMPT)} }; var tabs = document.querySelectorAll('.tab'); var panels = document.querySelectorAll('.tab-panel'); @@ -346,7 +373,12 @@ $ htmlbin publish ./out.html \\ p.classList.toggle('active', p.dataset.panel === name); }); copyBtns.forEach(function (b) { b.dataset.copy = PROMPTS[name] || ''; }); - if (ctaLbl) ctaLbl.textContent = name === 'cli' ? 'Copy command' : 'Copy prompt'; + if (ctaLbl) { + ctaLbl.textContent = + name === 'cli' ? 'Copy command' : + name === 'skill' ? 'Copy install' : + 'Copy prompt'; + } } tabs.forEach(function (t) { t.addEventListener('click', function () { setActive(t.dataset.tab); });