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'[]({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):