From c00b57fc6a39667e24a37c99f85532e79c85ff10 Mon Sep 17 00:00:00 2001 From: Maroun Najjar <60901592+thecolormaroun@users.noreply.github.com> Date: Thu, 5 Nov 2026 09:15:37 -0800 Subject: [PATCH] feat(stewdio): import the blank-page motion-brief skill Adds Blake Shao's blank-page (StewdioAI/blank-page, MIT) as a new pinned provider, so `/blank-page` turns a one-line motion brief into a referenced, beat-by-beat prompt. Pinned at cd42b37; the weekly maintenance lane now tracks it alongside the other providers. - Register the stewdio provider (upstreams, lock, imported-skills package, explicit-source-json import rule, stewdio-skills inventory row, lane allowlist root). - import-pinned-skills.py: support a provider with no prior inventory rows, allowlist its root, and unescape double-quoted descriptions. - Classifier and layout tool learn the stewdio provider; rename the classifier's design-import set to PINNED_DESIGN_IMPORTS. find_refs.py was reviewed: curl/ffmpeg against are.na, Pinterest, Sketchfab and Objaverse only; SKETCHFAB_TOKEN goes only to Sketchfab. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- THIRD_PARTY_NOTICES.md | 1 + .../capability-reconciliation.json | 6 +- config/runtime-targets.json | 2 +- config/stack-maintenance.json | 2 + docs/skill-architecture.md | 8 +- packages/imported-skills/package.json | 2 +- registry/capabilities.json | 67 +++- registry/maintenance-imports.json | 17 + registry/maintenance-sources.json | 10 + .../migrations/2026-07-23-skill-layout.json | 5 + registry/upstreams.json | 3 +- scripts/apply-skill-layout.py | 4 +- scripts/classify-capabilities.py | 9 +- scripts/import-pinned-skills.py | 20 +- skills/imported/stewdio/blank-page/SKILL.md | 236 ++++++++++++ .../stewdio/blank-page/agents/openai.yaml | 3 + .../stewdio/blank-page/capability.json | 63 ++++ .../stewdio/blank-page/references/examples.md | 193 ++++++++++ .../references/finding-references.md | 312 ++++++++++++++++ .../stewdio/blank-page/references/patterns.md | 133 +++++++ .../stewdio/blank-page/references/source.json | 21 ++ .../blank-page/references/vocabulary.md | 128 +++++++ .../stewdio/blank-page/scripts/find_refs.py | 339 ++++++++++++++++++ tests/test_stack_maintenance.py | 1 + tests/test_upstream_packages.py | 4 +- upstreams.lock.json | 2 +- 27 files changed, 1568 insertions(+), 25 deletions(-) create mode 100644 skills/imported/stewdio/blank-page/SKILL.md create mode 100644 skills/imported/stewdio/blank-page/agents/openai.yaml create mode 100644 skills/imported/stewdio/blank-page/capability.json create mode 100644 skills/imported/stewdio/blank-page/references/examples.md create mode 100644 skills/imported/stewdio/blank-page/references/finding-references.md create mode 100644 skills/imported/stewdio/blank-page/references/patterns.md create mode 100644 skills/imported/stewdio/blank-page/references/source.json create mode 100644 skills/imported/stewdio/blank-page/references/vocabulary.md create mode 100644 skills/imported/stewdio/blank-page/scripts/find_refs.py diff --git a/README.md b/README.md index 2dc8611..d7d8d9c 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ the product unless they directly support a named design/build workflow. Read the detailed contracts: -- [`docs/skill-architecture.md`](docs/skill-architecture.md) — the current 156-capability estate, cuts, merges, families, packages, and routing model. +- [`docs/skill-architecture.md`](docs/skill-architecture.md) — the current 157-capability estate, cuts, merges, families, packages, and routing model. - [`docs/architecture.md`](docs/architecture.md) — ownership, catalog, and inclusion boundary. - [`docs/capability-lifecycle.md`](docs/capability-lifecycle.md) — evidence, review, and lifecycle transitions. - [`docs/bookmark-curation.md`](docs/bookmark-curation.md) — safe intake through review packet. diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index a6e7844..957294e 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -9,5 +9,6 @@ Stack owns command mappings and package metadata, not the upstream skill impleme | Matt Pocock skills | mattpocock/skills | `391a2701dd948f94f56a39f7533f8eea9a859c87` | MIT | | David Ondrej skills | davidondrej/skills | `5c99080334072075eb9e0a17837f7d24e4f3e6ae` | MIT | | Emil Kowalski skills | emilkowalski/skills | `c8a79627b59d72d764d6ab6f2c87c09a48169833` | MIT | +| Stewdio blank-page skill | StewdioAI/blank-page | `cd42b37fa7cd0a5550e51f45cc8f82f63377b98c` | MIT | Stack-Codex is Stack-owned repository content, bundled under `packages/stack-codex/content` so a GitHub clone contains the complete eight-skill package. Its package pin, `483015638591618e884d4c21f1fa037b645bb872e33acf063fa7a5f802c80df3`, is a deterministic SHA-256 digest over sorted relative paths and exact file bytes. It is not an external upstream and does not appear in the third-party table above. diff --git a/artifacts/audits/phase1-architecture/capability-reconciliation.json b/artifacts/audits/phase1-architecture/capability-reconciliation.json index ac7b8b5..83fde25 100644 --- a/artifacts/audits/phase1-architecture/capability-reconciliation.json +++ b/artifacts/audits/phase1-architecture/capability-reconciliation.json @@ -126,6 +126,7 @@ "skills/imported/matt/matt-triage/SKILL.md": "skills/imported/matt/matt-triage/capability.json", "skills/imported/matt/matt-wayfinder/SKILL.md": "skills/imported/matt/matt-wayfinder/capability.json", "skills/imported/matt/matt-writing-great-skills/SKILL.md": "skills/imported/matt/matt-writing-great-skills/capability.json", + "skills/imported/stewdio/blank-page/SKILL.md": "skills/imported/stewdio/blank-page/capability.json", "skills/imported/studio/design/asset-generation/SKILL.md": "skills/imported/studio/design/asset-generation/capability.json", "skills/imported/studio/design/design-system/SKILL.md": "skills/imported/studio/design/design-system/capability.json", "skills/imported/studio/design/layout-strategy/SKILL.md": "skills/imported/studio/design/layout-strategy/capability.json", @@ -284,6 +285,7 @@ "skills/imported/matt/matt-triage/SKILL.md", "skills/imported/matt/matt-wayfinder/SKILL.md", "skills/imported/matt/matt-writing-great-skills/SKILL.md", + "skills/imported/stewdio/blank-page/SKILL.md", "skills/imported/studio/design/asset-generation/SKILL.md", "skills/imported/studio/design/design-system/SKILL.md", "skills/imported/studio/design/layout-strategy/SKILL.md", @@ -326,8 +328,8 @@ "missing": [] }, "counts": { - "callable_skills": 156, - "manifests": 156, + "callable_skills": 157, + "manifests": 157, "package_exports": 20, "private_declarations": 1, "unclassified": 0 diff --git a/config/runtime-targets.json b/config/runtime-targets.json index 94acde2..1c8f9f3 100644 --- a/config/runtime-targets.json +++ b/config/runtime-targets.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "catalog_digest": "82746e82d33ae72d52e029aa3758fd469d02644ddc2adb584652872f31316bea", + "catalog_digest": "fc8fee82769187387a9e66ecf35ae6c67ba572454d56a4f02d1e13de8872182e", "targets": [ { "name": "claude", diff --git a/config/stack-maintenance.json b/config/stack-maintenance.json index 3a44142..f3aaa63 100644 --- a/config/stack-maintenance.json +++ b/config/stack-maintenance.json @@ -14,6 +14,7 @@ "emil-design-eng", "review-animations", "emil-skills", + "stewdio-skills", "illo-skill", "codex-plugin-marketplace", "claude-plugin-marketplace", @@ -103,6 +104,7 @@ "skills/imported/matt/", "skills/imported/david/", "skills/imported/emil/", + "skills/imported/stewdio/", "skills/design/review-animations/", "docs/stack-maintenance.md" ], diff --git a/docs/skill-architecture.md b/docs/skill-architecture.md index 5bbdb7c..a5f3ad4 100644 --- a/docs/skill-architecture.md +++ b/docs/skill-architecture.md @@ -7,16 +7,16 @@ Stack is a runtime-neutral control plane for software work. Logical command IDs The refactor began with 150 callable skills. Nine personal-operations and knowledge-management workflows were integrated into their existing native owners and removed from Stack, leaving 141 capabilities. The full Emil Kowalski -collection (15 more pinned imports under `skills/imported/emil/`) brings the -catalog to 156 capabilities: 148 active capabilities and eight deprecated -compatibility routes. +collection (15 more pinned imports under `skills/imported/emil/`) and Stewdio's +`blank-page` (`skills/imported/stewdio/`) bring the catalog to 157 capabilities: +149 active capabilities and eight deprecated compatibility routes. | Family | Capabilities | | --- | ---: | | Core | 5 | | Product | 6 | | Planning | 7 | -| Design | 28 | +| Design | 29 | | Engineering | 71 | | Orchestration | 11 | | Review | 5 | diff --git a/packages/imported-skills/package.json b/packages/imported-skills/package.json index 191b1b5..951a6b1 100644 --- a/packages/imported-skills/package.json +++ b/packages/imported-skills/package.json @@ -1 +1 @@ -{"schema_version":1,"provider":"imported-skills","registry":"registry/upstreams.json","source_mode":"pinned-import","copy_upstream_source":false,"providers":["matt","david","emil"],"provenance_rule":"Functional family placement does not replace provider identity."} +{"schema_version":1,"provider":"imported-skills","registry":"registry/upstreams.json","source_mode":"pinned-import","copy_upstream_source":false,"providers":["matt","david","emil","stewdio"],"provenance_rule":"Functional family placement does not replace provider identity."} diff --git a/registry/capabilities.json b/registry/capabilities.json index 1a54c3f..379c169 100644 --- a/registry/capabilities.json +++ b/registry/capabilities.json @@ -567,6 +567,69 @@ "validation_class": "representative-route", "visibility": "extended" }, + { + "artifact_type": "skill", + "audit_status": "reviewed", + "canonical_name": "blank-page", + "commands": [ + "stack.design" + ], + "context": { + "inputs": [ + "request", + "workspace-context" + ], + "outputs": [ + "capability-result" + ] + }, + "disposition": { + "evidence_gap": null, + "next_review_trigger": "Reassess on source, export, or runtime-target change.", + "status": "keep" + }, + "domain": "design", + "family": "design", + "lifecycle": "active", + "overlaps": [], + "ownership": { + "package": "imported-skills", + "provider": "stewdio", + "source_path": "skills/imported/stewdio/blank-page/SKILL.md" + }, + "provenance": { + "license": "MIT", + "posture": "imported-upstream", + "source_identity": "upstream:stewdio/skills/blank-page" + }, + "purpose": "Turn a one-line motion / animation / design brief into the full prompt: a committed look grounded in five reference images, three motion references, numbered beats with a turn, and the refs and assets attached. Also tightens edit notes. Use for \"/blank-page\", \"expand this prompt\", \"make this prompt more specific\", \"what is missing from this prompt\", \"help me write the prompt for X\", or whenever a one-line animation / composition / design brief is about to be handed to an agent.", + "role": "leaf", + "runtimes": { + "publish_targets": [ + "claude", + "codex" + ], + "supported": [ + "claude", + "codex" + ] + }, + "schema_version": 1, + "source": { + "skill_path": "skills/imported/stewdio/blank-page/SKILL.md" + }, + "trust_class": "read-only", + "validation": { + "evidence": [ + "reviewed-estate-refactor", + "structural-classification", + "primary-runtime-parity" + ], + "status": "validated" + }, + "validation_class": "representative-route", + "visibility": "extended" + }, { "artifact_type": "skill", "audit_status": "reviewed", @@ -9870,7 +9933,7 @@ "catalog_kind": "stack-capability-catalog", "schema_version": 1, "summary": { - "callable_entrypoint_count": 156, - "capability_count": 156 + "callable_entrypoint_count": 157, + "capability_count": 157 } } diff --git a/registry/maintenance-imports.json b/registry/maintenance-imports.json index d7e0b6d..77169ed 100644 --- a/registry/maintenance-imports.json +++ b/registry/maintenance-imports.json @@ -115,6 +115,23 @@ "target": "skills/imported/emil/emil-write-swift" } ] + }, + { + "id": "stewdio", + "display_name": "Blake Shao (Stewdio)", + "target_root": ".", + "target_prefix": "", + "mapping": "explicit-source-json", + "source_metadata": "references/source.json", + "license": "MIT", + "retained_targets": [], + "retained_files": [], + "targets": [ + { + "source": "skills/blank-page", + "target": "skills/imported/stewdio/blank-page" + } + ] } ] } diff --git a/registry/maintenance-sources.json b/registry/maintenance-sources.json index 08bbba9..d08834b 100644 --- a/registry/maintenance-sources.json +++ b/registry/maintenance-sources.json @@ -132,6 +132,16 @@ "target_paths": ["skills/imported/emil/emil-animate", "skills/imported/emil/emil-animate-expo", "skills/imported/emil/emil-animation-performance", "skills/imported/emil/emil-animation-vocabulary", "skills/imported/emil/emil-apple-design", "skills/imported/emil/emil-ask-sonner", "skills/imported/emil/emil-break-ui", "skills/imported/emil/emil-choreograph", "skills/imported/emil/emil-find-animation-opportunities", "skills/imported/emil/emil-improve-animations", "skills/imported/emil/emil-mobile-native", "skills/imported/emil/emil-pick-ui-library", "skills/imported/emil/emil-prototype", "skills/imported/emil/emil-remove-animations", "skills/imported/emil/emil-write-swift"], "required_exports": ["emil-animate", "emil-animate-expo", "emil-animation-performance", "emil-animation-vocabulary", "emil-apple-design", "emil-ask-sonner", "emil-break-ui", "emil-choreograph", "emil-find-animation-opportunities", "emil-improve-animations", "emil-mobile-native", "emil-pick-ui-library", "emil-prototype", "emil-remove-animations", "emil-write-swift"] }, + { + "id": "stewdio-skills", + "target": "Blake Shao (Stewdio) imported skill collection", + "disposition": "catalog-managed-provider", + "provider_ref": "StewdioAI/blank-page", + "pin_source": "registry/upstreams.json:stewdio", + "provider_id": "stewdio", + "target_paths": ["skills/imported/stewdio/blank-page"], + "required_exports": ["blank-page"] + }, { "id": "illo-skill", "target": "illo external plugin and marketplace", diff --git a/registry/migrations/2026-07-23-skill-layout.json b/registry/migrations/2026-07-23-skill-layout.json index fd14f75..cae9d2a 100644 --- a/registry/migrations/2026-07-23-skill-layout.json +++ b/registry/migrations/2026-07-23-skill-layout.json @@ -46,6 +46,11 @@ "destination": "skills/design/better-icons/SKILL.md", "source": "skills/better-icons/SKILL.md" }, + { + "canonical_name": "blank-page", + "destination": "skills/imported/stewdio/blank-page/SKILL.md", + "source": "skills/imported/stewdio/blank-page/SKILL.md" + }, { "canonical_name": "bolder", "destination": "skills/imported/impeccable/bolder/SKILL.md", diff --git a/registry/upstreams.json b/registry/upstreams.json index c002403..1fe333d 100644 --- a/registry/upstreams.json +++ b/registry/upstreams.json @@ -6,6 +6,7 @@ {"id":"stack-codex","kind":"repository-package","canonical_source":"https://github.com/thecolormaroun/stack.git","pin":{"type":"sha256","value":"b773ec2e1f6353693184d7bda47bec9ca90663b5526c4c6690fec7e6cdf49595"},"license":"Stack-owned repository content","exports":["orchestrate-parallel-goals","stack-gemini-review","stack-ideate","stack-lfg","stack-mega","stack-review","stack-ship","stack-sync"],"install":"repository-bundle","bundle_path":"packages/stack-codex/content","adapters":["stack.explore","stack.build","stack.orchestrate","stack.review","stack.ship","stack.maintain","stack.run"],"compatibility":["tests/test_command_registry.py","tests/test_upstream_packages.py"],"last_known_good":{"pin":"b773ec2e1f6353693184d7bda47bec9ca90663b5526c4c6690fec7e6cdf49595","metadata_digest":"b773ec2e1f6353693184d7bda47bec9ca90663b5526c4c6690fec7e6cdf49595"}}, {"id":"matt","kind":"imported-collection","canonical_source":"https://github.com/mattpocock/skills.git","pin":{"type":"git-commit","value":"391a2701dd948f94f56a39f7533f8eea9a859c87"},"license":"MIT","license_sha256":"0e7ac423bf2c6e223b7c5b156f8cf72da49d748e56a1641402c31f22ad07dbb5","exports":["matt-code-review","matt-implement","matt-tdd"],"install":"pinned-import","adapters":["stack.build","stack.review"],"compatibility":["tests/test_upstream_packages.py"],"last_known_good":{"pin":"391a2701dd948f94f56a39f7533f8eea9a859c87","metadata_digest":"314c8e07b7e3989b4844e9d0a6f760001bd4955e09b1fc0f6d27f04cf5f6dd8d"}}, {"id":"david","kind":"imported-collection","canonical_source":"https://github.com/davidondrej/skills.git","pin":{"type":"git-commit","value":"5c99080334072075eb9e0a17837f7d24e4f3e6ae"},"license":"MIT","license_sha256":"1bd321a3b9cfa8d4af2105e20edd69d830df0b28e83a1b0255558f888e493981","exports":["david-handoff","david-goal-loop","david-read-all-adrs"],"install":"pinned-import","adapters":["stack.orchestrate","stack.learn"],"compatibility":["tests/test_upstream_packages.py"],"last_known_good":{"pin":"5c99080334072075eb9e0a17837f7d24e4f3e6ae","metadata_digest":"7c680c10b3be8907f0e0b214d3913bccbae17cbb839d7d565cf37f8cedc218b4"}}, - {"id":"emil","kind":"imported-collection","canonical_source":"https://github.com/emilkowalski/skills.git","pin":{"type":"git-commit","value":"c8a79627b59d72d764d6ab6f2c87c09a48169833"},"license":"MIT","license_sha256":"4ff5bdb7887ec1435c9cab0e8d1a7caee704d894d65c2a008ccc68b1cc2f260b","exports":["emil-animate","emil-animate-expo","emil-animation-performance","emil-animation-vocabulary","emil-apple-design","emil-ask-sonner","emil-break-ui","emil-choreograph","emil-design-eng","emil-find-animation-opportunities","emil-improve-animations","emil-mobile-native","emil-pick-ui-library","emil-prototype","emil-remove-animations","emil-write-swift","review-animations"],"install":"pinned-import","adapters":["stack.design"],"compatibility":["tests/test_upstream_packages.py"],"last_known_good":{"pin":"c8a79627b59d72d764d6ab6f2c87c09a48169833","metadata_digest":"914284e55376793590c835fc17b79e7dba8f0325539d5180d750fbebf8292966"}} + {"id":"emil","kind":"imported-collection","canonical_source":"https://github.com/emilkowalski/skills.git","pin":{"type":"git-commit","value":"c8a79627b59d72d764d6ab6f2c87c09a48169833"},"license":"MIT","license_sha256":"4ff5bdb7887ec1435c9cab0e8d1a7caee704d894d65c2a008ccc68b1cc2f260b","exports":["emil-animate","emil-animate-expo","emil-animation-performance","emil-animation-vocabulary","emil-apple-design","emil-ask-sonner","emil-break-ui","emil-choreograph","emil-design-eng","emil-find-animation-opportunities","emil-improve-animations","emil-mobile-native","emil-pick-ui-library","emil-prototype","emil-remove-animations","emil-write-swift","review-animations"],"install":"pinned-import","adapters":["stack.design"],"compatibility":["tests/test_upstream_packages.py"],"last_known_good":{"pin":"c8a79627b59d72d764d6ab6f2c87c09a48169833","metadata_digest":"914284e55376793590c835fc17b79e7dba8f0325539d5180d750fbebf8292966"}}, + {"id":"stewdio","kind":"imported-collection","canonical_source":"https://github.com/StewdioAI/blank-page.git","pin":{"type":"git-commit","value":"cd42b37fa7cd0a5550e51f45cc8f82f63377b98c"},"license":"MIT","license_sha256":"4533bc64e6e26958fd9bf4f9a56b422f9ab31b7dbcfac7bc23a8bd0d5cbdfde9","exports":["blank-page"],"install":"pinned-import","adapters":["stack.design"],"compatibility":["tests/test_upstream_packages.py"],"last_known_good":{"pin":"cd42b37fa7cd0a5550e51f45cc8f82f63377b98c","metadata_digest":"faeea6b4be818bbe31cc77d5e64dbaf45f882e201bc59ce23344da4a3dcae368"}} ] } diff --git a/scripts/apply-skill-layout.py b/scripts/apply-skill-layout.py index 26d2f63..4824ea8 100644 --- a/scripts/apply-skill-layout.py +++ b/scripts/apply-skill-layout.py @@ -19,7 +19,7 @@ ROOT = Path(__file__).resolve().parents[1] MIGRATION_PATH = ROOT / "registry/migrations/2026-07-23-skill-layout.json" -IMPORT_PROVIDERS = {"matt", "david", "impeccable", "studio", "ui", "emil", "taste-skill-suite"} +IMPORT_PROVIDERS = {"matt", "david", "impeccable", "studio", "ui", "emil", "stewdio", "taste-skill-suite"} class LayoutError(ValueError): @@ -70,7 +70,7 @@ def destination_for(manifest: dict[str, Any], source: str) -> str: if provider == "taste-skill-suite": provider_dir = "taste-skill-suite" # Preserve the collection's inside layout, but remove its old root. - old_root = {"matt": "matt", "david": "david", "impeccable": "impeccable", "studio": "studio", "ui": "ui-skills", "emil": "emil-design-eng", "taste-skill-suite": "taste-skill-suite"}[provider] + old_root = {"matt": "matt", "david": "david", "impeccable": "impeccable", "studio": "studio", "ui": "ui-skills", "emil": "emil-design-eng", "stewdio": "stewdio", "taste-skill-suite": "taste-skill-suite"}[provider] relative = Path(*parts[2:]) if len(parts) > 2 and parts[1] == old_root else Path(parts[-1]) return (Path("skills/imported") / provider_dir / relative / "SKILL.md").as_posix() # Stack-owned collections remain collections, including CDO and CPO. diff --git a/scripts/classify-capabilities.py b/scripts/classify-capabilities.py index 68b21e3..7f8cafd 100644 --- a/scripts/classify-capabilities.py +++ b/scripts/classify-capabilities.py @@ -41,11 +41,12 @@ "ideate": "stack.explore", } PRIMARY_CAPABILITIES = {"core-stack", "core-run", "cpo"} -# Emil Kowalski collection imports; the rest of that collection falls through to engineering. -EMIL_DESIGN = { +# Pinned design imports (Emil Kowalski, Stewdio); the rest of Emil's collection falls through to engineering. +PINNED_DESIGN_IMPORTS = { "emil-animate", "emil-animate-expo", "emil-animation-vocabulary", "emil-apple-design", "emil-choreograph", "emil-find-animation-opportunities", "emil-improve-animations", "emil-mobile-native", "emil-prototype", "emil-remove-animations", + "blank-page", } PURPOSE_OVERRIDES = { "agent-operating-stack": "Deprecated compatibility alias for the canonical Stack root router.", @@ -64,7 +65,7 @@ def canonical_json(value: Any) -> str: def provider_for(path: str) -> tuple[str, str]: - for provider in ("matt", "david", "impeccable", "studio", "ui", "emil", "taste-skill-suite", "other"): + for provider in ("matt", "david", "impeccable", "studio", "ui", "emil", "stewdio", "taste-skill-suite", "other"): if path.startswith(f"skills/imported/{provider}/"): return provider, "imported-skills" for prefix, provider in (("skills/matt-", "matt"), ("skills/david-", "david"), ("skills/impeccable/", "impeccable"), ("skills/studio/", "studio"), ("skills/ui-skills/", "ui"), ("skills/emil-", "emil"), ("skills/taste-skill-suite/", "impeccable")): @@ -85,7 +86,7 @@ def family_for(name: str, path: str) -> str: return "product" if path.startswith("skills/studio/research/") or name in {"field-theory-bookmark-synthesis", "fieldbook-source-split", "david-deep-research", "david-research-prompt", "david-youtube-transcript", "matt-research", "muller-brockmann-grid-systems", "userinterface-wiki"}: return "knowledge" - if path.startswith(("skills/studio/design/", "skills/impeccable/", "skills/ui-skills/", "skills/cdo/")) or name in {"cdo", "emil-design-eng", "illo", "better-icons", "review-animations", "ui-design-brain", "make-interfaces-feel-better", "design-intelligence", "rams", "deslop", "taste-skill-suite-soft-skill", "taste-skill-suite-redesign-skill", "cdo-taste-skill"} or name in EMIL_DESIGN: + if path.startswith(("skills/studio/design/", "skills/impeccable/", "skills/ui-skills/", "skills/cdo/")) or name in {"cdo", "emil-design-eng", "illo", "better-icons", "review-animations", "ui-design-brain", "make-interfaces-feel-better", "design-intelligence", "rams", "deslop", "taste-skill-suite-soft-skill", "taste-skill-suite-redesign-skill", "cdo-taste-skill"} or name in PINNED_DESIGN_IMPORTS: return "design" if name in {"tdd", "matt-tdd", "matt-implement", "matt-prototype", "matt-diagnosing-bugs", "matt-codebase-design", "matt-domain-modeling", "matt-improve-codebase-architecture", "matt-ask-matt", "react-doctor", "simplify", "knip", "fix-sentry-issues", "gemini-review"}: return "engineering" diff --git a/scripts/import-pinned-skills.py b/scripts/import-pinned-skills.py index 2706fa0..2b742e3 100644 --- a/scripts/import-pinned-skills.py +++ b/scripts/import-pinned-skills.py @@ -91,13 +91,22 @@ def record_collection_source(sources: dict[str, Any], provider: dict[str, Any], "target_paths": [], "required_exports": [], } - last = max(index for index, item in enumerate(sources["sources"]) if item.get("provider_id") == provider_id) + # Sit next to the provider's other rows, or after the last catalog provider for a new one. + own = [index for index, item in enumerate(sources["sources"]) if item.get("provider_id") == provider_id] + catalog = [index for index, item in enumerate(sources["sources"]) if item["disposition"] == "catalog-managed-provider"] + last = max(own or catalog) sources["sources"].insert(last + 1, row) policy_path = ROOT / "config" / "stack-maintenance.json" policy = policy_path.read_text(encoding="utf-8") ids = json.loads(policy)["legacy_target_ids"] anchor = next(f' "{item["id"]}",\n' for item in reversed(sources["sources"][: last + 1]) if item["id"] in ids) - policy_path.write_text(policy.replace(anchor, anchor + f' "{row_id}",\n', 1), encoding="utf-8") + policy = policy.replace(anchor, anchor + f' "{row_id}",\n', 1) + # The maintenance lane may only propose changes under allowlisted roots. + root_entry = f' "skills/imported/{provider_id}/",\n' + if root_entry not in policy: + last_root = [line for line in policy.splitlines(keepends=True) if line.startswith(' "skills/imported/')][-1] + policy = policy.replace(last_root, last_root + root_entry, 1) + policy_path.write_text(policy, encoding="utf-8") row["target_paths"] = sorted(set(row["target_paths"]) | {f"skills/imported/{provider_id}/{name}" for name in added}) row["required_exports"] = sorted(set(row["required_exports"]) | set(added)) @@ -123,7 +132,10 @@ def frontmatter_description(skill: Path) -> str: end = lines.index("---", 1) for line in lines[1:end]: if line.startswith("description:"): - return line.split(":", 1)[1].strip().strip("'\"") + value = line.split(":", 1)[1].strip() + if value.startswith('"') and value.endswith('"'): + return json.loads(value) # double-quoted YAML scalar: unescape \" + return value.strip("'") raise SystemExit(f"{skill}: missing description") @@ -224,7 +236,7 @@ def main(argv: list[str] | None = None) -> int: parser.add_argument("--list-unmapped", action="store_true") parser.add_argument("--all-unmapped", action="store_true") parser.add_argument("--skill", action="append", default=[], help="upstream skill name to add (repeatable)") - parser.add_argument("--family", action="append", default=[], help="UPSTREAM=family for a new skill (default: design); also add it to classify-capabilities.py family_for") + parser.add_argument("--family", action="append", default=[], help="UPSTREAM=family for a new skill (default: design); also add it to classify-capabilities.py family_for (PINNED_DESIGN_IMPORTS for design)") parser.add_argument("--canonical-source", help="update the provider's canonical source (e.g. after an upstream rename)") args = parser.parse_args(argv) diff --git a/skills/imported/stewdio/blank-page/SKILL.md b/skills/imported/stewdio/blank-page/SKILL.md new file mode 100644 index 0000000..b128cca --- /dev/null +++ b/skills/imported/stewdio/blank-page/SKILL.md @@ -0,0 +1,236 @@ +--- +name: blank-page +description: "Turn a one-line motion / animation / design brief into the full prompt: a committed look grounded in five reference images, three motion references, numbered beats with a turn, and the refs and assets attached. Also tightens edit notes. Use for \"/blank-page\", \"expand this prompt\", \"make this prompt more specific\", \"what is missing from this prompt\", \"help me write the prompt for X\", or whenever a one-line animation / composition / design brief is about to be handed to an agent." +--- + +## Stack Import + +- Invoke this curated import as `$blank-page`. +- Upstream name: `blank-page`. +- Upstream author: Blake Shao (Stewdio). +- Exact upstream commit: `cd42b37fa7cd0a5550e51f45cc8f82f63377b98c`. +- Source metadata and license notice: [references/source.json](references/source.json). +- New skills, deletions, and license changes remain review-gated. + +# Blank page + +Turn a short draft into the brief its author would have written. The drafts are usually +Stewdio composition work (motion, 3D, shaders, footage); the method applies to any +generative brief. + +**A good brief is references plus beats.** The idea lives in the thing pointed at +(`recreate this `, `in the texture of embroidery `) and the beats say what +turns into what: a committed look, a copied move, a real thing, and a turn. Not more +words, not more numbers. The voice is lowercase, imperative, numbered, no filler. A new +brief stays under ~150 words counted above `refs:`, an edit note under ~50; over the +cap, drop the optional lines (realism, params, a frame line restating a default) before +tightening, never a beat or the turn. + +Files in `references/`: + +- `finding-references.md`: roles, the fence, are.na seeds and loop, Pinterest, + Sketchfab, vetting. Read before step 2. +- `vocabulary.md`: the author's own words, per slot. Borrow while writing. +- `examples.md`: before / after pairs from real sessions. Read when unsure of the shape. +- `patterns.md`: corpus evidence and past failures behind the rules. Optional. + +## Procedure + +1. **Classify the draft.** + + | mode | signal | output shape | + |---|---|---| + | brief | "create", "recreate", a new comp or scene | aesthetic line + numbered beats + frame line + refs + assets | + | batch | "create N comps", "variations", "fill the gaps" | brief + per-item one-liners + dedupe rule + shared constraints | + | delta | "make X more/less Y", "get rid of", "fix", "move to" | target + change + magnitude + direction + keep-clause | + | image feedback | a screenshot / contact sheet is attached | one line per observation, each naming its frame or time | + | sequence | "at Ns", "after the X exits", beats across time | brief with a time anchor on every beat, duration cap | + | housekeeping | rename, push, export, "check the render" | leave as is; add the exact format or target | + + Brief, batch and sequence go through steps 2-8. Delta and image feedback skip to + step 6, searching only when the change brings in a new look or move. + +2. **Ground the look: five images, before any beat.** One aesthetic, sheeted, and + five stills from it that each do a job: the overall look, palette, material or + surface, composition, a detail or motif. Never blend two aesthetics; if a second + keeps winning tiles, switch to it wholesale. Its name goes in the prompt's first + line. + - **No fence** (the draft says nothing about the look): browse his umbrellas and + CARI's named aesthetics and pick for remarkable, not for matching the draft's + words. + - **A fence** (the draft names a style, a brand or a medium, or attaches a + reference): the word is the are.na query and the pick is the best instance + inside it, never a different aesthetic and never a screenshot of it. It fences + palette, material, type and components, not layout, scale, camera or the move. + The first line names a child of the user's word (`in stripe-gradient dark`). + How to decode and query it, and what to do when the queries come back as junk: + "The fence" in `finding-references.md`. + +3. **Ground the motion: three moving references.** gif / mp4 from the motion channels, + each a move worth copying ("would he put this in mo-graph?"), covering three jobs: + the main mechanic, the turn, the exit or camera. If no exit or camera move passes + after three channels, m3 takes another beat and the camera is written in words. + **The fence never applies to motion.** Then, as the beats need them: a copy + reference or asset for anything recognisable (a real UI, product, artwork, a + Sketchfab model) and a ui reference for interfaces. A user attachment fills its + slot. Look at every candidate before it gets a role. + +4. **Decide each reference's use, then write the beats.** For all eight: which beat + it feeds and exactly what is taken (`a3's wet-stone texture is the canvas surface`, + `m1 0.0-1.6s is beat 1 at 1.5x slower, subject swapped for cards`). A reference + with no beat is cut. The motion refs give the beats their order and timing; each + image sits on the beat where its quality first shows. Include **the turn**: a beat + where something is revealed, changes medium, zooms out to a larger whole, or + becomes something else (`the painting unravels into a single thread which becomes + a running silhouette`). Enter, animate, hold is not finished. When the draft + already holds a transformation (`snaps into`, `comes back as`), that verb is the + turn: make it the biggest beat and add no second metaphor. A ≤5 s clip carries one + idea (extra ideas go into the material and the camera, not the plot) and the action + fills it: end hold under 1 s; a turn over by 1.6 s means compressed beats or a + missing second half. + +5. **Add ideas.** On a bare draft, expected: a prop that makes the subject specific, a + real asset, a camera move tied to a reveal, a second beat that answers the first. + Write them as beats; mark the one or two real forks `[? ...]`. + +6. **Fill the slots** (checklist below). Inferable from the file, the previous comp, + an attachment or the conversation: silently. Missing and creative: a + `[? best default]` placeholder in the prompt. Missing and routine (duration, + aspect, file): default it inline, no marker; no file named means + `in stewdio, new file ,`. + +7. **Rewrite in the house shape** (templates below), keeping the author's wording + where it exists. + +8. **Output** three things and nothing else: the prompt in a fenced block; a + "fill-ins" list (max three creative forks, each with the choice made and the one + alternative worth considering; never duration, loop or aspect); one line pointing + at `.context/refs//` with the contact sheets so the user can veto a pick. + `` is a two- or three-word kebab slug of the subject (`coffee-menu`). If a + real thing is needed and absent (the user's own app, product, logo), say so in one + line above the prompt and name the stand-in used. No technique, no advice. + +## Slot checklist + +Opener slots first; they decide the result. Edit-loop slots after. + +| slot | ask | house form | +|---|---|---| +| where | tool, file, comp; for sequences the time or beat it attaches to | `in stewdio, , , at 3.5s:` / `after the sticker exits:` | +| look | one aesthetic, named, from a1; a child of the user's word when there is one | `in frutiger aero style` / `everything in riso` | +| medium / technique | photo or footage, 3D rebuild, vector, shader, real model | `using threejs or 3d framework` / `real 3d texture and train models` | +| move | the mechanic from the motion ref, subject swapped | `recreate this animation, but make it nyc subway` | +| subject | the real thing, by name, with its source | `the famous ukiyo-e painting ` | +| beats | numbered; each = subject + action + what it reveals or becomes | `2. then at around 2s, a big wave splats across the screen, turning the entire screen into a new texture` | +| turn | the reveal / morph / zoom-out / medium switch | `the camera zooms out to reveal that ...` | +| realism | fidelity demand when it matters | `it should be very realistic` / `loyal to the og` | +| camera | move + easing + what it lands on | `camera zooms fast into the pupil, steep quadratic ease-in` / `camera stays still` | +| pace | the feel in his words, seconds only for anchors | `very snappy, ease-in-out` / `one continuous motion from the start` | +| frame | bg, aspect, duration, loop, only where it differs from the defaults | `white bg, 1:1, ~5s loop` | +| params | values to expose when the comp will be tuned | `expose params for plumpness, sheen, glow` | +| keep | edits: what must not change | `keep the old entrance speed` / `keep the rest the same` | +| magnitude + direction | edits: multiplier, phase, axis and sense | `2x faster at top speed` / `30 degree clockwise` | +| scope | edits: which comps the change touches | `only for 23` / `unrelated: also ...` | + +**Standing defaults**, never written out: white bg (black for the math-graph family); +no fade, drop shadow, rounded corners, annotation text, UI chrome or guiding lines; 1:1 +for social posts, 16:9 for the graph and carousel families; ~5 s for a loop, 3-4 s for +an inserted beat, under 15-20 s for a sequence; real assets for recognisable objects, +stylised on top. The look outranks them: an aesthetic with its own ground (paper +stock, a counter, dark-mode navy) replaces the white bg on the frame line, and light +that belongs to the look (raking light across paper) is not a drop shadow. + +## Templates + +**Brief** + +``` +in stewdio, , [,] [at s / after ,] create the following, in [, using ]: + +1. +2.
[at ~s] +3. +4. + +; ; +; the whole thing ~s +[expose params for ] + +refs: +- a1 : look, (, channel ) +- a2 : palette, (, channel ) +- a3 : material, (, channel ) +- a4 : composition, (, channel ) +- a5 : detail, (, channel ) +- m1 : motion, beat : , subject swapped, not the look (, channel ) +- m2 : motion, beat [ (the turn)]: (, channel ) +- m3 : motion, beat [ (the turn)]: (, channel ) +- u1 : ui, layout + components, brand-neutral (, channel ) +- c1 : copy, , one-to-one () +assets: +- : use as-is for +- (, , ): , one-to-one, [? download] +``` + +Beats cite handles inline (`2. the sticker peels from the lower-left corner like m1, +on a3's wet stone`); every handle in `refs:` appears in a beat. Motion handles are +numbered in beat order, and the one feeding the turn is marked `(the turn)`. Add `orig ` after +the channel when the block has a source. User attachments go in the same list. + +**Batch** + +``` +in , create , , using as reference: + +1. +2. ... + +for all of them: ; keep each ~s +no overlap with ; a valid variation changes the mechanic, orientation, layout or treatment, not just direction or mirror +name them ": [ word description]" +``` + +**Delta**: one change per line, numbered when several, each naming its target; +"unrelated:" marks a different comp. + +``` +[for ,] make [] [at s] +[get rid of ] +keep +``` + +**Image feedback**: `: `, one +line each. + +## Rules + +- **Pick for quality, not for match.** The most striking move or look that could + carry the subject beats a keyword hit that shows the right object. +- **A film frame, not a web page.** One hero element takes ≥40% of the frame height at + the beat it matters; the smallest text is ≥24 px at 1080p; nothing is rebuilt at 1:1 + browser scale. Judge sheets at thumbnail size. +- **One reference, one job.** Moving media for motion, stills for look; a motion ref + implies a subject swap. A file used for two roles is listed twice, each scoped. +- **Assets are used, references are read.** Real footage, a real GLB, the real UI, the + real painting, stylised on top; say the fidelity up front and never re-interpret an + uploaded asset. Procedural only for primitives, orbs, blobs, extrusions, noise fields + and things that must grow or morph. +- **Treat each thing as a contraption.** Animate its special mechanism (a lid closes, + an envelope seals, a checkbox ticks), not a default draw-in. Transformations are + in-process morphs, not a teardown and rebuild. +- **Describe the mechanism, not the adjective.** "editorial page-drag" was built as a + slide-in; "the current image is peeled from a corner to reveal the new one already + underneath" was built right the first time. +- **Numbers where he uses them.** Seconds for anchors and length, multipliers and + degrees in edits, a hex only when the colour is the point (klein blue #002FA7). No + ms staggers or px offsets in an opener. +- **Edits name an axis, a sense and a phase.** "the other way" is not a direction; + "entrance 5x faster" needs "the fastest entrance we have had, constant speed after". +- **Keep the voice.** "get rid of", "tho", "~5s", "plz" are fine. No greetings, + rationale or headings inside the prompt. + +## Scripts + +`scripts/find_refs.py`: are.na channels / umbrellas / contact sheets, Pinterest pins, +Sketchfab search + download, file downloads, video contact sheets. Run it with no +arguments for the command list. diff --git a/skills/imported/stewdio/blank-page/agents/openai.yaml b/skills/imported/stewdio/blank-page/agents/openai.yaml new file mode 100644 index 0000000..23d3445 --- /dev/null +++ b/skills/imported/stewdio/blank-page/agents/openai.yaml @@ -0,0 +1,3 @@ +interface: + display_name: "Blank Page" + short_description: "Turn a one-line motion brief into a referenced, beat-by-beat prompt" diff --git a/skills/imported/stewdio/blank-page/capability.json b/skills/imported/stewdio/blank-page/capability.json new file mode 100644 index 0000000..e4ce727 --- /dev/null +++ b/skills/imported/stewdio/blank-page/capability.json @@ -0,0 +1,63 @@ +{ + "artifact_type": "skill", + "audit_status": "reviewed", + "canonical_name": "blank-page", + "commands": [ + "stack.design" + ], + "context": { + "inputs": [ + "request", + "workspace-context" + ], + "outputs": [ + "capability-result" + ] + }, + "disposition": { + "evidence_gap": null, + "next_review_trigger": "Reassess on source, export, or runtime-target change.", + "status": "keep" + }, + "domain": "design", + "family": "design", + "lifecycle": "active", + "overlaps": [], + "ownership": { + "package": "imported-skills", + "provider": "stewdio", + "source_path": "skills/imported/stewdio/blank-page/SKILL.md" + }, + "provenance": { + "license": "MIT", + "posture": "imported-upstream", + "source_identity": "upstream:stewdio/skills/blank-page" + }, + "purpose": "Turn a one-line motion / animation / design brief into the full prompt: a committed look grounded in five reference images, three motion references, numbered beats with a turn, and the refs and assets attached. Also tightens edit notes. Use for \"/blank-page\", \"expand this prompt\", \"make this prompt more specific\", \"what is missing from this prompt\", \"help me write the prompt for X\", or whenever a one-line animation / composition / design brief is about to be handed to an agent.", + "role": "leaf", + "runtimes": { + "publish_targets": [ + "claude", + "codex" + ], + "supported": [ + "claude", + "codex" + ] + }, + "schema_version": 1, + "source": { + "skill_path": "skills/imported/stewdio/blank-page/SKILL.md" + }, + "trust_class": "read-only", + "validation": { + "evidence": [ + "reviewed-estate-refactor", + "structural-classification", + "primary-runtime-parity" + ], + "status": "validated" + }, + "validation_class": "representative-route", + "visibility": "extended" +} diff --git a/skills/imported/stewdio/blank-page/references/examples.md b/skills/imported/stewdio/blank-page/references/examples.md new file mode 100644 index 0000000..04e635f --- /dev/null +++ b/skills/imported/stewdio/blank-page/references/examples.md @@ -0,0 +1,193 @@ +# Before / after + +Each "before" is a real prompt from the corpus with the corrections it needed. The +"after" is what the expansion should have produced from the first draft plus the +conversation. One example per lesson; the voice stays the author's. + +## 1. Medium unstated (four rounds) + +Before (2026-10-21): `in stewdio, file-a, create a realistic eye blinking in front of a klein blue background, everything is in resolgraph texture` + +Follow-ups: `make the eye an illustrator vector animation` / `actually revert back to the real eye` / `around the eye, add china porcelain vase's organic yet geometric patterns in white ` / `give the pattern a boil effect and have it grow out organically in the beginning` / `have the camera start zoomed out by 1x then a steep quadratic ease-out zoom in that is 2s long`. + +After: + +``` +in stewdio, file-a, create the following, everything in riso (3-ink halftone, grain, slight misregistration): + +1. a realistic eye (photo/footage based, not vector) centered on a klein blue #002FA7 field, blinking naturally [? 2 blinks over the comp] +2. around the eye, white porcelain-vase patterns ; the ring around the iris turns clockwise, the field outside it counter-clockwise; the whole pattern boils slightly and grows out bottom-up from 0s +3. camera starts 1x, steep quadratic ease-out zoom in over the first 2s + +1:1, ~5s [?], no fade, no border +expose params for zoom end, pattern growth speed, blink timing +``` + +## 2. Magnitude without a phase or reference point (four rounds) + +Before (2026-10-08): `make the orb's entrance velocity 5x faster,` + +Follow-ups: `the orb is slower despite me specifying it to be faster` / `have the ball keep a constant speed when rolling and add more bounce, lastly 1s, zoom in onto the orb and track it` / `keep the old entrance speed, i am saying it should have a fast constant speed afterwards, also, the zoom should happen at 1.2s exactly` / `no like the fastest entrance speed we have had`. + +After: + +``` +1. entrance: use the fastest entrance speed we have had so far (the v3 one), keep it +2. after landing: constant roll speed, no decel, 1.5x the current; more bounce height +3. at 1.2s exactly: zoom in onto the orb and track it, camera moves with the orb but does not turn +keep the splash and the structure as they are +``` + +## 3. Mechanism described by adjective + +Before (2026-10-05): `make 23 more editorial, like a new image with white border with either a side or a corner being draged to reveal the new stuff` + +Follow-ups: `still incorrect, the drag is not a slide in, rather it is dragging from a corner of the frame to reveal the new thing` / `make the border a lot thinner and make them come in from random corner and sides`. + +After: + +``` +for 23: the new image is already underneath, full frame; the current image is peeled away from a random corner or side (varies per transition) like a page being dragged off, revealing the new one beneath. not a slide-in. thin white border on each image, no guiding lines, no scale on the image, no fade +``` + +## 4. Adding to an existing comp without the style lock + +Before (2026-10-21): `in riso-tunnel in file-a, add a series of square decoration frames in the style of the pattern in riso-blink, have them twist and turn within the tunnel` + +Follow-ups: `it should be purely white, and its better to reference the outer portion of the first comp, also, have the frames form a proper tunnel it self, the tunnel only twists in rotation` / `they still need to be individual frames rather than a literal tunnel ... it doesn't have to literally contain a square`. + +After: + +``` +in riso-tunnel in file-a, add a series of individual decorative frames in the white porcelain pattern from the outer field of riso-blink (not the ring): +- purely white, still riso +- each frame is its own flat shape, roughly square but it need not contain a literal square +- the frames line up along the tunnel axis so together they read as a tunnel; they only rotate about that axis as the camera passes, no other motion +keep the existing colour tunnel and camera as they are +``` + +## 5. Two animated quantities (good as written; expansion only adds numbers) + +Before (2026-10-13): `ok the entrance animation should work as the following, two params are animated: size and fullness / they should have roughly similar easing but fullness finish later` + +After: + +``` +entrance animates two params: size and fullness. both ease-out, similar curve; size lands at ~0.3s, fullness keeps going and lands at ~0.8s [?]. the balloon pops in at ~70% fullness and finishes inflating after. jiggle starts right at the pop-in, only as a result of the impact, no delay +keep my plumpness and texture param edits +``` + +## 6. Batch without a dedupe rule + +Before (2026-10-05): `in stewdio's carousel project, create the following 25 variations based on the existing comps / keep the new comps tight, around 5-7s / for all of them use white bg and 3 place holder images @a.jpg @b.jpg @c.jpg` + +Follow-ups: `the variations doesn't have to be 1-to-1, just create new ideas based on the existing ones` / `no need to do backward directions, they are not a valid variation` / `mirror are not valid either` / `rename everything in the following format (Carousel: [5 word max description])`. + +After: + +``` +in stewdio's carousel project, create 25 new carousel comps as variations of the existing ones: +- not 1-to-1: a valid variation changes the mechanic, orientation, layout or treatment; reversing direction or mirroring is not a variation +- stay within the current sensibilities (flat, white bg, no fade, no drop shadow, no rounded corners, no UI chrome) +- each ~5-7s, white bg, the same 3 placeholder images @a.jpg @b.jpg @c.jpg +- expose expressive params for each +- name them "Carousel: [5 word max description]" +``` + +## 7. Image feedback (stays short, gains a pointer) + +Before: a pasted contact sheet + `make the splash's top brim a lot bigger and the background color in this and background texture in this ` + +After: + +``` +frame 3-4 (the splash peak): make the top brim ~2x bigger and more irregular +background: colour from (palette only), texture from (texture only) +keep the orb and camera as they are +``` + +## 8. Sequence beat mid-timeline + +Before (2026-10-26): `in stewdio file-b, create the following on main comp / at 3.5s mark, have many small jack-o-latern version of clawd crawl from the bottom of the screen up all over the skeleton covering it, / then, they crawl down and back to exit, leaving one bone dropping on the ground` + +Follow-ups: `make clawd still look like clawd except for the pumpkin texture` / `still make the eyes glow`. + +After: + +``` +in stewdio file-b, main comp, at 3.5s: +1. many small clawds (the clawd silhouette as-is , pumpkin texture + glowing eyes, same 16bit quantisation as the scene) crawl in from the bottom edge and up over the skeleton until it is covered [? ~1.5s] +2. they crawl back down and exit the bottom edge, leaving one bone that drops to the ground and stays +keep the sigil, skeleton dance and flames as they are; the beat ends by [? 7s] so the inventory scene can start +``` + +## 9. Bare brief: the first skill version versus the opener shape + +Before (2026-11-02 test set): `in stewdio file-d, make a video of our issue tracker app where the tasks show up nicely` + +What the first skill version produced: a dark linear-style list, "rows stagger in top-down 60ms apart, each rises 8px with opacity 0→1 over 400ms", a 20° tilt, "no fade, no drop shadow", "check sub-pixel smooth at pixelRatio 0.4–2", fill-ins about duration and loop. The unassisted agent built the same thing. Nothing in it was a decision. + +After (references chosen first; the motion ref is a stop-motion paper gif from mo-graph, the visual ref a tile from the Printed Matter channel): + +``` +the brief says "our issue tracker app" and nothing is attached: attach a screenshot of the real issues list, or it gets rebuilt from u1 below. + +in stewdio, file-d, create the following, in the look of printed matter (riso-ish ink on uncoated stock, two spot colours, visible grain), the ui rebuilt as paper: + +1. an empty issues list on a sheet of paper, camera top-down. each task slides in from the right edge as its own paper slip and lands with a stop-motion snap, one after another like m1, the stack getting thicker as they land +2. at ~2.5s a hand (real footage cutout, c1) reaches in and ticks the top three with a marker; each tick is one stroke, the slip turns from the dark ink to the accent ink as it is done +3. the camera pulls up and out to reveal the sheet is one of dozens pinned on a wall, every sheet filling with slips at its own pace +4. hold on the wall, slips still landing + +it should look physically printed, not a flat vector of paper; very snappy, stop-motion timing throughout, no eases +white paper on a [? cork / grey] wall; ~7s +expose params for slip count, tick timing, the two ink colours + +refs: +- a1 .context/refs/tracker/a1.jpg: look, the whole piece's finish: riso ink on uncoated stock, sets beat 1's frame (are.na/block/, channel printed-matter-) +- a2 .context/refs/tracker/a2.jpg: palette, the two spot inks (dark + accent), used everywhere (same channel) +- a3 .context/refs/tracker/a3.jpg: material, the slip paper's grain and torn edge, beats 1-2 (same channel) +- a4 .context/refs/tracker/a4.jpg: composition, the pinned wall grid of beat 3 (same channel) +- a5 .context/refs/tracker/a5.jpg: detail, the marker tick stroke of beat 2 (same channel) +- m1 .context/refs/tracker/m1.gif: motion, beat 1: the slide-in and snap landing, the stack thickening, 0.0-2.0s at 1.2x slower, subject swapped (are.na/block/, channel mo-graph-1uxjlkjqqhc) +- m2 .context/refs/tracker/m2.mp4: motion, beat 2: one-stroke tick with the colour flip on completion (are.na/block/, channel motion-inspo-tfrw-gidqfw) +- m3 .context/refs/tracker/m3.gif: motion, beat 3 (the turn): the pull-up-and-out to a wall of many, its ease-out and hold (are.na/block/, channel design-moving-l9-xt3sxtne) +- u1 [? screenshot of the real issues list]: ui, layout and the row anatomy one-to-one +- c1 .context/refs/tracker/c1.mp4: copy, the hand and marker, footage cutout (pexels.com/) +assets: none beyond c1 +``` + +Fill-ins: printed matter was chosen over the safe dark-UI look because it makes "tasks show up" physical; runner-up was the Baroque User Interface channel. The pull-out wall reveal is the turn; drop it if the piece must stay a single screen. The hand is footage, not drawn, so it reads as real. + +## 10. Missing motion + art direction + asset (found, vetted, structured) + +Before (2026-10-26): `in the stewdio file-b, for the main comp, do the following at 7s: / have a inventory/equipment interface move in like stone blocks / the inventory interface is that for a macbook, the controller keep adding stickers onto the laptop, the stickers eventually overflow the inventory screen and the computer is completely covered in stickers / also, be sure to include this memey artifact as part of the overwhelming equiping / the whole sequence should be around 3-4s` + +Eight follow-ups, every one about how stickers land and how dense the cover gets (`the cursor adding the stickers way too quickly`, `don't make it the spiral, make it more randomized`, `upon adding a sticker can you give an impact ... slight screen shake, on the first few`, `cover the laptop's keyboards with more stickers too`). That is what a motion ref and an art-direction ref supply. + +Search (run 2026-11-02): are.na `sticker bomb` / `stickers stop motion`, Pinterest `laptop covered in stickers sticker bomb macbook` / `stickers slapping on animation stop motion gif`. Kept one photo of a real sticker-bombed MacBook. Rejected a printed laptop skin, a "sticker" gif that was vinyl records, a dead pin, an unrelated cartoon gif. No moving reference passed. The stone-block image is a still, so it is art direction, not motion. The laptop is a product with a lid that must close, so it is a Sketchfab asset, not procedural geometry. + +After: + +``` +in stewdio file-b, main comp, at 7s, ~3.5s total: + +1. an inventory/equipment interface slides in as stone blocks (a1), ~0.5s +2. the inventory is for a macbook: laptop open by default, then closes; a highlighted cursor adds stickers to the lid one at a time, each landing exactly under the cursor with a hit impact (slight screen shake on the first ~4) +3. the cursor accelerates until it is a blur with light trails; stickers land at random positions and rotations, overlapping like a2 (no spiral, no pattern), spilling past the laptop and the inventory frame until the whole screen is covered, lid, keyboard and all +4. the claude hold lid stopper (c1) lands among them, closely modelled + +stickers: ai startups, y combinator, a16z [? exact list] +same 16bit quantisation and palette as the rest of the comp +keep everything before 7s as is + +refs: +- a1 .context/attachments//image.png: art direction, stone-block material + chunky entrance only +- a2 .context/refs/stickerbomb/a2.jpg: art direction, density, random overlap and white die-cut borders only, not the brands or the pink laptop (pinterest.com/pin/749990144179145089) +- c1 makerworld.com/en/models/2924138: copy, the lid stopper object, closely +assets: +- sketchfab.com/3d-models/efab224280fd4c3993c808107f7c0b38 (Macbook Pro 13 2020, timblewee, CC-BY, 77k faces, rotating hinge animation): the laptop, one-to-one, lid hinge drives the open → close, quantised to 16bit on top [? download] +- [? startup logos as svg from each brand's own site] +``` + +Fill-ins: the sticker list; the logo assets and the model download; no motion ref passed vetting, so the slap is described in words. Drop a sticker-slap clip in if you have one. diff --git a/skills/imported/stewdio/blank-page/references/finding-references.md b/skills/imported/stewdio/blank-page/references/finding-references.md new file mode 100644 index 0000000..3671eb5 --- /dev/null +++ b/skills/imported/stewdio/blank-page/references/finding-references.md @@ -0,0 +1,312 @@ +# Finding references and assets + +The roles a reference may play, where to search, and how to vet. `scripts/find_refs.py` +does the fetching; run it with no arguments for the command list. Output is one JSON +object per line. + +## Roles + +Every reference gets exactly one role, a take (what it supplies) and a fidelity word. +A file good for two roles is listed twice with two scoped takes. + +| role | supplies | never supplies | media | default fidelity | house phrasing | +|---|---|---|---|---|---| +| **motion** | mechanic, beat order, timing, easing, camera move, transitions | subject, palette, texture | gif / mp4 / multi-state still | mechanic + timing closely, look not at all | `recreate this animation, but make it ` / `only the
and the ` | +| **art direction** | palette, texture, material, lighting, era, background | shape, layout, motion | still | the named quality only | `in the color way of ` / `background texture in this` | +| **copy** | the specific thing to rebuild: artwork, character, object, product, lettering | how it moves | still, model, footage | closely; one-to-one for a named artwork or product | `recreate , loyal to the og` | +| **ui** | layout, component vocabulary, density, type hierarchy, states; interaction timing if moving | brand, logo, real product copy | still; gif / mp4 for interaction | structure closely, brand not at all | ` layout + components, brand-neutral, no real company` | +| **detail** | one feature inside a larger frame | anything outside the scoped region | still | the scoped part only | ` as indicated here ` | +| **family** | the space a batch is drawn from | a copy of any single item | are.na channel, board | loosely across the set | `using as reference` | +| **technique** | how to build it | look or motion | repo, article | optional | `reference this if it is helpful` | +| **timing** | beat grid, cut points | anything visual | audio | the stated range | `match the timing to the beats of from 17.15s to 30s` | + +**Assets are not references.** Models, fonts, footage, logos, placeholder photos and +audio go under `assets:` with `use as-is` or `one-to-one`. + +Handles use the role letter: m motion, a art direction, u ui, c copy, d detail, +f family, t technique. + +## Order of work + +References come first, before any beat (SKILL.md steps 2-4): five images from one +aesthetic and three moving references, then, for all eight, the beat each feeds and +what is taken. Five tiles from one channel is normal; two channels of the same +aesthetic is fine; two aesthetics is not. For motion the test is "would he add this to +mo-graph?", not "does it show the right object?": a dull move on the right object +loses to a striking move on a different subject. Before falling back on a camera move +written in words, try `channels "camera move"`, `"zoom"`, `"transitions"`. + +### The fence: a named style or an attached reference + +Blake names niche aesthetics himself; other users name mainstream ones in plain words +(`clean and minimal, lots of white`, `like stripe's style`, `like claymation`). Both +past failures (overriding the word, screenshotting it; see `patterns.md`) treated the +fence as a place to copy from, not as a query. So: + +1. **Decode the word** in one line: what the user pictures when they say it. `minimal, + lots of white` = big type, one accent, generous margins; `claymation` = stop-motion + clay, fingerprints, boil, on twos; `like stripe, dark mode` = navy, blurple, fine + gradient lines, mono code. That line is the fence; it constrains palette, material, + type and component vocabulary. It does not constrain layout, scale, camera or the + mechanic. +2. **The word is the are.na query.** Still are.na, still curated, but the style or + company name is the constraint. Two kinds of query, both needed: + - **The name itself**, with `search "