feat(artifact-compiler): emit companion_plugin_payload producer seam (#491 slice 2)#240
Merged
Merged
Conversation
Add the producer half of the companion-plugin / plugin-materialization keystone (issue #491). Slice 1 (SSI #492) built the consumer (Static_Site_Importer_Companion_Plugin::scaffold()); this slice packages the generated block definitions the ArtifactCompiler already detects (block.json + render + view JS + assets) into a companion_plugin_payload whose shape exactly matches what scaffold() consumes. - New CompanionPluginPayload builder collects detected block types plus their file contents into per-block entries (name, block_json, render, view_js, assets) and stamps the shared consumer schema. - Payload includes an empty preserved_js slot for the later JS->plugin wire-up (SSI #488), and derives site_slug/site_name/mu_plugin from the artifact when carried (SSI may override site identity at install time). - Emitted under source_reports.companion_plugin_payload only when at least one generated block exists; absent otherwise (core/html fallback unchanged). No mapping/routing changes. Proven end-to-end against slice-1's real scaffold(): the emitted payload materializes a complete ssi-<site> plugin file set. Contract tests cover present-with-block, present-without-site, and absent-without-blocks. Co-Authored-By: Claude Opus 4.8 <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
Refs #491 (slice 2 of N). Slice 1 is SSI #492 (merged), which built the consumer:
Static_Site_Importer_Companion_Plugin::scaffold()turns a "companion plugin payload" into an installable, theme-independent plugin that houses generated custom blocks (registered from their ownblock.json) plus preserved island JS. This PR is the producer: it extends the blocks-engineArtifactCompilerto emit acompanion_plugin_payloadwhose shape exactly matches what slice-1'sscaffold()consumes.This is purely the packaging seam. It does not change mapping/routing —
core/htmlstays the safe fallback, and there is no "generate a custom block instead of core/html" path here (that is a later wire-up / recognizer hook). The producer only packages generated blocks the artifact already declares viablock.json(the compiler already detects/validates these — seeinvalid_block_json/block_json_missing_name).Payload shape -> slice-1 contract
source_reports.companion_plugin_payload:schema— stampsstatic-site-importer/companion-plugin/v1(mirrors SSI'sPAYLOAD_SCHEMA) so the consumer can assert conformance.blocks[]— one per detected generated block:name(local slug; SSI namespaces it tossi-<site>/<name>),block_json(decoded array),render(render.php content),view_js(viewScript content),assets{}(remaining block-dir files keyed by block-relative path). Render / view JS / block.json are excluded fromassetsso the consumer doesn't write them twice.preserved_js[]— empty slot today; reserved for the JS->plugin wire-up (SSI #488).site_slug/site_name/mu_plugin— derived from the artifact envelope when carried; omitted otherwise (SSI supplies site identity at install time).Producer behavior
src/ArtifactCompiler/CompanionPluginPayload.phpbuilder wired intoArtifactCompiler::compile().HtmlTransformer.php/ButtonsPattern.phpare untouched (avoiding the Style fidelity: translate source CSS styling onto native block attributes (buttons render as default gray) #233 button-styling work).Proven end-to-end
A scratch harness ran the emitted payload through slice-1's real
scaffold()(fetched fromorigin/main): it materializes a completessi-acme/...plugin file set (main plugin file,blocks/hero/block.jsonrewritten tossi-acme/hero,render.php,view.js,style.css,index.js). Confirms the shape conforms to slice-1 with no slice-1 change required.Tests
composer test:canonical— pass (added contract assertions: payload present with a synthetic block, present without site identity, absent without blocks; render/view/block.json not duplicated into assets).composer parity— pass (125 fixtures).composer test(incl. packaging install-proof) — pass.DO NOT MERGE.
🤖 Generated with Claude Code