M1 PR-2: dspack surface → A2UI emitter + library exports#4
Merged
Conversation
- input contract upgraded to dspack v0.3 (intents/rules/examples governance blocks; catalog emission verified byte-identical — the transformer ignores the new blocks per dspack conformance rules) - src/targets/a2ui/surface.ts: compiles a dspack surface (CSR, surface schema v0.1) into A2UI v0.9 messages. Projection knowledge is data in the profile (surfacePlan directives); compound composition flattens per the MAPPING.md casualties; synthesized actions and every drop are recorded as warnings. Unknown components raise EmitSurfaceError (CLI exit 4). - CLI --emit-surface: emits + instance-validates (gate A3) against the freshly generated catalog. - library exports (src/index.ts + exports map + tsc build with declarations); pack-and-install boundary test (npm run test:pack) proves the package is consumable via the exports map only — publish-ready, consumed as a pinned git dependency until the publish decision at M1 exit. - surface/delete-account.dsurface.json: the contract's worked example as a standalone golden CSR; CI workflow runs tests, both catalog emissions, surface emission, and the pack test. Verify: npm test && npm run test:pack && npm run transform -- --in input/shadcn-ui.dspack.json --a2ui-version 0.9.1 --out out --emit-surface surface/delete-account.dsurface.json Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR makes dspack-to-a2ui consumable as an A2UI emitter library and adds a new dspack surface (CSR) → A2UI v0.9 message emitter, including CLI support, tests, packaging boundary checks, and CI to verify the milestone’s machine-checkable gates.
Changes:
- Add
emitSurface(dspack surface v0.1 → A2UI v0.9createSurface+ flatupdateComponents) driven by profilesurfacePlandirectives. - Expose a stable public library API via
src/index.ts+package.jsonexports, and enable TS declaration output. - Add acceptance tests + pack/install smoke test + GitHub Actions workflow to run gates and surface emission.
Reviewed changes
Copilot reviewed 12 out of 16 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
tsconfig.json |
Enables declaration output to support library consumption. |
surface/delete-account.dsurface.json |
Adds a concrete dspack-surface v0.1 input used for surface emission. |
src/types.ts |
Introduces DspackSurface / SurfaceNode types for the new surface protocol. |
src/transform/profiles.ts |
Adds surface projection vocabulary (surfaceSynthesis, surfacePlan) to profiles and wires it into shadcnProfile. |
src/targets/a2ui/surface.ts |
Implements the surface emitter, warnings, and deterministic ID/event synthesis. |
src/surface-emit.test.ts |
Adds emitter-focused tests: projection behavior, determinism, failure modes, and gate validation. |
src/index.ts |
Defines the public library surface and re-exports emitter + validation APIs. |
src/cli.ts |
Adds --emit-surface flow (emit + instance-validate against generated catalog; exit code 4 on failure). |
scripts/pack-test.sh |
Adds pack-and-install boundary test for exports-only consumption. |
README.md |
Documents emitter gates naming and how to run surface emission via CLI. |
package.json |
Adds exports map + build/prepare/test:pack scripts; updates package name/description. |
out/validation-report.v1_0.json |
Updates generated timestamp in emitted validation report artifact. |
out/validation-report.v0_9_1.json |
Updates generated timestamp in emitted validation report artifact. |
out/delete-account.surface.json |
Adds emitted surface output artifact for the worked example. |
input/shadcn-ui.dspack.json |
Updates contract to dspack v0.3 and embeds intents/rules/worked surface example. |
.github/workflows/test.yml |
Adds CI to run tests, transform emission, and pack/install boundary checks. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Found via the live demo: A2uiSurface begins rendering at component id 'root' (as the hand-authored surfaces do); the emitter previously derived the root id from the component name, leaving the renderer at '[Loading root...]'. Gates A1-A3 don't check ids, so only rendering caught it — exactly what the render step of the demo exists to prove. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…interactive-descendants (input copy) Mirrors the same one-line fix on dspack#9 (see that commit for the design grounds: ADR-7 repair template carries linked examples; this was the one rule without a corrected reference). Repair-feedback-only change: the example is already in the destructive-action few-shot, so generation context is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 2, 2026
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.
What this is
PR-2 of Milestone 1 (governed generation vertical slice; depends on aestheticfunction/dspack#9 for the v0.3 spec, though this repo carries its own contract copy). This repo becomes consumable as the A2UI emitter target of the pipeline.
Contents
ex.delete-account-confirmationexample). Catalog emission verified byte-identical — the transformer ignores unknown blocks per dspack conformance rules (only report timestamps changed).src/targets/a2ui/surface.ts— dspack surface (CSR, surface schema v0.1) → A2UI v0.9 messages (createSurfacewith dspack-token theme + flatupdateComponents). All projection knowledge is data in the profile (surfacePlandirectives); the engine has no component-name-specific code (matches the existing engine+profile architecture — no engine changes). Compound composition flattens per the documented MAPPING.md casualties; A2UI's required declarative actions are synthesized with deterministic event slugs; every synthesis/drop is a recorded warning — nothing silent.--emit-surface— emits and instance-validates (gate A3) against the freshly generated catalog; exit4on unknown component / unprojectable structure.transform,emitSurface,validateCatalog,extractInstances,shadcnProfilevia an exports map; tsc build with declarations; no npm publish in M1 (per revised plan): dspack-gen consumes a pinned git dependency; boundary verified by a pack-and-install test.Acceptance (machine-verifiable)
All run in CI (
.github/workflows/test.yml, new — this repo previously had no workflow).Hand-review focus
SurfacePlanDirectivesinsrc/transform/profiles.ts(the public projection vocabulary) and theemitSurfacesignature — the rest is gate-verified.ADRs: 2 (CSR compiled down by emitters), 4 (emitter repo + git-dep consumption), 5 (v0.9 envelope; instances validate against both catalogs).
🤖 Generated with Claude Code