snowflake: smoother startup, browser-intent round-trip gate, and substrate un-weave#161
Draft
catalan-adobe wants to merge 20 commits into
Draft
snowflake: smoother startup, browser-intent round-trip gate, and substrate un-weave#161catalan-adobe wants to merge 20 commits into
catalan-adobe wants to merge 20 commits into
Conversation
…on install Adds a `defaults` object to MANIFEST.json with all five repo-level config keys (projectsDir, daRoot, branchPrefix, trunkBranch, tagPrefix). The installer now merges these into .snowflake/config.json using a three-layer merge (defaults → existing config → substrateVersion/installedAt), so user-edited values survive upgrades and a fresh install always has all keys present. Bumps substrate to v1.0.6. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ase 1 Phase 0 now branches by dry-run outcome: clean installs proceed without a separate file-list confirmation (the init summary covers it); drift and custom-code-detected cases still surface details and pause for explicit input. Phase 1 auto-detects the target repo via `gh repo view` / `git remote` and reads daRoot from .snowflake/config.json instead of always asking the user. Slug and templateName derivation is shown in the init summary rather than triggering mid-phase follow-up questions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…eter display Source URL is now the only required input; repo, daRoot, level, slug, and template name are all resolved automatically. A parameter summary is always displayed before Phase 0 begins (no confirmation needed — the skill proceeds immediately after showing it). DA token status is surfaced early and non-blocking; phases 1-4 do not need it. Reading order is now just-in-time: only SKILL.md + methodology.md load at startup; the four heavy knowledge files are deferred to the phases that use them (Analyze, Generate, Round-trip). HOST-NOTES.md updated to accurately describe the defaults source-of-truth (now actually in MANIFEST.json), document the three-layer merge, and add `gh` (GitHub CLI) to the allowed-primitives list — it was already used in Phase 5 but missing from the list. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rowser instructions
The skill body no longer calls playwright-cli directly. Browser interactions
are now expressed as host-agnostic intents ("open this URL in a browser",
"evaluate this JavaScript", "take a screenshot") so the executing agent can
use whatever tool fits its environment — playwright-cli, cmux-browser, or
any other available primitive.
JavaScript payloads (what to evaluate and verify) are preserved unchanged;
only the tool invocation scaffolding is removed. HOST-NOTES.md updated to
map browser intents to tools per host and to list specific browser CLI calls
as a forbidden pattern in the skill body.
Also fixes the stale Quick start Phase 1 snippet that incorrectly showed
playwright-cli instead of curl.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 5 is now an explicit pass/fail gate rather than an advisory report. Before the run may continue to Phase 6, the converted page must pass six checks on both local and production preview: 1. Renders (not blank) — visible text, rendered height, section count 2. Overlay applied — main[data-overlay] and body.appear 3. Structure matches decisions.json 4. No console errors (font-CORS tolerated, must be recorded) 5. No network failures or broken images (about:error / naturalWidth 0) 6. 1:1 with the source via dom-equality.mjs (PASS, or only the known wrapper-element deltas) The previous consoleErrors check read window.__errors, which nothing ever populates — it always returned 0. Replaced with real capture: the browser tool's console/network logs, with an injectable in-page listener fallback for tools that can't surface them. The evaluate payload now also reports not-blank metrics and broken images. dom-equality (check 6) is tightened from "FAIL with small deltas — move on" to PASS-or-allowlisted-deltas-only. Results of all six checks are recorded in state.json under healthGate so the pass is auditable. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The installer's no-marker branch flagged every non-empty file that differed from the bundled substrate as "custom content" and refused without --force. But a vanilla aem-boilerplate clone always has non-empty stock files that differ from the substrate — that's exactly what the skill replaces — so the common case always tripped a redundant confirmation pause. The no-marker case now installs directly: it reports which pre-existing files it replaces (so a genuinely custom file is still surfaced) but does not block. Originals are backed up unconditionally and the init summary already disclosed the file count, so the install is reversible and pre-disclosed. The drift case (marker present but files diverged from the bundled version) still refuses without --force — there a prior snowflake substrate could carry intentional customization, so a human decision is warranted. Phase 0 docs collapse the former Clean/Custom-code cases into one no-pause Fresh-install case; SKILL.md Initialization note updated to match. Also folds a duplicate "After install" heading introduced in an earlier edit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…o-op Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s on overlay DOM loadSections(element) queries div.section descendants. The overlay template contains the original static page's <main> markup with plain design elements, not EDS wrapper div.section nodes, so the call finds zero matches and returns immediately. The old woven scripts.js guard was defensive but unnecessary; the new hook-based approach omits it intentionally. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tessl Skill Lint✅ ✅ All 1 tile(s) clean. Updated by |
Page-level overlay is the safer, more common path. Making it the default means /snowflake <url> proceeds directly to page-level conversion without a feasibility-gate question. level=auto is still available for users who want the analysis to decide. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Instead of hardcoding /marketing, the DA root now defaults to the current git branch name — the same branch the skill uses for code. This matches the common EDS convention where DA content lives under a path named after the branch. The config daRoot key still overrides when set; the value is always shown in the init summary for correction. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ck fires The installer stamped "daRoot": "" into config, which the resolution logic treated as "set" — so the branch-name fallback never triggered. Removing daRoot from defaults entirely means the key is absent in a fresh config, and the Phase 1 resolution correctly falls back to the current branch name. Users who explicitly set daRoot in their config are unaffected. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ibility The slot-identification rules in Phase 2 and methodology.md said "Visible text" which caused the agent to skip content inside hidden tab panels, collapsed accordions, and inactive carousel slides. CSS visibility is irrelevant during content extraction — the template's own JS/CSS handles show/hide at render time. All DOM content is now treated as authorable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Large pages with many sections or slottable elements risk silent content loss during page-level conversion (context pressure, repetitive-structure fatigue). Block-level processes one section at a time and is immune. Phase 2 now checks: >8 sections or >100 slottable elements. When the gate fires and level=page was the default (not explicitly requested), it auto-switches to block-level and proceeds. When level=page was explicitly passed, it warns but respects the user's choice. level=auto/block/check are unaffected. The outcome is recorded in decisions.json as complexityGate + sectionCount + slottableElementCount. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…per) When an <a> contains authorable text alongside decorative non-authorable children (inline SVGs, icon images), placing data-slot on the <a> causes writeSlot to destroy the decorative content at runtime. Adds: - Learnings entry documenting the pattern and the general rule - Phase 2 mixed-content detection: slots flagged with mixedContent=true in decisions.json when <a> contains SVG/decorative-img/icon children - Phase 3 span-wrapper rule: wrap only the authorable text in a <span data-slot>, leaving decorative siblings as template chrome - Self-check #7: DOM-based post-generate validation that no data-slot element contains SVG or decorative image descendants Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Block-level conversion generates N independent blocks — own JS, CSS, content model, no shared state. Phase 3 (B.5) now explicitly states blocks can be generated in parallel if the host supports concurrent work dispatch. The hint is intent-level (no specific tool prescribed), matching the browser-intent pattern. HOST-NOTES updated: replaced the "out of scope in v1" parallelism disclaimers with per-host guidance — Slicc dispatches one scoop per block via the cone, Claude Code dispatches one Agent subagent per block. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deliberately high for now to avoid premature auto-switching while we gather data on real pages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Improvements to the snowflake static-to-EDS skill, in five areas:
Startup (init / inputs / defaults)
projectsDir,daRoot,branchPrefix,trunkBranch,tagPrefix) now live in adefaultsblock inMANIFEST.jsonand are stamped into.snowflake/config.jsonon install; user-edited values survive upgrades.Phase 0 substrate install
aem-boilerplateclone no longer triggers a confirmation pause. The installer reports which pre-existing files it replaces (all backed up) and proceeds; only genuine drift (a prior snowflake substrate that diverged) still requires--force.Browser interactions
playwright-clicommands, so any host browser tool (cmux-browser, playwright-cli, …) can fulfil them.Phase 5 round-trip health gate
window.__errors, which nothing populated; it is replaced with real capture plus an injectable fallback.Substrate un-weave
scripts.jsinto a wholesale-replacedscripts/overlay-engine.js.scripts.jsis no longer replaced — the installer injects a small import + aloadEagerguard via a new anchored, idempotentinjectoperation (fail-loud with a manual snippet if the anchor is absent). This preserves Adobe's upstreamscripts.jschanges across installs. Substrate bumped to v1.1.0.Test Plan
node --test plugins/aem/edge-delivery-services/skills/snowflake/scripts/install-substrate.test.mjs(6/6 pass)npm run validate— snowflake skill validatesadobe/aem-boilerplateinstall: anchors match current upstream, injectedscripts.jspassesnode --check, config stamped v1.1.0 + defaults, idempotent re-run no-opsNote: includes design spec + implementation plan under
docs/superpowers/for the substrate un-weave.🤖 Generated with Claude Code