Contributor docs

September 6, 2026 · View on GitHub

These are contributor docs — for working on this repo (plugin, CLI, renderers, daemon, VS Code extension). They assume you're building from source with ./gradlew against the local tree.

Consumer docs live elsewhere. If you just want to use the published plugin/CLI, see the documentation site and the yschimke/skills bundles (compose-preview, compose-preview-review). Don't duplicate consumer guidance here.

Rules live in root AGENTS.md — the short, canonical file every agent loads on every turn. This tree is the detail behind it: start with AGENT_GUIDE.md for the architecture map and the rationale, and treat this index as the map of everything else.

Orientation

  • root AGENTS.md — the CI-enforced invariants and the normative PR workflow, stated once. Every agent loads it on every turn.
  • AGENT_GUIDE.md — class-by-class architecture, commands, constraints, and the rationale behind the rules. Read first.
  • HOW_IT_WORKS.md — end-to-end: how a @Preview becomes a PNG.
  • DEVELOPMENT.md — building the plugin, CLI, and extension from source.
  • RENDER_FILENAMES.md — render output layout and filename normalization.

Rendering & compatibility

Integration & distribution

Process & policy

  • RELEASING.md — release-please flow.
  • VERSIONING.md — versioning policy for public surfaces.
  • API_STABILITY.md — what counts as a public contract.
  • AGENT_INVOCATION.md — summoning an agent onto an issue/PR.
  • AGENT_ENTRYPOINTS.mdmeasurement: which instruction file each agent (Claude Code, Codex, Gemini, Copilot) actually resolves, why none of them follows a markdown link, what the old layout cost the three non-Claude agents, and the CI gate that keeps every CI-enforced invariant reachable from all four.
  • PR_REVIEW_WORKFLOW.md — preview-gated AI PR review.
  • TOKEN_USAGE.md — token-budget reference for agent recipes.
  • Testing the extension in a cloud sandbox — moved with the extension to docs/CLOUD-TESTING.md in compose-preview-vscode.

Daemon

The long-lived renderer. See daemon/README.md for its own index; the load-bearing specs are daemon/DESIGN.md, daemon/PROTOCOL.md (wire format), daemon/DATA-PRODUCTS.md, and daemon/MCP.md. The in-process / continuous-compile save loops (composePreview.daemon.compileInProcess and composePreview.daemon.continuousCompile) are experimental features whose behaviour is documented in the code that implements them — :daemon:core's bta/ package and the VS Code extension's daemon client.

Specs behind shipped code (design/)

