docs: add runnable examples and SourceFile embedding for Allows reference#1179
docs: add runnable examples and SourceFile embedding for Allows reference#1179
Conversation
Add four new App examples covering scenarios from the Allows docs that lacked runnable code: CSV flat records, event bus with sealed trait auto-unwrap, GraphQL/tree structures with Self recursion, and sealed trait auto-unwrap with nested hierarchies. Also add a "Running the Examples" section to allows.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add mdoc:passthrough blocks using SourceFile.print to embed full example source files directly in the Allows reference page. Move SourceFile to package docs so mdoc can import it. Update docs-data-type-ref skill with the SourceFile.print convention and correct import pattern. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds documentation support for embedding full runnable example sources in the Allows reference, and introduces several new schema-examples Apps to cover previously undocumented scenarios.
Changes:
- Added
docs.SourceFilehelper to embed source files into docs viamdoc:passthrough. - Added 4 new runnable
schema-examplesApps demonstrating Allows scenarios (CSV, event bus, GraphQL/tree recursion, sealed trait auto-unwrap). - Updated
docs/reference/allows.mdto embed all example sources, and updated the docs skill guide to codify theSourceFile.printconvention.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
zio-blocks-docs/src/main/scala/SourceFile.scala |
New helper for reading/printing source files into mdoc output. |
schema-examples/src/main/scala/comptime/AllowsSealedTraitExample.scala |
Runnable example for sealed trait auto-unwrap behavior. |
schema-examples/src/main/scala/comptime/AllowsGraphQLTreeExample.scala |
Runnable example showing Self for recursive/tree-like grammars. |
schema-examples/src/main/scala/comptime/AllowsEventBusExample.scala |
Runnable example for event bus publishing constraints over sealed traits. |
schema-examples/src/main/scala/comptime/AllowsCsvExample.scala |
Runnable example for CSV flat-record constraints. |
docs/reference/allows.md |
Adds “Running the Examples” section and embeds example sources via SourceFile.print. |
.claude/skills/docs-data-type-ref/SKILL.md |
Documents the SourceFile.print embedding pattern and import convention. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* docs: add Structural Types reference page and examples Implements documentation for the ToStructural[A] type class and structural types feature (Issue zio#517 / PR zio#614). Includes: - New reference page (docs/reference/structural-types.md) covering: - Type signature and use cases for structural types - Motivation (duck typing, cross-system interop) - Construction via .structural extension method - Supported conversions (products, tuples, sum types) - Integration with DynamicValue and Schema Evolution - Compile-time errors and limitations - Example applications in schema-examples/: - StructuralProductExample: simple and nested case classes - StructuralSumTypeExample: sealed traits and enums - StructuralTupleExample: tuple structural schemas - StructuralIntegrationExample: DynamicValue manipulation - Sidebar navigation updated to include new reference page All documentation compiles with mdoc and examples run without errors. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs: enrich Structural Types reference page with gh-query findings Enriched the structural types documentation with insights from GitHub issues and PRs: 1. **Scala 2 Deeply Nested Types Limitation** (zio#612): In Scala 2, accessing fields on deeply nested structural types requires explicit casting to StructuralRecord, as reflection limitations prevent field chaining. Added workaround with example. 2. **Alphabetical Field Ordering Rationale**: Clarified that alphabetical sorting ensures deterministic, normalized type identity for predictable schema evolution and cross-system interop. 3. **Binding.of Integration** (zio#883): Added section documenting support for structural types in Binding.of macro for high-performance JVM-only serialization of anonymous structural types. 4. **Platform Detection**: Noted that implementation uses Platform.supportsReflection to detect and reject structural types at compile time on non-JVM platforms. All examples compile with mdoc, 0 errors. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * fix: correct runMain command in StructuralIntegrationExample documentation comment Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * fix: correct object name in StructuralIntegrationExample to match filename Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs: enrich Round-tripping Through DynamicValue section with cross-type conversion motivation The section now explains why structural types matter for DynamicValue round-tripping: - Shows the real benefit: cross-type conversion (Person → DynamicValue → Employee) - Adds concrete integration scenarios (API gateways, message brokers, data pipelines) - Includes comparison table for when to use structural vs nominal schemas - Example demonstrates encoding with one schema and decoding with another This replaces the thin example that only showed encoding/decoding the same type. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs: ensure structural-types.md compliance with writing style and mdoc conventions - Add mdoc modifiers (compile-only, silent, mdoc) to all Scala code blocks - Add introductory prose before "Type Signature" heading and code block - Remove emojis (✅, ❌) from comments; replace with plain English descriptions - Add missing imports (Schema, SchemaError) in code blocks - Refactor cross-type conversion example: split into setup (mdoc:silent) + evaluated output (mdoc) blocks - Ensure all code blocks are self-contained and compile-checked Fixes compliance violations in: - docs-writing-style (emoji removal, prose requirements) - docs-mdoc-conventions (modifier requirements, import requirements, setup + output pattern) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs: enforce sbt docs/mdoc compilation verification in documentation workflows Add mandatory mdoc compilation checks across all documentation skills: - docs-integrate: Convert Step 4 to explicit compilation gate with error checks - docs-data-type-ref: Add mdoc verification to Step 5 Review - docs-how-to-guide: Add mdoc check to Technical Accuracy checklist in Step 6 - docs-enrich-section: Add final Verification step with mdoc check All Scala code blocks in docs are now compile-verified before completion. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs: remove irrelevant "With DynamicValue" section from structural-types reference The "With DynamicValue" subsection demonstrated general Schema features (toDynamicValue, fromDynamicValue, DynamicOptic) using a nominal schema, not a structural one. This content is not specific to structural types and was off-topic. The bottom "See Also" section already links to DynamicValue documentation. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * More efficient encoding and decoding of `java.time._` in different codecs (zio#1163) * Update zio-json and zio-schema dependencies (zio#1165) * Documentation of As/Into Derivation for DynamicValue (zio#1168) * Add docs-document-pr skill for generating documentation from pull requests Generates docs by gathering PR metadata, linked issues, and commits, then creates a new reference/guide page or adds a subsection to existing docs based on content type. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * refactor(docs-document-pr): Delegate to specialized documentation skills Phase 3 now leverages existing ZIO Blocks documentation skills: - docs-data-type-ref for new reference/API pages - docs-how-to-guide for new how-to guides - docs-writing-style for prose conventions - docs-mdoc-conventions for code block formatting Phase 4 uses docs-integrate skill for sidebar management. This reduces duplication, ensures consistency across docs, and makes the skill more modular by composing with domain-specific expertise. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * feat(docs-document-pr): Add YAML frontmatter with metadata Add skill frontmatter containing: - name: docs-document-pr - description: Comprehensive skill purpose - triggers: keyword patterns for skill auto-invocation This enables proper skill discovery and auto-triggering based on user intent patterns like "document PR zio#1234". Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs: add comprehensive reference for Into and As type classes (PR zio#1007) Created docs/reference/into-as.md covering: - Into[A, B]: one-way schema-driven conversions - As[A, B]: bidirectional conversions with round-trip guarantees - DynamicValue integration for polyglot serialization - Numeric widening/narrowing with validation - Container conversions (Option, Either, Map, List, Array, etc.) - Schema evolution patterns and custom validations - Error handling and cross-format support Integrated into documentation: - Added to sidebars.js in Reference section - Updated docs/index.md with link in Data Operations - Added cross-references from Schema and DynamicValue pages Also integrated existing schema-examples for Into and As: - IntoDomainBoundaryExample: custom validations - AsNumericRoundTripExample: bidirectional numeric conversions - AsManualConstructionExample: combining Into instances - AsSchemaEvolutionExample: schema evolution patterns - AsReverseExample: reversing conversions Addresses documentation gap for PR zio#1007 which adds DynamicValue support to Into/As macros, enabling seamless conversions between typed data and semi-structured representations. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Revert "docs: add comprehensive reference for Into and As type classes (PR zio#1007)" This reverts commit da0fd3c. * docs(schema-evolution): Add DynamicValue conversion sections (PR zio#1007) Enhanced Into and As documentation with comprehensive DynamicValue support sections covering the new macro capabilities added in PR zio#1007. Added to docs/reference/schema-evolution/into.md: - Converting to DynamicValue (type-safe → semi-structured) - Converting from DynamicValue (semi-structured → type-safe) - Collections and DynamicValue conversions (List, Map, etc.) - Motivation: polyglot data handling and format independence Added to docs/reference/schema-evolution/as.md: - Bidirectional DynamicValue conversions with round-trip guarantees - Use cases: polyglot configuration systems and schema-driven migrations - Chained migration patterns (A → DynamicValue → B) - Scala 2/3 differences including ambiguity detection These additions document the DynamicValue feature that enables seamless conversions between type-safe domain models and semi-structured data representations, critical for polyglot serialization workflows. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs(schema-evolution): Enhance DynamicValue examples with JSON round-tripping Updated DynamicValue conversion sections to show complete polyglot workflows: - Type → DynamicValue → JSON → DynamicValue → Type - Demonstrates full round-trip cycle with actual serialization - Shows practical use cases with real data flow In docs/reference/schema-evolution/into.md: - Added JSON serialization to "Converting to DynamicValue" section - Added round-trip examples for collections (List, Map) - Demonstrates format-independent conversions via JsonFormat In docs/reference/schema-evolution/as.md: - Added full polyglot cycle example (Config case) - Enhanced polyglot configuration use case with JSON I/O - Added bidirectional migration example with rollback support - Shows practical data flow for configuration management Examples now show: 1. Forward/reverse conversion operations 2. JSON encoding/decoding integration 3. Round-trip data preservation 4. Practical rollback and validation patterns Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs(schema-evolution): Simplify DynamicValue examples using mdoc evaluation Replaced verbose JsonFormat.encode/decode examples with clean mdoc evaluation: - Use _.toJsonString for JSON serialization - Rely on mdoc for evaluation instead of ShowExpr.show - Split setup and evaluation into separate code blocks - Cleaner, more idiomatic examples Updated both into.md and as.md DynamicValue conversion sections. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs(schema-evolution): Add reverse JSON → DynamicValue → Config example Enhanced "Bidirectional DynamicValue Support with JSON Round-Trip" section to show both directions: Forward: Config → DynamicValue → JSON - Uses _.toJsonString for serialization Reverse: JSON → DynamicValue → Config - Uses DynamicValue.fromJsonString to parse JSON - Uses As[Config, DynamicValue].from to deserialize to typed Config Demonstrates complete round-trip cycle with full type safety. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * fix: correct JSON parsing in As documentation example Use .fromJson[DynamicValue] extension method instead of non-existent DynamicValue.fromJsonString() to properly parse JSON strings in mdoc examples. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs(as): rewrite polyglot configuration example with realistic read-modify-write cycle Replace the incomplete example that only showed forward conversion (Config → DynamicValue) with a realistic scenario where a config service: 1. Reads JSON from external storage (Consul/etcd/file) → DynamicValue 2. Hydrates typed DatabaseConfig using As#from 3. Applies business logic (update timeout) 4. Writes back to store using As#into This demonstrates why As (bidirectional) is needed instead of just Into (one-way), showing the full read-modify-write cycle in a single for-comprehension. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs(as): expand polyglot configuration example with problem statement Clarify the real-world problem: configuration systems require reading from external storage, modifying in-place, and writing back. Without As, you need two separate conversions (Into[DynamicValue, Config] and Into[Config, DynamicValue]) with no guarantee they align. As solves this by guaranteeing a faithful round-trip via macro validation. Add step-by-step breakdown (read → hydrate → modify → serialize) to show why As is essential for mutable config pipelines. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs: restructure use cases with #### headings and update style guide - Update docs-writing-style to explicitly allow and encourage #### level headings - Add guidance on when to use #### for grouping related items (use cases, examples) - Restructure as.md Use Cases section to use #### for "Polyglot configuration systems" and "Schema-driven bidirectional migrations" - Add introductory sentence explaining when As is the right choice Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs(as): enrich schema-driven migrations section with motivation and rollback example Replace toy example with realistic database migration scenario: - Explain the gap: naive one-way Into doesn't support rollback - Add contrast: As for bidirectional/rollback migrations vs Into for permanent ones - Show realistic use case: user database schema upgrade with rollback capability - Demonstrate round-trip guarantee: PersonOld → PersonNew → PersonOld preserves data This clarifies when As is essential for safe, reversible schema evolution. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs(as): remove schema-driven bidirectional migrations section Remove the #### Schema-driven bidirectional migrations section and keep only the Polyglot configuration systems use case. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * remove: delete empty IntoDynamicValue example Remove the empty IntoDynamicValue.scala placeholder file that contains only an empty object definition. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Update docs/reference/schema-evolution/as.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix parsing of `java.time.Year` to parse similar to the latest JVMs + remove raw codecs for `java.time.Year`, `java.time.YearMonth`, `java.time.ZoneId`, and `java.time.ZoneOffset` because decoding/encoding by the latest JVMs performs better (zio#1167) * Preparing to migration on Scala 3.8.x (zio#1169) * docs: complete JsonPatch reference page and add cross-reference from Patch (zio#1161) * docs: add JsonPatch reference documentation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: rewrite JsonPatch reference page following skill structure - Add opening definition with structural type shape - Add Motivation section with ASCII diagram and hello-world example - Use #### headings for each method per skill guidelines - Add full Op hierarchy diagram with all subtypes - Add PatchMode section with comparison table - Add Operation Types section covering all Op/StringOp/ArrayOp/ObjectOp cases - Add Diffing Algorithm table - Add JsonPatch vs RFC 6902 comparison table - Add Advanced Usage examples (change log, composing sub-patches) - Use DynamicOptic.root.field(...).at(...) idioms throughout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add JsonPatch runnable examples and link from reference page - Step1DiffAndApply: diff/apply, extension methods, roundtrip guarantee - Step2ManualPatches: JsonPatch.root, path-based apply, empty - Step3PatchOperations: all Op types (Set, NumberDelta, StringEdit, ArrayEdit, ObjectEdit) - Step4CompositionAndModes: ++, PatchMode, toDynamicPatch, fromDynamicPatch - CompleteJsonPatchExample: collaborative editor with patch log, replay, and sync - Add Examples section to json-patch.md linking all five files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: fix compilation errors in CompleteJsonPatchExample - Explicitly type var doc as Json to accept patch.apply's return type - Use asObj() helper to cast Json → Json.Object before navigation - Fix contentSource extraction: JsonSelection#one returns Either, not Option - Fix foldLeft accumulators with explicit : Json type annotation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add explanatory comments to CompleteJsonPatchExample - Explain the append-only log design and its event-sourcing analogy - Explain why doc is typed as Json (patch.apply return type widening) - Explain why PatchMode.Strict is the default choice - Explain the ++ composition strategy and why publishPatch uses NumberDelta instead of a literal value (concurrent increment robustness) - Explain ArrayOp.Append safety (non-destructive) vs Insert/Delete - Explain why contentSource is extracted from live doc, not a snapshot - Explain foldLeft with JsonPatch.empty as the identity element - Explain each PatchMode behaviour (Strict/Lenient/Clobber) in context - Explain toDynamicPatch widening of NumberDelta to BigDecimalDelta - Add production serialization comment showing the typical codec workflow Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: update JsonPatch reference to use mdoc evaluated output and show() examples - Replace mdoc:compile-only blocks (with manual // result comments) with mdoc:silent:reset + mdoc pairs for live evaluated output throughout the doc - Fix bare subheader violations: add intro prose before the first ### in Creating Patches, Core Operations, Advanced Usage, and Integration sections - Fix lone subheader violations: merge #### ++ into ### Composing Patches and #### toDynamicPatch into ### Converting - Rename Step1–Step4 example files to scenario-based names and rewrite all println() calls as util.ShowExpr.show() for expression + result output Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: prefix every line of multi-line show() results with // Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * Update sourcecode to 0.4.4 (zio#1148) Co-authored-by: zio-scala-steward[bot] <145262613+zio-scala-steward[bot]@users.noreply.github.com> * Update zio-sbt-gh-query, zio-sbt-website to 0.5.0 (zio#1149) Co-authored-by: zio-scala-steward[bot] <145262613+zio-scala-steward[bot]@users.noreply.github.com> * Safe and correct (to match `java.time.*` value formatting) validation of predefined JSON schema formats + code cleanup (zio#1151) * More test coverage for XML codecs + tune visibility of private methods for Scala 2 (zio#1152) * Tune visibility for private methods in the chunk, schema and schema-thrift modules * More test coverage for XML codecs * feat(schema): add DynamicValue support to Into/As macros (zio#1007) * feat(schema): add DynamicValue support to Into/As macros - Into[A, DynamicValue] converts any type A to DynamicValue via Schema - Into[DynamicValue, A] converts DynamicValue to any type A via Schema - As[A, DynamicValue] provides bidirectional conversion - As[DynamicValue, A] provides bidirectional conversion - Schema[A] is summoned if available, otherwise derived - Added tests for DynamicValue conversions in IntoSpec and AsSpec Closes zio#981 * refactor(test): improve DynamicValue test assertion pattern Use assert(result)(isRight(equalTo(expected))) instead of assertTrue with manual field checking for clearer failure messages. * test(schema): add comprehensive DynamicValue tests for Into/As macros - Add tests for List, Map, Option, and sealed trait conversions - Replace failing Either tests with working sealed trait tests - Add ambiguity detection in Scala 3 findImplicitOrDeriveSchema * style(test): use assertTrue in DynamicValue tests per review feedback * fix(schema): detect ambiguous Schema implicits in Scala 2 DynamicValue macros Previously, findImplicitOrDeriveSchema in Scala 2 Into/As macros used inferImplicitValue(silent=true), which returns EmptyTree for both 'not found' and 'ambiguous' cases, silently ignoring ambiguity. Now uses a two-pass approach: first silent=true, then silent=false in a try/catch to distinguish ambiguous/diverging from genuinely absent. This matches the Scala 3 behavior which inspects failure.explanation. * Hardened a regex for email validation during checking JSON Schema conformance to avoid SSRF when routing emails directly to IP addresses (zio#1160) * Update sbt, sbt-dependency-tree, ... to 1.12.5 (zio#1159) Co-authored-by: zio-scala-steward[bot] <145262613+zio-scala-steward[bot]@users.noreply.github.com> * docs: refactor documentation skills and add BindingResolver + DynamicSchema reference pages (zio#1146) * feat(skills): add shared docs-mdoc-conventions skill * fix(skills): clarify mdoc:invisible guidance in docs-mdoc-conventions * feat(skills): add shared docs-writing-style skill * feat(skills): add shared docs-integrate skill * refactor(skills): write-data-type-ref delegates to shared doc skills Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(skills): write-how-to-guide delegates to shared doc skills Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(skills): add prose line-break and bullet capitalization rules to docs-writing-style Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: add BindingResolver reference page and examples Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: integrate BindingResolver page into site navigation and cross-references Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(skills): require type-qualified references for all methods and constructors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(binding-resolver): qualify all method and constructor references with their type name Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(binding-resolver): add schema registry example showing real-world rebinding use case Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(dynamic-schema): add DynamicSchema reference page and companion examples - Add docs/reference/dynamic-schema.md covering: opening definition with ASCII flow diagram, creation via toDynamicSchema/fromDynamicValue, serialization via toDynamicValue/fromDynamicValue, validation (check, conforms), rebinding, structural navigation via DynamicOptic, metadata access, toSchema, and integration cross-references - Add four runnable companion examples in schema-examples/dynamicschema/: validation, serialization round-trip, rebind pipeline, schema registry - Wire into sidebars.js (after dynamic-value), docs/index.md, and add See Also cross-references from dynamic-value.md and dynamic-optic.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(skills): require docs-writing-style as a mandatory sub-skill in write-data-type-ref Change the passive "See the docs-writing-style skill" reference to an active REQUIRED SUB-SKILL declaration, matching the convention used by other skills in the system. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(dynamic-schema): sync page with writing style rules - Capitalize all bullet sentences (holds/can → Holds/Can) - Add introductory prose after bare ## headings before first ### - Remove lone ### subheaders (Serializing, Rebinding, Structural Navigation, Converting) — content placed directly under ## - Add bridging sentences between consecutive code blocks in toDynamicValue, check, conforms, get, doc, and getDefaultValue sections Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(skills): require introductory sentences before code blocks to end with a colon Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(skills): ban hardcoded expression output comments in favour of mdoc evaluation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(dynamic-schema): expand "Converting to a Typed Schema" with motivation and use-cases Replace the thin toSchema section (signature + toy Slot example) with: - Opening sentence stating the return type and one-line when-to-use rule - Motivation paragraph naming the gap: post-transport scenarios where Scala types are unavailable, making rebind impractical - Explicit contrast: toSchema vs rebind[A] in prose - Bridging sentence before signature block - Realistic gateway example: receive DynamicSchema from registry, call toSchema, validate an incoming payload with fromDynamicValue Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(skills): add docs-enrich-section skill New skill for enriching thin documentation sections that show only a signature and a toy example without explaining motivation or when to prefer this API over alternatives. Covers: thin-section signals, source research checklist, five-part expansion pattern (opening → motivation → contrast → signature → realistic example), and a mistakes table with fixes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(skills): rename docs skills to use consistent docs-* prefix - write-data-type-ref → docs-data-type-ref - write-how-to-guide → docs-how-to-guide - finding-undocumented → docs-find-documentation-gaps Name field in each SKILL.md frontmatter updated to match. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(skills): clarify that fixing hardcoded output requires restructuring, not just deletion The previous rule said "never hardcode output in comments" but left the remedy ambiguous. Removing the comment from a compile-only block still hides the result — the correct fix is to restructure the block: 1. Move setup into mdoc:silent:reset 2. Add a bridging sentence ending in ':' 3. Put evaluated expressions in a bare mdoc block Adds explicit steps and a cross-reference to docs-mdoc-conventions. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs(dynamic-schema): apply mdoc:silent:reset + mdoc pattern to evaluated examples Converts all examples that previously showed hardcoded output comments (or had output stripped) to the proper two-block pattern: - mdoc:silent:reset — type definitions and setup vals - bare mdoc — expressions whose results are shown to the reader Sections converted: fromDynamicValue, toDynamicValue (Serializing), check (3 outcomes), conforms, rebind (decoded round-trip), get (streetSchema.map), typeId, doc, getDefaultValue, toSchema gateway. Also fixes remaining style violations: - adds ':' after Motivation paragraph before ASCII art block - removes step 3 ("compile all") from Running the Examples Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * docs: update docs-data-type-ref skill and sync dynamic-schema.md - Update docs-data-type-ref SKILL.md: add per-example source links to "Running the Examples" template - Each example now shows bold description, clickable source link, and separate bash block - Makes GitHub links clickable in Docusaurus (links in bash blocks are not clickable) - Update Rules section to document the new three-part structure - Sync dynamic-schema.md with skill requirements: - Fix hardcoded output in code block: replace mdoc:compile-only with proper mdoc:silent:reset + mdoc pattern - Update "Running the Examples" section to use per-example template with source links - All code blocks now properly evaluated and displayed per writing-style rules Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * style: apply scalafmt formatting Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * fix(docs): correct sidebars.js path and diagram notation - Update docs-integrate skill to reference correct path: docs/sidebars.js (was incorrectly referencing website/sidebars.js) - Fix ASCII diagram notation in dynamic-schema.md to use '.' for companion object methods (DynamicSchema.toDynamicValue) instead of '#' notation Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * fix(schema-examples): remove unused example and correct method reference - Remove empty MyExample.scala placeholder (unused, no implementation or docs) - Fix comment in BindingResolverSchemaRegistryExample.scala to correctly reference Schema[A]#toDynamicSchema instead of DynamicSchema#toDynamicSchema Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Update .claude/skills/docs-writing-style/SKILL.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update docs/reference/dynamic-schema.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix(pr-1146-review): address remaining review comments - Add trailing newline and closing separator to docs-writing-style skill for consistency - Restructure long run-on sentence in dynamic-schema.md toSchema section: split into two shorter sentences and move contrast into warning admonition - Refactor DynamicSchemaRegistryExample to use immutable patterns: replace var registry/queue with functions that take and return updated collections, adhering to the 'Prefer val over var' style rule Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * docs: add cross-reference from Patch to JsonPatch in Patching reference Add a note in the Patching page that directs readers to JsonPatch when they need untyped JSON-specific patching. This helps distinguish between Patch[S] (typed, schema-based) and JsonPatch (untyped, JSON-specific). Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * fix: format JsonPatch example files with scalafmt Format the 4 JsonPatch example files to comply with project style guidelines: - CompleteJsonPatchExample.scala - JsonPatchCompositionExample.scala - JsonPatchManualBuildExample.scala - JsonPatchOperationsExample.scala Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * Update schema-examples/src/main/scala/jsonpatch/JsonPatchCompositionExample.scala Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update schema-examples/src/main/scala/jsonpatch/CompleteJsonPatchExample.scala Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update schema-examples/src/main/scala/util/ShowExpr.scala Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: address review comments on example files - JsonPatchCompositionExample: Remove Scala 3-only 'as' import syntax for Scala 2.13 compatibility - JsonPatchCompositionExample: Use concrete Either[SchemaError, JsonPatch] instead of Either[_, JsonPatch] - JsonPatchCompositionExample: Add SchemaError import - CompleteJsonPatchExample: Explicitly handle patch application errors instead of silently falling back - ShowExpr: Minimize memory allocation by only loading lines up to the call site Addresses Copilot review comments for improved code quality and compatibility. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs: apply docs-writing-style rules to json-patch.md - Qualify bare method names with JsonPatch prefix (diff, root, apply, empty) - Add colons to intro sentences before code blocks (required by style guide) - Update docs-writing-style skill to reference docs-mdoc-conventions in description Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs: complete docs-writing-style updates for json-patch.md - Qualify all bare method references (diff → JsonPatch.diff, apply → JsonPatch#apply) - Add intro sentence before type signature code block - Add missing colon before Composing Patches code block Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs: fix all remaining docs-writing-style rule violations in json-patch.md - Add missing colons to 8 intro sentences before code blocks (lines 188, 394, 421, 429, 452, 489, 529, 569) - Qualify bare method names: empty → JsonPatch.empty, isEmpty → JsonPatch#isEmpty (lines 160, 174) All docs-writing-style rules now fully compliant. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: zio-scala-steward[bot] <145262613+zio-scala-steward[bot]@users.noreply.github.com> Co-authored-by: Andriy Plokhotnyuk <plokhotnyuk@gmail.com> Co-authored-by: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix zio#1166 by adding numeric widening support when converting from dynamic values (zio#1170) * Check Compliance Skill (zio#1174) * docs: integrate XML module reference into sidebar Add reference/xml to docs/sidebars.js in the Reference section after json-schema to make the XML documentation page accessible in the site navigation. PR zio#1016 includes comprehensive XML module documentation that was missing from the sidebar. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs: enhance XML module reference with comprehensive coverage of all PR zio#1016 features Add comprehensive documentation for all aspects of PR zio#1016: Major additions: - XmlEncoder and XmlDecoder traits with custom encoder/decoder examples - XmlBinaryCodec low-level codec interface and usage - Enhanced XmlError documentation with line/column position information - Real-world examples: RSS feed parsing, Atom feed, Sitemap XML - Implementation details section covering zero dependencies - Cross-Scala (2.13, 3.x) compatibility notes - Performance characteristics (time/space complexity) - Comparison table with Java XML libraries (JAXB, DOM4j) Sections now include: - Overview, Installation, Basic Usage - XML AST with node types - XmlBuilder for programmatic construction - WriterConfig and ReaderConfig with tables - @xmlAttribute and @xmlNamespace annotations - XmlSelection with navigation, filtering, and combinators - XmlPatch with position options and composition - XmlEncoder/XmlDecoder with implicit derivation and combinators - Extension syntax (.toXml, .fromXml) - Printing XML with various configurations - Type testing and access patterns - Comprehensive supported types list - XmlBinaryCodec usage examples - Error handling and XmlError details - Cross-platform (JVM/Scala.js) support - Multiple real-world examples - Implementation approach and performance analysis - Comparison with alternatives This ensures all features, APIs, and patterns from PR zio#1016 are thoroughly documented and discoverable by users. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs(xml): fix encoding examples to use mdoc instead of manual output comments Split the encoding example into setup block with mdoc:silent and separate mdoc blocks for each encoding operation. This follows the convention of never manually writing output comments when mdoc can show real evaluated output. * docs(xml): fix attributes example to use mdoc instead of manual output comments Split the attributes example into setup block with mdoc:silent and separate mdoc block to show the encoding result. Removes manually written output comment. * docs(xml): fix namespace examples to use mdoc instead of manual output comments Split both namespace examples (with and without prefix) into setup blocks with mdoc:silent/mdoc:silent:nest and separate mdoc blocks for encoding. Uses mdoc:silent:nest for the second example since it redefines Feed. * docs(xml): fix printing example to use mdoc instead of manual output comments Split the printing example into setup block with mdoc:silent and separate mdoc blocks for compact and pretty-printed output. Removes manually written output comments from the compile-only block. * docs(xml): fix Decoding from XML to use mdoc:silent:nest when redefining Person * docs(xml): fix Attributes to use mdoc:silent:nest when redefining Person * docs(xml): fix Namespaces to use mdoc:silent:nest when redefining Feed * docs(xml): fix XmlDecoder to use mdoc:silent:nest when redefining Person * docs(xml): fix missing colon before code block in Installation section * docs(xml): fix heading hierarchy in Printing XML section * docs(xml): fix heading hierarchy in Error Handling section * feat: add docs-check-compliance skill for flexible documentation auditing - Accepts two arguments: doc file and rule skill name - Loads rule skill dynamically - Checks and fixes each rule with separate commits - Verifies compilation with 'sbt docs/mdoc' - Reusable across any rule skill and documentation file Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs(xml): fix Navigation section to use mdoc:silent:nest when redefining xml * docs(xml): fix remaining mdoc violations for compilation - Add missing Chunk import to custom decoders section - Fix Message round-trip example with syntax extension import - Fix xmlStr variable rename in Complete Example section - Fix XmlBinaryCodec derivation method call - Simplify XmlError example to work with actual API * Update .claude/skills/docs-check-compliance/SKILL.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * chore: remove settings.local.json from repository - Remove tracked .claude/settings.local.json to avoid weakening sandboxing - Add to .gitignore to prevent future commits - Users can create their own settings.local.json if needed locally Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com> * docs(xml): add Opening Definition section with type signature [docs-data-type-ref compliance] * docs: clarify Opening Definition section should not have explicit heading * docs(xml): linter formatting adjustments --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * docs(structural-types): fix type reference notation [referencing types rule] * docs(structural-types): fix Schema reference notation in Binding.of section [referencing types rule] * docs(structural-types): add prose before Supported Conversions subheader [bare subheader rule] * docs(structural-types): add prose before Integration subheader [bare subheader rule] * fix(skills): restore argument-hint and allowed-tools to docs-document-pr skill * fix: remove unused structural schema variables from sum type examples Remove unused structuralSchema, colorStructural, statusStructural, and fruitStructural variables that trigger -Wunused:all warnings in Scala 3. * fix: clarify that example creates nominal Person, not anonymous structural value * fix: remove misleading Into macro reference from integration example The example demonstrates DynamicValue manipulation and cross-type interop, not schema evolution with the Into macro. Update header and section title to reflect actual functionality. * docs(structural-types): clarify nested products keep nominal types Reword to avoid implying recursive structuralization that doesn't happen. Nested fields retain their nominal types; only the outer product is structuralized. * refactor: use show() to display structural schema representations Instead of computing unused structural schema variables, use ShowExpr.show() to print their evaluation. This demonstrates to users what the structural schema looks like for each sum type variant (Shape, Color, Status, Fruit). * style: format with scalafmt * docs(structural-types): workaround Scala 3.7.4 compiler crash in mdoc Convert code blocks from `mdoc:compile-only` to plain `scala` to work around a Scala 3.7.4 compiler crash (erasure phase) triggered by structural type syntax. TEMPORARY WORKAROUND: Code examples in this file are NOT compiled/type-checked until Scala 3.8.x is adopted (see PR zio#1169). When Scala 3.8.x becomes the default: 1. Revert mdoc:compile-only modifiers 2. Re-enable compilation checks with `sbt docs/mdoc` 3. Delete the blocking issue comment Fixes: CI failures in docs/mdoc task Related: PR zio#1169 "Preparing to migration on Scala 3.8.x" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com> Co-authored-by: Andriy Plokhotnyuk <plokhotnyuk@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: zio-scala-steward[bot] <145262613+zio-scala-steward[bot]@users.noreply.github.com> Co-authored-by: Nabil Abdel-Hafeez <7283535+987Nabil@users.noreply.github.com>
…test for issue zio#1145 (zio#1182) Add c.enclosingImplicits fallback in the Scala 2 whitebox macro so that A and S are resolved from the implicit search's expected type when c.macroApplication.tpe is null or unresolved. Add Issue1145Reproducer — a top-level object with import Allows._ matching the reporter's exact code — as a regression guard.
Add mandatory lint checks (sbt fmt + sbt check) to documentation skills that create Scala example files: - docs-data-type-ref: lint step between Step 3 (Write Examples) and Step 5 (Integrate) - docs-how-to-guide: lint step 4f after example compilation - docs-document-pr: Phase 6 for verification after documentation generation This prevents CI failures due to unformatted Scala files in schema-examples/. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…d files - Add 'git add' step before 'sbt fmtChanged' in all three documentation skills - Ensures newly created (untracked) example files are properly linted - Resolves issue where untracked files were missed by git diff-based filtering - Applies to: docs-data-type-ref, docs-how-to-guide, docs-document-pr skills Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
… runMain hint Address Copilot review comment: The RDBMS and DocumentStore examples are compile-only demonstrations of Allows constraints, not runnable Apps. Remove runMain commands and add explicit '(compile-only)' labels. Update section text to clarify these examples show compile-time validation patterns. This prevents user confusion about why sbt runMain would fail on files that don't extend App. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Address three related Copilot review comments: 1. Fix resource leak: Wrap Source.fromFile() with Using.resource to ensure file handles are reliably closed in all code paths, including when slicing specific line ranges. 2. Narrow exception handling: Replace overly broad 'catch Throwable' with 'catch NonFatal' to avoid silently hiding unexpected failures like InterruptedException or VirtualMachineError. 3. Optimize file reads: Read the entire file once into a Vector at the start, then slice multiple line ranges from the in-memory copy. Previously, the file was unnecessarily re-opened and fully read for each (from, to) range. Combined, these changes eliminate file handle leaks, improve error visibility, and reduce I/O overhead for multi-range operations. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Resolved merge conflict in docs-data-type-ref SKILL.md where Step 6 (Review and Verify Compilation) was renamed to Step 5 in main. Kept our numbering since we intentionally added Step 4 (Lint Check with fmtChanged), shifting subsequent steps to 5-6. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Use 4 backticks for outer mdx fence to properly contain inner scala fences
| val javaPath = java.nio.file.Paths.get(path) | ||
| val fileExtension = | ||
| javaPath.getFileName.toString | ||
| .split('.') | ||
| .lastOption | ||
| .getOrElse("") |
There was a problem hiding this comment.
fileExtension uses .split('.'), but String.split takes a regex where . matches any character. This will typically produce an empty/incorrect extension (so embedded fences won’t get the expected language like scala). Use a literal-dot split (e.g., split("\\.")) or lastIndexOf('.')/substring to extract the extension safely.
| val javaPath = java.nio.file.Paths.get(path) | |
| val fileExtension = | |
| javaPath.getFileName.toString | |
| .split('.') | |
| .lastOption | |
| .getOrElse("") | |
| val javaPath = java.nio.file.Paths.get(path) | |
| val fileName = javaPath.getFileName.toString | |
| val lastDotIndex = fileName.lastIndexOf('.') | |
| val fileExtension = | |
| if (lastDotIndex >= 0 && lastDotIndex < fileName.length - 1) | |
| fileName.substring(lastDotIndex + 1) | |
| else | |
| "" |
| object SourceFile { | ||
|
|
||
| def read(path: String, lines: Seq[(Int, Int)]): String = { | ||
| def openSource(path: String): Source = | ||
| try { | ||
| Source.fromFile("../" + path) | ||
| } catch { | ||
| case NonFatal(_) => Source.fromFile(path) | ||
| } | ||
|
|
There was a problem hiding this comment.
SourceFile is a new public utility in src/main/scala, but it currently has no Scaladoc. Please add Scaladoc for the object and its public methods (read, fileExtension, print), documenting parameters (especially the lines ranges being 1-indexed/inclusive) and expected output format, since this is intended for reuse from mdoc sessions.
| | `Self` | Recursive self-reference back to the entire enclosing `Allows[A, S]` grammar | | ||
| | `Dynamic` | `DynamicValue` — the schema-less escape hatch | | ||
| | `IsType[A]` | Exact nominal type match: satisfied only when the checked type is exactly `A` (`=:=`) | | ||
| | `` `\|` `` | Union of two grammar nodes: `A \| B`. In Scala 2 write `` A `\|` B `` in infix position. | |
There was a problem hiding this comment.
In the grammar table, the union node is shown as `\|` and described with A \| B. \| isn’t valid Scala syntax; the Allows union is written as A | B (Scala 3 native unions; Scala 2 infix type | from Allows). Please adjust this row to display | / A | B (escape the pipe for the Markdown table without changing the visible syntax).
| | `` `\|` `` | Union of two grammar nodes: `A \| B`. In Scala 2 write `` A `\|` B `` in infix position. | | |
| | \| | Union of two grammar nodes: `A | B`. In Scala 2 write `A | B` in infix position. | |
| | | | | ||
| | `Record[A]` | A case class / product type whose every field satisfies `A`. Vacuously true for zero-field records. Sealed traits and enums are **automatically unwrapped**: each case is checked individually, so no `Variant` node is needed. | | ||
| | `Sequence[A]` | Any collection (`List`, `Vector`, `Set`, `Array`, `Chunk`, …) whose element type satisfies `A` | | ||
| | `Sequence.List[A]` | `scala.collection.immutable.List` only, element type satisfies `A` | | ||
| | `Sequence.Vector[A]` | `scala.collection.immutable.Vector` only, element type satisfies `A` | | ||
| | `Sequence.Set[A]` | `scala.collection.immutable.Set` only, element type satisfies `A` | | ||
| | `Sequence.Array[A]` | `scala.Array` only, element type satisfies `A` | | ||
| | `Sequence.Chunk[A]` | `zio.blocks.chunk.Chunk` only, element type satisfies `A` | | ||
| | `IsType[A]` | Exact nominal type match: satisfied only when the checked type is exactly `A` (`=:=`) | | ||
| | `Map[K, V]` | `Map`, `HashMap`, … whose key satisfies `K` and value satisfies `V` | | ||
| | `Optional[A]` | `Option[X]` where the inner type `X` satisfies `A` | | ||
| | `Wrapped[A]` | A ZIO Prelude `Newtype`/`Subtype` wrapper whose underlying type satisfies `A` | | ||
| | `Dynamic` | `DynamicValue` — the schema-less escape hatch | | ||
| | | | |
There was a problem hiding this comment.
The empty table rows (| | |) inside the Grammar Nodes table render as blank entries and look accidental. If you want visual grouping, consider removing these rows and using prose/heading breaks outside the table instead.
Summary
Appexamples inschema-examples/covering Allows doc scenarios that lacked examples: CSV flat records, event bus with sealed trait auto-unwrap, GraphQL/tree structures with Self recursion, and sealed trait auto-unwrap with nested hierarchiesSourceFileutility (package docs) for embedding example source files in documentation viamdoc:passthroughallows.mdwith "Running the Examples" section that embeds all 6 example files usingSourceFile.printdocs-data-type-refskill withSourceFile.printconvention and correct import patternTest plan
sbt "schema-examples/compile"passessbt "schema-examples/runMain ..."sbt "docs/mdoc"compiles with 0 errors🤖 Generated with Claude Code