+- **Cross-port `<Name>Extractor` codegen** (shipped 2026-05-31, TS / Python / C# / Kotlin — capability parity with Java). A generated `<Name>Extractor` per `template.output` adds an **`extract` tier** over the existing recover: `extract` returns the port's **idiomatic strict typed payload** (TS inferred type, Python Pydantic model, C# `record`, Kotlin `data class`) and throws on lost-required; `recover` (never-throws, all-nullable mirror) is re-exposed. It reuses each port's existing nested-capable runtime-delegating recover and a generated recursive mirror→strict mapper (nested objects + arrays-of-objects, one-shot construct), with **no registry / binding / factory** (codegen knows the type graph statically) and **no new flavored object-class generation** (constructs each port's existing idiomatic types). Compile-and-run gated per port (incl. non-string scalar arrays). Surfaced + fixed a latent cross-port scalar-array recover bug (JVM `DataConverter` array conversions were dead/throwing; `MetaObjectRecover`/C# recover emitted scalar arrays as non-arrays). **Idiom divergence (intentional):** TS/Python honor `@required` optionality in the strict payload; C#/Kotlin payloads are all-`required` (no optional-absent modeling) — extract works into each port's existing payload shape. The cross-port `recover → extract` rename (#87) now sweeps all 5 ports together next. Designed in `docs/superpowers/specs/2026-05-31-cross-port-extractor-codegen-design.md`.
0 commit comments