The design/ tree used to hold many speculative proposals; what remains are the specs the code actually depends on:

  • design/BUILD_HOST_PROTOCOL_PREVIEWMODULE.mddecision requested: where PreviewModule lives once ServeBuildHost becomes a wire protocol between the preview server and a compose-preview build-host process. Four options costed (contracts depending upward, redeclaring the shape there, moving the type down, or publishing the protocol from here), why the type's java.io.File and Serializable shape is owned by the Gradle Tooling API rather than by a wire, and a recommendation that turns on the change loop rather than on purity.
  • design/REPOSITORY_LAYERS.mdnormative: which repository a module belongs in. Four layers (contracts = shape; compose-ai-tools = offline behaviour; compose-preview-server = HTTP and the surfaces over it; vscode/xr = leaves), a dependency may only point down, and the consequences that follow — why the Gradle Tooling API is permanently compose-ai-tools', and why a fourth repository is not the answer to a misplaced module.
  • design/RELEASE_TRAINS.mdmeasurement + proposal: this repository publishes 94 Maven artifacts on a line that releases ~6 times a day, and 96.7% of what it uploads is a version-bumped rebuild of identical code (117 module-changes against 3,572 module-publications over 38 releases). Measures each lever: a change-detection guard on the publish (−15.8%, implemented in reporting mode), splitting the publish into five cadence-based trains (−45.7%), and why skipping is unsafe until the CLI names the Maven version it was built against rather than assuming its own.
  • design/SPATIAL_SCENE_CONTRACT.md — the XR scene wire format (schema-generated Kotlin/TS/C++ mirrors).
  • design/DESIGN_CATALOGS.md — the code-led sticker-sheet catalog system.
  • design/USAGE_SNIPPET_CORPUS.mdmeasurement: whether the Source panel's "plain Compose" actually compiles. Samples previews from real catalog checkouts, cleans them with each catalog's own rules, and compiles the result against a consumer's classpath (Compose + material3 only, deliberately not the catalog's). Records the current ratios, the failure taxonomy, and why one catalog's zero is structural rather than a missing rules file.
  • design/PSI_PARSE_SPIKE.mdspike: should the usage cleaner parse instead of scan? Measures parse-only Kotlin PSI (no analysis, no classpath), what it costs per file, which of the corpus's defects it settles, and that it reaches the CLI through the existing isolated lib-bta/ loader. Includes what it does not buy, and two corrections to its own earlier numbers.
  • design/UI_BUILDER.mdproposal: assembling screens from catalog components (scaffold-first slots, a persisted composition document, Figma round-trip). Product analysis + phased plan; no code yet.
  • design/COMPONENT_RECORD.mdplan: one derived component record replacing the three hand-written tables the UI builder keeps in sync by hand, overrides moved out of composable bodies and into the preview function's own parameter list, code generated by printing a call site rather than subtracting scaffolding, and a mechanical conformance ladder deciding which surface a component reaches. Root-cause analysis measured over this repo, m3-catalog, wear-m3-catalog/remote-m3 and a typical app; supersedes UI_BUILDER.md on architecture.
  • design/AGENT_ACCESS_GRANTS.mdshipped: how an agent with no credential gets temporary, scoped, revocable access to a serve host — an RFC 8628-shaped device grant where the agent prints a link and a verification code, a human approves in a browser, and the token is delivered to the poller rather than to whoever opens the link. Covers why the link is not the credential, what each scope maps to, and the two ceilings on what an approver may pass on.
  • design/PLAYGROUND.mdproposal: a hosted Kotlin/Compose editor over the serve preview server (compile-then-permalink handoff, CMP / Compose-Android / Remote-Compose modes, the preview-token capability, isolation requirements). Product analysis + phased plan; Phase 1 in progress.
  • design/CATALOG_ONBOARDING.mdplan: onboarding a GitHub project into the preview server from its URL alone, with no change to the target repo (#4789). A separate builder repository checks the target out, auto-injects the plugin and publishes its catalog branch; the approval is a PR against that builder, with a trial render attached. Covers why the build job holds no write credential, why one builder must not mean one trusted producer, and the consent/attribution policy for rendering repos that never asked.
  • design/RC_CMP_WASM_PLAYER.mdproposal: an original non-JVM CMP player for Remote Compose documents, with a typed binary codec, Compose/Skiko rendering boundaries, operation clusters, and per-operation conformance gates.
  • design/RC_PLAYER_PROFILING.mdmeasurement: what androidx.tracing 2.x says about the CMP player's decode/link/layout/paint/input phases over four reference documents (static button, canvas, animated canvas, interactive button), why the tracing seam is an expect/actual facade, and how to re-run the profile.
  • design/RC_PLAYER_TYPEFACES.mdaudit: how each of the five Remote Compose player lanes (js, cmp-wasm, java, cmp-android, cmp-jvm) resolves built-in, named, downloadable, and document-embedded typefaces, and where two chips in the same viewer disagree about one document.
  • design/COMPONENT_PARITY_WORKFLOW.mdPhase 1 shipped, rest proposal: turning parity reporting into an iterative loop — a stable component/preview/reference locator, a published GitHub issue index (parity/issues.json), and issue-linked scoped acceptance of one known difference that still detects everything else. The locator, the index and its four display surfaces are live and carrying real issues; scoped acceptance, element selection and resolution automation are still a phased plan (#3680).
  • design/RC_TEXT_METRICS.mdharness: Remote Compose documents that measure their own text with TextMeasure and draw the answers as guide lines, so each player lane renders its own metrics and a text divergence gets a name instead of a pixel percentage. Companion to the typefaces audit — that one covers which face, this one covers how it is laid out once chosen.
  • design/CATALOG_CONTENT_CACHE.mdproposal: a durable, commit-addressed home for fetched catalog content, so a redeployed serve adopts the catalogs it already had, converges to the branch tip in the background, and re-fetches only what moved. Companion to the theme cache — that one persists derived pixels, this one persists published bytes. Phased plan; no code yet.

Component-level contracts (the XR semantics tree, FigmaLayeredSvg, the font preview wrapper, @XrSubspacePreview) now live as KDoc on the owning class, not as separate docs — read them next to the code.

Internal tooling