feat(snowflake): Milo substrate flavor on top of feedback-improvements#166
feat(snowflake): Milo substrate flavor on top of feedback-improvements#166vhargrave wants to merge 8 commits into
Conversation
…s rework Re-applies the Milo flavor (originally PR adobe#162, off main) on top of David's worktree-fix-snowflake-feedback-improvements branch. David's branch reworked the same phase docs + installer for EDS; this re-homes the additive Milo deltas into his versions. No semantic conflict — his rework is pure-EDS and has zero Milo awareness; the artifact contract (section[class] + [data-slot] markers, /templates/<name>.html) is identical, so the Milo overlay block consumes his reworked phase output unchanged. - assets/substrate-milo/: minimal Milo substrate (overlay block only; leaves Milo's head.html/scripts.js/styles.css untouched). Additive — David has none. - scripts/install-substrate.mjs: --flavor / --milo / --eds + auto-detect (milolibs / setLibs). EDS path unchanged; defaults to eds. - phases/{0-prereq,1-capture,3-generate,4-wire}.md: re-applied "Milo flavor" sections at the matching anchors (3-generate step refs 3.1/3.3/3.4/3.8 still align with David's numbering). - install-substrate.test.mjs: +3 tests (milo auto-detect, --flavor=eds override, bad-flavor rejection). Full suite 9/9 green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Re-opening |
catalan-adobe
left a comment
There was a problem hiding this comment.
Review notes
1. VERSION mismatch (must-fix)
assets/substrate-milo/MANIFEST.json declares "substrateVersion": "1.0.0-milo.1" but assets/substrate-milo/VERSION contains 1.0.0-milo.2. These should agree — the installer reads VERSION to write substrateVersion into .snowflake/config.json, so the manifest's own field drifts from what gets deployed.
2. writeSlot duplication (suggestion)
The writeSlot logic in blocks/snowflake/snowflake.js is described as "ported verbatim from the EDS substrate's writeSlot" (assets/substrate/scripts/overlay-engine.js). If a bug is found in slot writing, both files need patching independently. Worth adding a cross-reference comment in each file pointing to the other, e.g.:
// Ported from assets/substrate/scripts/overlay-engine.js — keep in sync.and the reverse in the EDS file. Alternatively, extracting to a shared module if the two runtimes can reference a common path — but a comment is the pragmatic minimum.
Everything else looks clean — the additive design, auto-detection, phase doc gating, test coverage, and [data-overlay] scoping are all solid. Nice work.
…ent + writeSlot sync comments - MANIFEST.json substrateVersion 1.0.0-milo.1 → 1.0.0-milo.2 to match VERSION (the file the installer reads to write .snowflake/config.json substrateVersion) - cross-reference 'keep in sync' comments on both writeSlot impls (Milo blocks/snowflake/snowflake.js ↔ EDS scripts/overlay-engine.js) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks for the review @catalan-adobe — both addressed in 1. VERSION mismatch (must-fix) — Bumped 2. writeSlot duplication (suggestion) — Went with the pragmatic cross-reference rather than extracting a shared module (the two runtimes don't share a load path — Milo loads the block from
If |
… blocks) Adds a Milo block-level path so a Milo repo can produce editable DA block tables that render 1:1 with the live gnav/footer -- not just the page-level overlay. Milo runs the standard decorateBlocks pipeline and loads any block from the repo root with no allow-list (verified in milo/libs/utils/utils.js loadBlock/getBlockData), so bespoke forge-* blocks decorate natively while Milo keeps its runtime and renders chrome from page metadata. - phases/3-generate.md: "Milo flavor deltas" under the Block-level path -- no styles.css/head.html/scripts.js edits, no header/footer fragments, forge-<section> block names, rebuild decorators, self-contained per-block CSS, full-bleed wrapper overrides, chrome metadata block (no template key), per-section visual-diff 1:1 gate. - phases/4-wire.md: Milo block-level wire branch (copy blocks/forge-*, no fragments/templates/styles). - SKILL.md, 0-prereq.md, block-level-conversion.md: note Milo supports level=block and where the deltas live. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…he runtime (Milo block-level)
Converges snowflake's animation output onto the page-animator --pa-* contract so
generated forge-* block pages animate on load AND stay adjustable in the
page-animator panel/sidekick — one vocabulary for generate -> animate -> adjust.
- substrate-milo: vendor the scroll-animation runtime (blocks/animation/{js,css} +
tools/page-animator/controls.js) verbatim from milo@page-animator-poc (3fc472a1f),
with provenance headers. Milo auto-loads blocks/animation from repo root, so a
sibling <div class="animation forge-<name>"> drives a CSS scroll animation
(animation-timeline: view()) on the deployed page and stamps data-pa-* so the
panel can read + adjust it. MANIFEST.replace + VERSION bumped to 1.0.0-milo.3;
install-substrate.test asserts the runtime files land (scripts.js untouched).
- phases/3-generate.md: new step B.5b — emit animations as --pa-* `animation`
sidecar blocks (not bundled JS). Policy default|preserve|off (default = tasteful
staggered reveal; view() no-ops above-fold; cinematics stay bundled). 1:1 gate
unaffected (reveals settle to the real end-state).
- knowledge/animation-sidecars.md: the --pa-*/range-*/timing-* vocabulary + defaults
(mirrors controls.js), recipes, browser-floor note. Wired into the load list + SKILL.md.
Remove the vendored copy once the page-animator work lands in Milo main.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@vhargrave, are you looking at extending the scope of this plugin in this PR? I see Milo mentions leaking more and more beyond the Milo substrate. |
…OR.md Addresses review feedback that Milo-specific content was leaking beyond the Milo substrate into the skill's shared core. The substrate FILES were already isolated, but the Milo GENERATION GUIDANCE (chrome metadata, page-level and block-level deltas, --pa-* animation sidecars, wiring) had spread across the shared phase docs as conditional branches. - New assets/substrate-milo/FLAVOR.md holds all Milo deltas verbatim, anchored #capture / #generate-page / #generate-block / #wire. - Each phase (1-capture, 3-generate x2, 4-wire) now carries a single gated pointer to the matching FLAVOR.md section instead of inline Milo prose. - Moved knowledge/animation-sidecars.md -> assets/substrate-milo/ (it documents the vendored runtime; belongs with it). Repointed referrers. - SKILL.md, 0-prereq.md, block-level-conversion.md trimmed to pointers; fixed a stale "installs only blocks/snowflake" line (it also ships blocks/animation + tools/page-animator). Net: shared core back to substrate-neutral (-333/+43 lines); no behavior change (verbatim relocation behind the same "read FIRST if milo" gate the skill already uses). FLAVOR.md/animation-sidecars.md are not in MANIFEST, so not deployed. install-substrate tests 9/9. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ls, no inlined JS The source page's animation code is stripped when sections become forge-* block tables (the "snowflake nuke"). preserve mode now re-expresses that motion as adjustable --pa-* sidecar DATA the deployed Milo runtime runs, instead of leaving it as bundled JS (which earlier led agents to inline a Lenis shim into block JS): - enter/reveal -> --pa-opacity-from + --pa-translate-y (entry range) - scale/blur-in -> --pa-scale / --pa-blur - parallax/translate-on-scroll -> approximate as a --pa-translate-y reveal (Ryan's panel is an entry-based reveal model, not continuous parallax; approximate-and-adjustable is the correct substitute) - never inline Lenis/GSAP/scroll-listener JS into block code; smooth-scroll is free from Milo's foundation:c2 Lenis init - no source motion -> fall back to default reveal; skip true pin/scrub timelines Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@catalan-adobe no, it's grew a little too far. I've tried reducing the reach as much as I can just now, but yeah let me know. Worst case we might need to have our own separate snowflake skill for our milo flavours. |
|
Current state seems to be still fine, I could successfully test it locally. So if you are done with current state, I will approve and you can merge it. |
… elements Full-width buttons/inputs/cards with their own padding overflow the container without box-sizing (CTA bleeding past card edge). Milo has no global box-sizing reset reaching scoped block CSS, so the block-level generate guidance now mandates a per-block reset.
… never reinterpret as dynamic
Root cause of a 1:1 regression: block-level Generate dropped a visible
Stardust placeholder ("PLACEHOLDER · price / e.g. US$0/mo") because the
agent judged it a commerce-injected slot and rendered an em-dash. The
placeholder-preservation rule existed only for the overlay path (Phase 2
data-slot-skip), which has no meaning when decorate() rebuilds DOM from a
hand-designed content model. Add the rule to the block-level content-model
guidance (block-level-conversion.md + 3-generate.md B.5 + Milo FLAVOR.md
generate-block): a visible generator placeholder is static source content
to reproduce verbatim, not a dynamic slot to drop.
yes please then! |
What
Adds the Milo substrate flavor to snowflake, rebased onto this branch's feedback-improvements rework. Originally proposed against
mainas #162; this re-applies it on top of your reworked phases + installer so the two land together instead of conflicting.On a Milo repo, snowflake must not replace
head.html/scripts.js/styles.css— that rips out the Milo runtime that loads the liveglobal-navigation+ footer from page metadata. So the Milo flavor installs a minimal substrate: an overlayblocks/snowflakeblock (Milo loads it fromcodeRoot) and nothing else. Chrome stays owned by Milo; the bespoke body is drawn by the block from/templates/<name>.html.Why it composes cleanly with your rework
## Milo flavorsections gated on.snowflake/config.jsonsubstrateFlavor, so they don't touch the EDS path.overlay-engine.js(hooked into the boilerplatescripts.js) vs the Miloblocks/snowflakeblock. They consume the identical artifact contract (section[class]+[data-slot]markers,/templates/<name>.html), so the Milo block renders your reworked phase output 1:1 with no engine changes.Changes
assets/substrate-milo/— minimal Milo substrate (overlay block + ignore patches). Additive; nothing on this branch references it.scripts/install-substrate.mjs—--flavor=milo|eds/--milo/--eds, else auto-detect (milolibsin head.html, orsetLibs()in scripts.js). EDS path unchanged; defaults to eds.phases/{0-prereq,1-capture,3-generate,4-wire}.md—## Milo flavorsections at the matching anchors. 3-generate's step refs (3.1/3.3/3.4/3.8) align with your numbering.install-substrate.test.mjs— +3 tests (milo auto-detect,--flavor=edsoverride, bad-flavor rejection).Tests
node --test scripts/install-substrate.test.mjs→ 9/9 pass (your 6 + 3 new). Milo install verified to addblocks/snowflakeand leavescripts.jsbyte-identical.Context
Driving this from page-forge (a DA tool that runs snowflake to publish prototypes). It auto-detects Milo repos and deploys via this flavor — adopting your feedback-improvements gets the nicer 1:1 EDS blocks on the Milo path too. Happy to adjust naming/placement to fit how you'd prefer to fold it in.