Skip to content

M1 PR-2: dspack surface → A2UI emitter + library exports#4

Merged
ryandmonk merged 3 commits into
mainfrom
claude/inspiring-bartik-07ada9
Jul 2, 2026
Merged

M1 PR-2: dspack surface → A2UI emitter + library exports#4
ryandmonk merged 3 commits into
mainfrom
claude/inspiring-bartik-07ada9

Conversation

@ryandmonk

Copy link
Copy Markdown
Contributor

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

  • Input contract → dspack v0.3: same governance blocks as the spec repo's example (1 intent, 3 rules, worked ex.delete-account-confirmation example). 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 (createSurface with dspack-token theme + flat updateComponents). All projection knowledge is data in the profile (surfacePlan directives); 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.
  • CLI --emit-surface — emits and instance-validates (gate A3) against the freshly generated catalog; exit 4 on unknown component / unprojectable structure.
  • Library exportstransform, emitSurface, validateCatalog, extractInstances, shadcnProfile via 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.
  • Gate naming: README documents A1/A2/A3 as the emitter-side names for the existing three ajv gates (S1–S3 run upstream in dspack-gen).

Acceptance (machine-verifiable)

npm test          # 30 tests: A1–A3 pass over the emitted worked example (both A2UI versions),
                  # AlertDialog flattening golden, unknown component → typed error,
                  # missing title → A3 FAILS (gate proven non-vacuous), determinism
npm run test:pack # npm pack → install into temp project → import smoke via exports map only
npm run transform -- --in input/shadcn-ui.dspack.json --a2ui-version 0.9.1 --out out \
  --emit-surface surface/delete-account.dsurface.json   # exit 0; bad CSR → exit 4

All run in CI (.github/workflows/test.yml, new — this repo previously had no workflow).

Hand-review focus

SurfacePlanDirectives in src/transform/profiles.ts (the public projection vocabulary) and the emitSurface signature — 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

- 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>
Copilot AI review requested due to automatic review settings July 2, 2026 16:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.9 createSurface + flat updateComponents) driven by profile surfacePlan directives.
  • Expose a stable public library API via src/index.ts + package.json exports, 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.

Comment thread src/targets/a2ui/surface.ts
Comment thread src/targets/a2ui/surface.ts
Comment thread .github/workflows/test.yml
Comment thread src/targets/a2ui/surface.ts
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>
@ryandmonk ryandmonk merged commit 793c065 into main Jul 2, 2026
1 check passed
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.

2 participants