Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
│ │
Expand Down
18 changes: 18 additions & 0 deletions skills/htmlbin/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
23 changes: 23 additions & 0 deletions src/discoverability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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",
Expand Down
38 changes: 38 additions & 0 deletions src/onboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`.",
Expand Down Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions src/skill.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
38 changes: 35 additions & 3 deletions src/views/landing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ npx @htmlbin/cli login
echo '<h1>hello from htmlbin</h1>' > 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
Expand Down Expand Up @@ -158,7 +168,7 @@ ${pageHead({ verb: "GET", path: "/" })}
</section>

<section class="body">
<p class="prompt-cue">↓ paste into your agent — or pop open a terminal</p>
<p class="prompt-cue">↓ paste into your agent — pop open a terminal — or install the skill</p>

<div class="prompt">
<div class="prompt-chrome">
Expand All @@ -181,6 +191,13 @@ ${pageHead({ verb: "GET", path: "/" })}
data-tab="cli"
aria-selected="false"
>cli</button>
<button
class="tab"
type="button"
role="tab"
data-tab="skill"
aria-selected="false"
>skill</button>
</div>
<button
class="prompt-mark js-copy-prompt"
Expand Down Expand Up @@ -209,6 +226,15 @@ $ echo '<span class="em">&lt;h1&gt;hello from htmlbin&lt;/h1&gt;</span>' &gt; ou
$ npx <span class="em">@htmlbin/cli</span> publish out.html
<span class="arr">→</span> <span class="em">https://htmlbin.dev/p/aB3xK7g</span></pre>
</div>
<div class="tab-panel" data-panel="skill" role="tabpanel">
<pre><span class="cmt"># install the official htmlbin agent skill (one-time)</span>
<span class="cmt"># works with claude code, cursor, codex, gemini, …</span>
$ npx <span class="em">skills add</span> https://github.com/utsengar/htmlbin-cli \
--skill <span class="em">htmlbin-publish</span>

<span class="cmt"># then just ask the agent</span>
&gt; <span class="em">publish a drop to htmlbin explaining this PR</span></pre>
</div>
</div>
</div>

Expand Down Expand Up @@ -329,7 +355,8 @@ $ htmlbin <span class="key">publish</span> ./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');
Expand All @@ -346,7 +373,12 @@ $ htmlbin <span class="key">publish</span> ./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); });
Expand Down
Loading