diff --git a/optional-skills/creative/auteur/LICENSE b/optional-skills/creative/auteur/LICENSE index 34d81ae5d3..6c92f892af 100644 --- a/optional-skills/creative/auteur/LICENSE +++ b/optional-skills/creative/auteur/LICENSE @@ -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 diff --git a/optional-skills/creative/auteur/SKILL.md b/optional-skills/creative/auteur/SKILL.md index fc4d0bc17f..77fb187899 100644 --- a/optional-skills/creative/auteur/SKILL.md +++ b/optional-skills/creative/auteur/SKILL.md @@ -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 `** 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 `** 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 `** → 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. diff --git a/tests/skills/test_auteur_skill.py b/tests/skills/test_auteur_skill.py index 8456cf706a..ed6a760f55 100644 --- a/tests/skills/test_auteur_skill.py +++ b/tests/skills/test_auteur_skill.py @@ -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 diff --git a/website/docs/user-guide/skills/optional/creative/creative-auteur.md b/website/docs/user-guide/skills/optional/creative/creative-auteur.md index da1c70d55b..2f43dfb8b2 100644 --- a/website/docs/user-guide/skills/optional/creative/creative-auteur.md +++ b/website/docs/user-guide/skills/optional/creative/creative-auteur.md @@ -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 `** 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 `** 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 `** → 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.