Skip to content

feat(starters): recreate production websites as local prototypes - #252

Merged
PCoelho merged 4 commits into
mainfrom
feat/production-prototype-skill
Nov 13, 2026
Merged

PCoelho merged 4 commits into
mainfrom
feat/production-prototype-skill

Conversation

@PCoelho

@PCoelho PCoelho commented Nov 13, 2026

Copy link
Copy Markdown
Collaborator

Why

Product teams need to explore changes to an existing website without changing the live product. Rebuilding its pages, navigation and visual patterns by hand is repetitive work, while disconnected mockups leave out the context needed to judge how a change fits the wider experience. This skill gives teams an editable, connected local starting point from a public production site, so they can focus on testing ideas rather than reconstructing what already exists.

What changes

Adds create-prototype-from-production to the Minimal starter. It turns a public production URL into a standalone, connected prototype in one run:

/create-prototype-from-production https://example.com/

The skill asks two intake questions (coverage and a go-ahead for local work). Unattended runs apply the defaults. The go-ahead covers only local, git-reversible work; the skill never signs in, submits real data, pushes or publishes. Then it runs three phases:

  1. Discover: proves the browser session is empty, finds every first-level destination in the rendered site (header, menus, mobile menu, footer) and groups pages into families by their section structure.
  2. Capture: saves one full reference per family and the content of every page under reference/.
  3. Build: builds each family's representative first, checks it section by section against the source, builds the rest of the family from it, verifies every local route and sets the source page as the entry page.

A coverage ledger, reference/coverage.json, records each destination as built, stubbed (external, login, download) or deferred. check-ledger.mjs enforces the coverage and routing rules, and its --final mode requires a verified source page.

Safety model. The browser runs in a fresh, signed-out session, so the only way a secret can enter the run is through the URL the user supplies; the ledger rejects a source URL that carries one. The browser loads the public site like any visitor's browser, which the skill states. The agent's own downloads go through fetch-assets.mjs, which rejects private addresses before connecting and on every redirect, limits size and time, and records sources with signing values redacted. Captured content stays under reference/ as data and never becomes agent guidance. Captured SVGs are used only through <img> or CSS.

Context. create-prototype needs active context. When a repository has none, the skill copies Minimal's default context files into .agents/context/ with one cp command. Existing team guidance is used as is.

Why the Minimal starter only. Cloning a production site wants a blank canvas with no component library, which is Minimal. Putting the skill in starters/shared would list it in every app's repositories, where it isn't useful.

Hub test fixes. Starter changes select Hub integration checks, and this PR exposed three existing test-fixture races there: a canvas test queried lazy review controls before initialization, a Hub-panel test assumed selection would stay the last message during bridge polling, and a Rails reply fixture could violate a timestamp constraint across a clock tick. The fixes are test-only.

Results. Headless runs on a fresh Minimal repository built awesome-azd in 14 minutes (6 pages, 12 assets) and Gymshark in about 75 minutes (187 pages, 1,658 assets, 4 sign-in boundaries). Both passed the final ledger check with no blocked rows or rejected assets.

Scope. Public sites only. Support for apps behind a sign-in is tracked in #251.

History. This replaces #195, whose review rounds added and then removed a large hardening layer. That PR keeps the full review discussion; this one carries only the final result.

Known limitations:

  • The downloader does not pin connections, so DNS rebinding between its check and the connection is an accepted risk.
  • Attended intake has not yet been exercised with user responses.

PCoelho and others added 3 commits November 13, 2026 12:44
Settle lazy canvas imports, ignore earlier bridge messages and fix reply
timestamps before deletion so these suites stop flaking on starter changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 70eb50ed-f16b-426d-9f3b-00aaa9c0f5aa
Add URL and ledger checks and a bounded asset downloader for the
production prototyping skill, with their tests wired into Minimal.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 70eb50ed-f16b-426d-9f3b-00aaa9c0f5aa
Minimal can now turn a public website into a local prototype through
Discover, Capture and Build workflows, with general default context.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 70eb50ed-f16b-426d-9f3b-00aaa9c0f5aa
@PCoelho
PCoelho requested review from a team and nshki as code owners November 13, 2026 20:45
Copilot AI dynamic review requested due to automatic review settings November 13, 2026 20:45
@PCoelho

PCoelho commented Nov 13, 2026 •

Copy link
Copy Markdown
Collaborator Author

Real-run proof

Both runs used a freshly assembled Minimal repository whose skill files match this PR, on macOS with Copilot CLI 1.0.111 and claude-sonnet-5.5. Each ran headless in autopilot with a separate COPILOT_HOME, so the only Playwright server was the repository's isolated one. Nothing was pushed or published. The prompt was Create a prototype from <URL>. The intake questions went unanswered, so the defaults applied.

