From 286dc7e6fdfbabb02431602bd1d78d414075da96 Mon Sep 17 00:00:00 2001 From: Kristofer Jussmann Date: Thu, 29 Oct 2026 11:51:18 +0200 Subject: [PATCH] Add Paper Unfold Frames and Paper Unfold Mesh listings Two Creative skills with logos and maintainer review records. Tests now derive listing and sitemap counts from the catalog instead of hard-coding them. Co-Authored-By: Claude Opus 5.5 --- data/listings/paper-unfold-frames.json | 61 +++++++++++++++++++++++ data/listings/paper-unfold-mesh.json | 60 ++++++++++++++++++++++ data/reviews.json | 4 +- site/assets/logos/paper-unfold-frames.svg | 1 + site/assets/logos/paper-unfold-mesh.svg | 1 + tests/test_catalog.py | 2 +- tests/test_publishing.py | 2 +- 7 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 data/listings/paper-unfold-frames.json create mode 100644 data/listings/paper-unfold-mesh.json create mode 100644 site/assets/logos/paper-unfold-frames.svg create mode 100644 site/assets/logos/paper-unfold-mesh.svg diff --git a/data/listings/paper-unfold-frames.json b/data/listings/paper-unfold-frames.json new file mode 100644 index 0000000..218c632 --- /dev/null +++ b/data/listings/paper-unfold-frames.json @@ -0,0 +1,61 @@ +{ + "schema_version": 1, + "id": "paper-unfold-frames", + "name": "Paper Unfold Frames", + "summary": "Photo-real stop-motion of a crumpled paper ball opening into a note, made from GPT-image keyframes.", + "category": "Creative", + "repository": "https://github.com/Ker102/paper-unfold-frames", + "license": "MIT", + "version": "1.0.0", + "distribution": { + "kind": "package", + "url": "https://github.com/Ker102/paper-unfold-frames/releases/download/v1.0.0/paper-unfold-frames.zip", + "label": "Download skill ZIP", + "scope": "One skill: SKILL.md, a frame keying script, two working prompts, a playback snippet and the licence. No media.", + "repository_has_extra_material": true + }, + "installation": [ + { + "title": "Download the focused package", + "body": "Download the ZIP from the release and extract it. It holds only the skill folder; preview media and translations stay on separate branches of the repository.", + "url": "https://github.com/Ker102/paper-unfold-frames/releases/tag/v1.0.0", + "label": "Release v1.0.0" + }, + { + "title": "Add it to your agent", + "body": "Copy the extracted folder into your agent's skills directory (Claude Code: ~/.claude/skills/), or install it straight from main with git.", + "command": "git clone --depth 1 https://github.com/Ker102/paper-unfold-frames ~/.claude/skills/paper-unfold-frames" + }, + { + "title": "Ask for an unfold", + "body": "Describe the shot in plain words, for example: \"Open the video with a crumpled note that unfolds to show our tagline.\" The agent generates a 3x3 grid of stages, keys out the frames and plays them stepped at 6-8 fps." + } + ], + "manual_setup": [ + "Access to a GPT image model, for example through the Figma MCP generate_image tool or the OpenAI API.", + "Python 3 with Pillow, numpy and scipy to key out the frames.", + "A canvas-based video tool such as HyperFrames or Remotion, or a web page." + ], + "notes": [ + "Handwriting or a sketch can be baked into the image prompt so it is revealed as the sheet opens.", + "Sister skill: Paper Unfold Mesh draws the same effect procedurally in code." + ], + "contents": { + "skills": 1, + "references": 0, + "renderers": 0, + "files": 4, + "mcp_tools": 0, + "tools": [ + "GPT image model", + "Python + Pillow, numpy, scipy" + ] + }, + "documentation": "https://github.com/Ker102/paper-unfold-frames/blob/main/SKILL.md", + "type": "Skill", + "image": { + "url": "assets/logos/paper-unfold-frames.svg", + "alt": "A 3x3 grid of paper stages from crumpled ball to flat torn sheet", + "source": "https://github.com/Ker102/paper-unfold-frames/blob/assets/logo.svg" + } +} diff --git a/data/listings/paper-unfold-mesh.json b/data/listings/paper-unfold-mesh.json new file mode 100644 index 0000000..3828fa3 --- /dev/null +++ b/data/listings/paper-unfold-mesh.json @@ -0,0 +1,60 @@ +{ + "schema_version": 1, + "id": "paper-unfold-mesh", + "name": "Paper Unfold Mesh", + "summary": "Procedural paper that crumples, folds or rolls and opens frame by frame on a canvas, with writing that bends with the sheet.", + "category": "Creative", + "repository": "https://github.com/Ker102/paper-unfold-mesh", + "license": "MIT", + "version": "1.0.0", + "distribution": { + "kind": "package", + "url": "https://github.com/Ker102/paper-unfold-mesh/releases/download/v1.0.0/paper-unfold-mesh.zip", + "label": "Download skill ZIP", + "scope": "One skill: SKILL.md, the full source of a 9-scene demo composition and the licence. No media, textures or fonts.", + "repository_has_extra_material": true + }, + "installation": [ + { + "title": "Download the focused package", + "body": "Download the ZIP from the release and extract it. It holds only the skill folder; preview media and translations stay on separate branches of the repository.", + "url": "https://github.com/Ker102/paper-unfold-mesh/releases/tag/v1.0.0", + "label": "Release v1.0.0" + }, + { + "title": "Add it to your agent", + "body": "Copy the extracted folder into your agent's skills directory (Claude Code: ~/.claude/skills/), or install it straight from main with git.", + "command": "git clone --depth 1 https://github.com/Ker102/paper-unfold-mesh ~/.claude/skills/paper-unfold-mesh" + }, + { + "title": "Ask for a variation", + "body": "Describe the shot in plain words, for example: \"Show our three steps on an accordion strip of paper that unfolds one fold at a time.\" Balls, squashed wads, accordions, folded notes and scrolls are covered." + } + ], + "manual_setup": [ + "No image model or API key is needed. It runs in plain canvas 2D with GSAP as the clock.", + "Supply your own paper texture, desk background and handwriting font for the demo composition." + ], + "notes": [ + "Work in progress: the skill records what went wrong and ideas not yet tried, and is updated when projects get better results.", + "Sister skill: Paper Unfold Frames gives a more photo-real single reveal from generated images." + ], + "contents": { + "skills": 1, + "references": 0, + "renderers": 0, + "files": 3, + "mcp_tools": 0, + "tools": [ + "Canvas 2D", + "GSAP" + ] + }, + "documentation": "https://github.com/Ker102/paper-unfold-mesh/blob/main/SKILL.md", + "type": "Skill", + "image": { + "url": "assets/logos/paper-unfold-mesh.svg", + "alt": "A paper sheet drawn as a triangle mesh with one corner folded over", + "source": "https://github.com/Ker102/paper-unfold-mesh/blob/assets/logo.svg" + } +} diff --git a/data/reviews.json b/data/reviews.json index 9d7151d..11f3339 100644 --- a/data/reviews.json +++ b/data/reviews.json @@ -2,6 +2,8 @@ "schema_version":1, "reviews":{ "smooth-motion-graphics":{"reviewed_at":"2026-10-10","status":"artifact-checked","built_with_harneloop":true,"evidence":"Windows: fictional example and alternate brand frames inspected; layout/direction tests and 1080p60 encode/decode checked. Other platforms not runtime-tested.","url":"https://github.com/Ker102/smooth-motion-graphics#what-gets-checked"}, - "vipermesh-blender":{"reviewed_at":"2026-10-10","status":"setup-reviewed","built_with_harneloop":false,"evidence":"Existing release assets, README installation and skill references reviewed. A live Blender bridge was not retested for this listing.","url":"https://github.com/OpenRootdev/vipermesh-blender/releases/tag/v1.3.0"} + "vipermesh-blender":{"reviewed_at":"2026-10-10","status":"setup-reviewed","built_with_harneloop":false,"evidence":"Existing release assets, README installation and skill references reviewed. A live Blender bridge was not retested for this listing.","url":"https://github.com/OpenRootdev/vipermesh-blender/releases/tag/v1.3.0"}, + "paper-unfold-frames":{"reviewed_at":"2026-10-29","status":"artifact-checked","built_with_harneloop":false,"evidence":"Windows: two GPT-image grids keyed with the included script and played in a rendered 1080p HyperFrames reel; frames inspected. Release ZIP contents checked. Other platforms not runtime-tested.","url":"https://github.com/Ker102/paper-unfold-frames#readme"}, + "paper-unfold-mesh":{"reviewed_at":"2026-10-29","status":"artifact-checked","built_with_harneloop":false,"evidence":"Windows: the included 9-scene composition rendered to 1080p with HyperFrames and frames inspected. Marked work in progress; demo textures and fonts are not bundled. Other platforms not runtime-tested.","url":"https://github.com/Ker102/paper-unfold-mesh#readme"} } } diff --git a/site/assets/logos/paper-unfold-frames.svg b/site/assets/logos/paper-unfold-frames.svg new file mode 100644 index 0000000..9518226 --- /dev/null +++ b/site/assets/logos/paper-unfold-frames.svg @@ -0,0 +1 @@ + diff --git a/site/assets/logos/paper-unfold-mesh.svg b/site/assets/logos/paper-unfold-mesh.svg new file mode 100644 index 0000000..7e102cd --- /dev/null +++ b/site/assets/logos/paper-unfold-mesh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/test_catalog.py b/tests/test_catalog.py index b752ed3..9fece44 100644 --- a/tests/test_catalog.py +++ b/tests/test_catalog.py @@ -12,7 +12,7 @@ def setUp(self): self.now=datetime(2026,10,10,12,tzinfo=c.UTC) self.badge=f'[![Listed in Harness Library]({c.SITE}badges/{self.entry["id"]}.svg)]({c.SITE}#{self.entry["id"]})' def test_seed_entries_valid(self): - self.assertEqual(len(c.checked_catalog()['listings']),2) + self.assertEqual(len(c.checked_catalog()['listings']),len(c.entries())) def test_install_and_manual_setup_are_required(self): for field in ['installation','manual_setup']: e=copy.deepcopy(self.entry);e.pop(field) diff --git a/tests/test_publishing.py b/tests/test_publishing.py index 5cfed70..f9ebd75 100644 --- a/tests/test_publishing.py +++ b/tests/test_publishing.py @@ -55,7 +55,7 @@ def test_home_links_are_real_paths_and_submissions_are_prominent(self): self.assertIn('New submissions welcome',' '.join(page.data)) def test_sitemap_contains_only_existing_canonical_pages(self): root=ET.parse(self.out/'sitemap.xml').getroot();locations=[el.text for el in root.iter('{http://www.sitemaps.org/schemas/sitemap/0.9}loc')] - self.assertEqual(len(locations),5);self.assertEqual(len(set(locations)),5) + n=3+len(self.catalog['listings']);self.assertEqual(len(locations),n);self.assertEqual(len(set(locations)),n) for url in locations: self.assertNotIn('#',url);self.assertTrue((self.out/url.removeprefix(p.SITE)/'index.html').is_file()) def test_json_and_html_escape_submitted_script_content(self):