fix(skills): auteur — proper upstream attribution, windows platform, trimmed tests

Review follow-ups on the port (all verified against the upstream snapshot,
which I re-downloaded and diffed: every scripts/*.mjs and template is the
upstream file byte-for-byte after CRLF→LF, except one `reference/` →
`references/` path fix; the reference docs differ only by Hermes adaptation
notes and the same path fix).

- LICENSE: header naming the upstream repo, pinned commit 9bca227d… and the
  copyright holder above the verbatim MIT text.
- SKILL.md frontmatter: `author` credits the upstream human first, Hermes
  Agent second (skills/AGENTS.md rule 4); `metadata.hermes.upstream` pin in
  the same shape mono-color/pr-lens use; `category: creative`; H1
  `# Auteur Skill` with a linked provenance blockquote.
- `platforms` gains `windows`: the declared prerequisites (Node 18+,
  Playwright, optional ffmpeg) all run on Windows and no script uses a
  POSIX-only primitive (audited: no /tmp, spawn/exec of shells, fcntl, etc).
- Routing examples translated from Russian to English (marked as translated
  from upstream) so an English-language skill doesn't carry stray artefacts.
- tests/skills/test_auteur_skill.py: keep the two port-specific invariants
  (path annotations, de-Claude residue). Dropped the exact-count tree
  snapshot (change detector), the `~/.hermes/hermes-agent` host-dependent
  related_skills fallback, and the frontmatter/description checks that
  tests/skills/test_authoring_standards.py already enforces repo-wide.
- Regenerated the docs page with website/scripts/generate-skill-docs.py
  (scoped to this skill).
This commit is contained in:
teknium1
2026-09-14 18:39:36 -07:00
committed by Teknium
parent 251ab05000
commit 54255f1e9e
4 changed files with 36 additions and 82 deletions

View File

@@ -1,3 +1,8 @@
auteur — ported from https://github.com/agiwhitelist/auteur
Upstream snapshot: commit 9bca227df9877e60dc45d49783c8cbd885eccd9b (2026-08-06)
Upstream author / copyright holder: agiwhitelist (https://github.com/agiwhitelist)
The MIT license text below is reproduced verbatim from the upstream LICENSE.
MIT License
Copyright (c) 2026 agiwhitelist

View File

@@ -2,17 +2,23 @@
name: auteur
description: Design and build cinematic, award-level web pages.
version: 1.3.1
author: agiwhitelist (upstream) / Hermes port
author: agiwhitelist (https://github.com/agiwhitelist, upstream agiwhitelist/auteur), ported by Hermes Agent
license: MIT
platforms: [linux, macos]
platforms: [linux, macos, windows]
metadata:
hermes:
tags: [web-design, cinematic, scroll-animation, design-system, anti-slop, frontend]
category: creative
related_skills: [popular-web-designs, design-md, p5js]
upstream: https://github.com/agiwhitelist/auteur (pinned 9bca227d)
---
Ported from agiwhitelist/auteur (MIT), snapshot 9bca227df9877e60dc45d49783c8cbd885eccd9b.
# Auteur Skill
> Ported from [agiwhitelist/auteur](https://github.com/agiwhitelist/auteur) (MIT), snapshot
> commit [`9bca227d`](https://github.com/agiwhitelist/auteur/commit/9bca227df9877e60dc45d49783c8cbd885eccd9b)
> — see `LICENSE`. Scripts, templates and references are the upstream files (CRLF→LF), with
> Hermes adaptation notes and `references/` path fixes as the only edits.
Auteur designs and builds web experiences the way a film director makes a film: script first, then assets, then the shoot, then the cut. It has three registers — **build** (an excellent conventional site), **direct** (a cinematic scroll-directed site) and **system** (a multi-screen product as one design system) — on one shared core of taste. Nothing ships until the page passes an executable anti-slop gate and the skill has looked at its own output.
@@ -86,9 +92,9 @@ Read the argument / brief and route:
2. **`build`** or the brief is ONE conventional surface — a marketing page, a landing, a single product page → load `references/build.md`.
3. **`system`** or the brief has **more than one screen that must feel like one product** — app, dashboard, admin, settings, onboarding, a docs or content site with real navigation → load `references/system.md`. The unit of design becomes the component × state, the failure mode becomes drift rather than boredom, and there is deliberately **no peak**. If you are already in `build` and a second screen appears, stop and switch: half a system is worse than either.
4. **`edit`** or the request modifies a page this skill built (the project contains `design/DESIGN.md`) — "add a section", "change the pricing", "swap the hero copy" → read `design/DESIGN.md` FIRST and follow its Editing protocol: reuse its tokens, section-opening patterns, and motion families; after the change run slopscan and re-shoot the affected viewports. An edit that ignores DESIGN.md is a regression even if it looks good in isolation.
5. **`recon <brief>`** or the ask is only for reference material — "найди референсы", "собери мудборд", "what's the state of the art for X sites" → load `references/recon.md` and run just that phase: scout live sites, build the moodboard, hand back `design/refs/REFERENCES.md` (with the `steal:` lines filled) and `design/moodboard/contact-sheet.png` (with the read filled). No commit-sheet, no build.
5. **`recon <brief>`** or the ask is only for reference material — "find references", "put together a moodboard", "what's the state of the art for X sites" → load `references/recon.md` and run just that phase: scout live sites, build the moodboard, hand back `design/refs/REFERENCES.md` (with the `steal:` lines filled) and `design/moodboard/contact-sheet.png` (with the read filled). No commit-sheet, no build.
6. **`audit <path-or-url>`** → load `references/verify.md` and run the verification pipeline on an auteur-built page. If the target is an existing UI auteur didn't build and the user wants it *polished* rather than *rebuilt*, say that a dedicated UI-polish/critique pass (upstream paired auteur with a separate 'impeccable' skill, not vendored here) is the right tool and offer to continue only if they want a rebuild.
7. **Ambiguous** (e.g. plain "сделай лендинг") → ask exactly one question: "Обычный отличный лендинг или кино-режим со scroll-режиссурой и генерацией ассетов?" Then route. (Multi-screen briefs are not ambiguous — they are `system`.) Don't ask anything else yet — each register runs its own intake.
7. **Ambiguous** (e.g. plain "make a landing page") → ask exactly one question: "A great conventional landing page, or cinema mode with scroll direction and generated assets?" (upstream phrased these example briefs in Russian; translated here.) Then route. (Multi-screen briefs are not ambiguous — they are `system`.) Don't ask anything else yet — each register runs its own intake.
All three registers share phase zero, and its centre of gravity is the commit-sheet. Order differs: **build** runs recon → commit-sheet → mockup; **direct** runs recon → storyboard → commit-sheet → mockup, because the film's scenes are what the six decisions get made *about*; **system** runs recon → system-sheet (route map + component inventory) → commit-sheet → mockup, because the six decisions get made about a product, not a page. Either way nothing is coded before the sheet is full.

View File

@@ -1,58 +1,20 @@
"""Tests for the auteur optional skill (ported from agiwhitelist/auteur, MIT)."""
"""Tests for the auteur optional skill (ported from agiwhitelist/auteur, MIT).
Frontmatter shape, description length and related_skills resolution are
covered repo-wide by tests/skills/test_authoring_standards.py; this file only
holds the two invariants specific to the port.
"""
import re
from pathlib import Path
import yaml
def _find_skill_dir() -> Path:
base = Path(__file__).resolve().parents[2]
candidate = base / "optional-skills" / "creative" / "auteur"
if candidate.is_dir():
return candidate
# fallback: glob from repo root for any auteur skill dir
for p in base.glob("**/optional-skills/**/auteur"):
if (p / "SKILL.md").exists():
return p
raise AssertionError("auteur skill directory not found relative to test file")
SKILL_DIR = _find_skill_dir()
SKILL_DIR = Path(__file__).resolve().parents[2] / "optional-skills" / "creative" / "auteur"
SKILL_MD = SKILL_DIR / "SKILL.md"
def _frontmatter() -> dict:
text = SKILL_MD.read_text(encoding="utf-8")
assert text.startswith("---\n"), "SKILL.md must start with YAML frontmatter"
fm = text.split("---\n", 2)[1]
data = yaml.safe_load(fm)
assert isinstance(data, dict)
return data
def test_frontmatter_parses():
fm = _frontmatter()
assert fm["name"] == "auteur"
def test_description_length():
fm = _frontmatter()
desc = fm["description"]
assert isinstance(desc, str) and desc.strip()
assert len(desc) <= 60, f"description is {len(desc)} chars, must be <= 60"
def test_required_fields():
fm = _frontmatter()
assert fm.get("license") == "MIT"
assert fm.get("author"), "author missing"
platforms = fm.get("platforms")
assert isinstance(platforms, list) and platforms, "platforms missing"
assert set(platforms) <= {"linux", "macos", "windows"}
assert fm.get("version")
def test_mentioned_paths_exist_or_annotated():
"""Every references/scripts/templates path mentioned in SKILL.md exists on
disk, or its line carries an 'upstream' / 'not vendored' annotation."""
disk, or its line carries an 'upstream' / 'not vendored' annotation (the
port deliberately drops upstream's README gallery and CLI assets)."""
pattern = re.compile(r"(references|scripts|templates)/[A-Za-z0-9._-]+")
missing = []
for line in SKILL_MD.read_text(encoding="utf-8").splitlines():
@@ -68,31 +30,8 @@ def test_mentioned_paths_exist_or_annotated():
def test_no_claude_residue():
"""Upstream is a Claude Code plugin; its plugin-only frontmatter keys and
harness name must not leak into the Hermes port."""
text = SKILL_MD.read_text(encoding="utf-8").lower()
for token in ("claude", "allowed-tools", "argument-hint"):
assert token not in text, f"residual '{token}' in SKILL.md"
def test_related_skills_resolve():
fm = _frontmatter()
related = (fm.get("metadata") or {}).get("hermes", {}).get("related_skills", [])
if not related:
return # empty list is allowed
staging_root = Path(__file__).resolve().parents[2]
repo_root = Path.home() / ".hermes" / "hermes-agent"
roots = [
staging_root / "skills",
staging_root / "optional-skills",
repo_root / "skills",
repo_root / "optional-skills",
]
for name in related:
found = any(r.is_dir() and list(r.glob(f"**/{name}")) for r in roots)
assert found, f"related skill '{name}' not found in skills/optional-skills trees"
def test_vendored_tree_shape():
assert (SKILL_DIR / "LICENSE").exists()
assert len(list((SKILL_DIR / "references").glob("*.md"))) == 11
assert len(list((SKILL_DIR / "scripts").glob("*.mjs"))) == 8
assert len(list((SKILL_DIR / "templates").iterdir())) == 6

View File

@@ -17,9 +17,9 @@ Design and build cinematic, award-level web pages.
| Source | Optional — install with `hermes skills install official/creative/auteur` |
| Path | `optional-skills/creative/auteur` |
| Version | `1.3.1` |
| Author | agiwhitelist (upstream) / Hermes port |
| Author | agiwhitelist (https://github.com/agiwhitelist, upstream agiwhitelist/auteur), ported by Hermes Agent |
| License | MIT |
| Platforms | linux, macos |
| Platforms | linux, macos, windows |
| Tags | `web-design`, `cinematic`, `scroll-animation`, `design-system`, `anti-slop`, `frontend` |
| Related skills | [`popular-web-designs`](/docs/user-guide/skills/bundled/creative/creative-popular-web-designs), [`design-md`](/docs/user-guide/skills/bundled/creative/creative-design-md), [`p5js`](/docs/user-guide/skills/bundled/creative/creative-p5js) |
@@ -29,8 +29,12 @@ Design and build cinematic, award-level web pages.
The following is the complete skill definition that Hermes loads when this skill is triggered. This is what the agent sees as instructions when the skill is active.
:::
Ported from agiwhitelist/auteur (MIT), snapshot 9bca227df9877e60dc45d49783c8cbd885eccd9b.
# Auteur Skill
> Ported from [agiwhitelist/auteur](https://github.com/agiwhitelist/auteur) (MIT), snapshot
> commit [`9bca227d`](https://github.com/agiwhitelist/auteur/commit/9bca227df9877e60dc45d49783c8cbd885eccd9b)
> — see `LICENSE`. Scripts, templates and references are the upstream files (CRLF→LF), with
> Hermes adaptation notes and `references/` path fixes as the only edits.
Auteur designs and builds web experiences the way a film director makes a film: script first, then assets, then the shoot, then the cut. It has three registers — **build** (an excellent conventional site), **direct** (a cinematic scroll-directed site) and **system** (a multi-screen product as one design system) — on one shared core of taste. Nothing ships until the page passes an executable anti-slop gate and the skill has looked at its own output.
@@ -104,9 +108,9 @@ Read the argument / brief and route:
2. **`build`** or the brief is ONE conventional surface — a marketing page, a landing, a single product page → load `references/build.md`.
3. **`system`** or the brief has **more than one screen that must feel like one product** — app, dashboard, admin, settings, onboarding, a docs or content site with real navigation → load `references/system.md`. The unit of design becomes the component × state, the failure mode becomes drift rather than boredom, and there is deliberately **no peak**. If you are already in `build` and a second screen appears, stop and switch: half a system is worse than either.
4. **`edit`** or the request modifies a page this skill built (the project contains `design/DESIGN.md`) — "add a section", "change the pricing", "swap the hero copy" → read `design/DESIGN.md` FIRST and follow its Editing protocol: reuse its tokens, section-opening patterns, and motion families; after the change run slopscan and re-shoot the affected viewports. An edit that ignores DESIGN.md is a regression even if it looks good in isolation.
5. **`recon <brief>`** or the ask is only for reference material — "найди референсы", "собери мудборд", "what's the state of the art for X sites" → load `references/recon.md` and run just that phase: scout live sites, build the moodboard, hand back `design/refs/REFERENCES.md` (with the `steal:` lines filled) and `design/moodboard/contact-sheet.png` (with the read filled). No commit-sheet, no build.
5. **`recon <brief>`** or the ask is only for reference material — "find references", "put together a moodboard", "what's the state of the art for X sites" → load `references/recon.md` and run just that phase: scout live sites, build the moodboard, hand back `design/refs/REFERENCES.md` (with the `steal:` lines filled) and `design/moodboard/contact-sheet.png` (with the read filled). No commit-sheet, no build.
6. **`audit <path-or-url>`** → load `references/verify.md` and run the verification pipeline on an auteur-built page. If the target is an existing UI auteur didn't build and the user wants it *polished* rather than *rebuilt*, say that a dedicated UI-polish/critique pass (upstream paired auteur with a separate 'impeccable' skill, not vendored here) is the right tool and offer to continue only if they want a rebuild.
7. **Ambiguous** (e.g. plain "сделай лендинг") → ask exactly one question: "Обычный отличный лендинг или кино-режим со scroll-режиссурой и генерацией ассетов?" Then route. (Multi-screen briefs are not ambiguous — they are `system`.) Don't ask anything else yet — each register runs its own intake.
7. **Ambiguous** (e.g. plain "make a landing page") → ask exactly one question: "A great conventional landing page, or cinema mode with scroll direction and generated assets?" (upstream phrased these example briefs in Russian; translated here.) Then route. (Multi-screen briefs are not ambiguous — they are `system`.) Don't ask anything else yet — each register runs its own intake.
All three registers share phase zero, and its centre of gravity is the commit-sheet. Order differs: **build** runs recon → commit-sheet → mockup; **direct** runs recon → storyboard → commit-sheet → mockup, because the film's scenes are what the six decisions get made *about*; **system** runs recon → system-sheet (route map + component inventory) → commit-sheet → mockup, because the six decisions get made about a product, not a page. Either way nothing is coded before the sheet is full.