awesome-azd (https://azure.github.io/awesome-azd/): the about:blank check found 0 cookies and 1 page. --final reports {"build/verified":6,"stub-external":13,"deferred/verified":2} with no blocked rows. fetch-assets.mjs fetched 12 assets and rejected none. startPage is /. The agent checked every local route in the browser at 1440 and 390 px, and check:starter passes. 258 AI credits, 14 minutes.

Gymshark (https://www.gymshark.com/): the about:blank check found 0 cookies and 1 page. --final reports {"build/verified":187,"stub-external":19,"stub-auth/verified":4}. The four account and wishlist pages became sign-in boundaries. fetch-assets.mjs fetched 1,658 assets (222 MB) and rejected none. startPage is /, and check:starter passes. 393 AI credits, about 75 minutes.

An earlier run found a defect. Chrome wasn't installed, so the isolated browser couldn't start. One run stopped correctly. The other fell back to web_fetch and recorded a browser check that never ran, and --final still passed. The fix, included here, adds one sentence to the Discover workflow and one row to the red-flag table: if the browser can't start, stop and report it. Both runs above came after that fix, with Chrome installed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The downloader continues requests to denied origins and validates metadata only after downloads, violating the required stop rule and risking untracked files and redundant transfers.

2 open issues
What changed in this PR

Adds a Minimal-only workflow for recreating public production websites as connected, editable local prototypes. Hub and publishing remain optional; sign-in-gated sites are outside this PR’s scope.

Changes:

  • Introduces discovery, capture and build workflows with coverage tracking and route verification.
  • Adds URL validation, bounded asset downloads, default context and helper tests to Minimal’s checks.
  • Updates starter assembly coverage and stabilizes three Hub test fixtures.
File Description
starters/​shared/​.agents/​context-templates/​SKILL.md Documents Minimal’s fixed-context exception.
starters/​minimal/​package.json Integrates helper tests and formatting.
starters/​minimal/​AGENTS.md Updates check and context guidance.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​workflows/​discover.md Defines browser preflight, discovery and classification.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​workflows/​capture.md Defines reference and asset capture.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​workflows/​build.md Defines implementation, comparison and route verification.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​SKILL.md Defines intake, scope and phase coordination.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​scripts/​fetch-assets.node-test.mjs Covers download limits, redirects and metadata.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​scripts/​fetch-assets.mjs Implements bounded asset downloads and provenance.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​scripts/​check-public-url.node-test.mjs Covers URL validation and redaction.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​scripts/​check-public-url.mjs Validates destinations and redacts sensitive URL values.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​scripts/​check-ledger.node-test.mjs Covers ledger rules and CLI behavior.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​scripts/​check-ledger.mjs Enforces coverage, routing and completion rules.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​references/​local-context/​SEED-DATA.md Supplies default data guidance.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​references/​local-context/​RESPONSIVE-DESIGN.md Defines responsive validation targets.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​references/​local-context/​REPOSITORY.md Describes Minimal’s structure and commands.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​references/​local-context/​PRODUCT-DESIGN.md Defines local, mock-only prototype behavior.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​references/​local-context/​DESIGN-SYSTEM.md Supplies component and styling defaults.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​references/​local-context/​BROWSER-VALIDATION.md Defines isolated browser validation practices.
starters/​minimal/​.agents/​skills/​create-prototype-from-production/​references/​local-context/​ACCESSIBILITY.md Supplies accessibility expectations and evidence limits.
scripts/​create-prototype-repo.test.mjs Checks the added skill and default-context filenames.
hub/​test/​integration/​canvas_repository_comments_test.rb Orders fixture timestamps before deletion.
hub/​app/​javascript/​features/​prototype-canvas-hub-panel/​index.test.tsx Makes message assertions tolerate bridge polling.
hub/​app/​javascript/​application/​prototype-canvas/​tests/​commenting-and-polish.test.tsx Waits for lazy review controls before interaction.
docs/​starter-development.md Documents the helper-test command.

Review effort: Max (dynamic)

A malformed assets.json now stops the downloader before any request,
so it never leaves files without metadata.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 70eb50ed-f16b-426d-9f3b-00aaa9c0f5aa

@nshki nshki left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @PCoelho!

@PCoelho
PCoelho merged commit f6e0380 into main Nov 13, 2026
46 checks passed
@PCoelho
PCoelho deleted the feat/production-prototype-skill branch November 13, 2026 22:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants