External foundations (RC6) + Unified Types (Bridge) + DSL/CLI rework + site overhaul#189
Merged
oyvindberg merged 8 commits intomainfrom May 3, 2026
Merged
External foundations (RC6) + Unified Types (Bridge) + DSL/CLI rework + site overhaul#189oyvindberg merged 8 commits intomainfrom
oyvindberg merged 8 commits intomainfrom
Conversation
… & build overhaul
A single chunk of work that pulls in many layers at once. Each piece
forced the next, so they ended up squashed into one commit. The pieces:
------------------------------------------------------------------------
1. foundations becomes an external published artifact (RC6)
------------------------------------------------------------------------
`foundations-jdbc` and its dsl/hikari/scala/kotlin wrappers used to be
in-repo bleep projects. They're now published as
`dev.typr.foundations:foundations-jdbc{,-kotlin,-scala_3,-hikari}:1.0.0-RC6-SNAPSHOT`,
and the in-repo modules are deleted. This is the kernel that everything
else hangs off.
Foundations itself reshaped on the way out:
- `Connection` (writable) is split from `ConnectionRead` (read-only).
- `Operation` and `OperationRead` form a sealed hierarchy.
`OperationRead` declares `run(ConnectionRead)` and overrides
`run(Connection)` so Scala 3's overload resolver picks the
most-specific candidate without ambiguity.
- Kotlin wrapper exposes `Bijection.of` publicly and exposes
`Connection.javaConnection` (was `internal`) so typr-dsl-kotlin
can unwrap when delegating.
------------------------------------------------------------------------
2. Codegen rewrite (DbLibFoundations + adapters)
------------------------------------------------------------------------
`DbLibFoundations.scala` (~2400 LOC) is rewritten around the
Connection/ConnectionRead split:
- Read methods: `(using c: ConnectionRead)`; write methods:
`(using c: Connection)`.
- A single `runOn(connParam)` helper emits `.run(using c)` for
Scala / `.run(c)` for Java/Kotlin via `jvm.ApplyNullary`.
- `dbTypeArray` now generated as `pgType.array()` (PG) or
`duckDbType.list()` (DuckDB) — the inner Bijection is reused
instead of duplicated. `pgType` is emitted before `pgTypeArray`
to satisfy Java's static-field forward-reference rule.
Six new adapters replace inline dialect logic:
`PostgresAdapter`, `OracleAdapter`, `MariaDbAdapter`, `DuckDbAdapter`,
`SqlServerAdapter`, `Db2Adapter` (~250–350 LOC each). They centralise
quoting, type casting, null-safe equality (`IS NOT DISTINCT FROM`,
`<=>`, `IS b`), and pagination clauses.
`db.scala` (~530 LOC) defines the typed model of every DB column type:
`PgType`, `MariaType`, `OracleType`, `DuckDbType`, `SqlServerType`,
`Db2Type`, with composite/array/enum subtypes.
`FilePreciseType` (~2200 LOC) and `FilePgCompositeType` (~250 LOC)
handle precise-type and composite rendering.
------------------------------------------------------------------------
3. Unified Types / Bridge — the headline feature
------------------------------------------------------------------------
New `typr/src/scala/typr/bridge/` tree introduces the domain model:
Model:
DomainTypeDefinition, DomainField, PrimarySource, AlignedSource,
FieldOverride (Forward / Drop / MergeFrom / SplitFrom /
ComputedFrom / Enrichment), TypePolicy (Exact / AllowWidening /
AllowNarrowing / AllowPrecisionLoss / AllowTruncation /
AllowNullableToRequired), CompatibilityMode (Exact / Superset /
Subset).
Validation:
FlowValidator, TypePolicyValidator, SmartDefaults.
Public API:
BridgeApi.{check, resolveFlows} — check validates declarations
against actual source entities; resolveFlows produces field-level
mappings.
Inference:
ColumnTokenizer, ColumnStemmer, ColumnGrouper, TypeSuggester,
CompositeTypeSuggester. Used to suggest domain types from column
naming patterns across sources.
Codegen:
FileBridgeCompositeType (record + JSON codecs),
FileBridgeProjectionMapper (`fromXxx` / `toXxx` mapper methods for
every aligned source).
Adapters:
BridgeAvroAdapter and BridgeProtoAdapter translate
ComputedAvroRecord / proto messages into Bridge's `ExternalRecord`
so domain types align across DB rows, OpenAPI models, Avro
records, and gRPC messages alike.
Tests at `tests/src/scala/typr/bridge/` (~67 cases / 1k LOC):
FlowValidatorTest, SmartDefaultsTest, TypePolicyValidatorTest,
TypeNarrowerIntegrationTest.
------------------------------------------------------------------------
4. typr DSL renamed and expanded
------------------------------------------------------------------------
`foundations-jdbc-dsl{,-scala,-kotlin}` → `typr-dsl{,-scala,-kotlin}`,
significantly expanded:
Java core (~3.5k LOC):
Dialect.java (~860 LOC) — unified dialect interface with
null-safe operators, per-dialect pagination, composite-type
support.
SelectBuilder, DeleteBuilder, UpdateBuilder, GroupedBuilder,
SqlExpr, RenderCtx, GenericDbTypes, RowCodecDbType.
Scala wrapper (~1.5k LOC) and Kotlin wrapper (~1k LOC) shipped as
separate published artifacts.
------------------------------------------------------------------------
5. CLI tool reshape
------------------------------------------------------------------------
`typr/src/scala/typr/cli/` is rewritten. `Main.scala` exposes:
- `generate` — two-phase parallel pipeline across six boundary
kinds (Database, DuckDB, OpenAPI, JSON Schema, Avro, gRPC) with
a per-output progress tracker.
- `watch` — re-runs Generate on schema/SQL changes.
- `check` — validates that domain types align across configured
sources via BridgeApi.
`TyprConfig` (circe-driven) accepts both legacy `boundaries:` and new
`sources:` keys, loads `types:` for Bridge domain types, and supports
`${ENV_VAR}` substitution.
New helpers:
ConfigParser, ConfigToOptions, ConfigWriter, EnvSubstitution,
PatternMatcher (glob → typr.Selector), SourceEntityLoader,
ProjectionFieldFormat.
------------------------------------------------------------------------
6. Boundary expansion: OpenAPI, Avro, gRPC
------------------------------------------------------------------------
OpenAPI gets a full parser/computed/codegen split:
Parser layer: OpenApiParser, ModelExtractor, TypeResolver,
SpecValidator.
Computed layer: ComputedApiService, ComputedEndpoint, ComputedModel,
ComputedParameter, ComputedProperty.
Codegen layer: OpenApiCodegen, ModelCodegen, ApiCodegen.
JSON Schema added alongside: JsonSchemaParser, JsonSchemaCodegen.
Avro gets a parallel computed-types layer
(ComputedAvroRecord, ComputedAvroField, ComputedProtocol,
ComputedEventGroup) and Cats integration (KafkaFrameworkCats).
gRPC gets ComputedGrpcMethod / ComputedGrpcService and
GrpcFrameworkCats.
A new `boundaries/` framework abstraction replaces ad-hoc per-framework
branching: Framework (base) → HttpFramework / MessagingFramework /
RpcFramework → SpringFramework / QuarkusFramework / CatsFramework.
------------------------------------------------------------------------
7. Build tool migration: Gradle → Bleep (Kotlin side)
------------------------------------------------------------------------
The whole Kotlin side switched build tools. All
`build.gradle.kts` / `settings.gradle.kts` / `gradle/` infra deleted.
Kotlin projects fold into `bleep.yaml` via:
- template-kotlin (kotlin 2.3.0, jvmTarget 21)
- template-kotlin-db-tester (per-DB tester scaffold)
Every Kotlin tester (db2 / duckdb / mariadb / oracle / pg / sqlserver /
combined) is now a few lines in bleep.yaml instead of a Gradle
subproject. Single-tool monorepo, one project list, one compile graph
across Java/Kotlin/Scala/Scala-2.13 cross-builds.
------------------------------------------------------------------------
8. Build / dep churn
------------------------------------------------------------------------
Bleep config: 0.0.14 → 1.0.0-M3
Scala 3: 3.7.3 → 3.8.3
Kotlin: 2.3.0 (new templates, jvmTarget 21)
JVM: GraalVM 25.0.0
Scala 2.13: unchanged at 2.13.16
New deps for events / reactive frameworks:
io.confluent:kafka-avro-serializer:7.8.0
org.apache.kafka:kafka-clients:3.9.0
org.apache.avro:avro:1.12.0
io.smallrye.reactive:mutiny:2.6.1
io.smallrye.reactive:mutiny-zero-flow-adapters:1.0.0
jakarta.validation:jakarta.validation-api:3.0.2
jakarta.ws.rs:jakarta.ws.rs-api:3.1.0
Test framework migrated:
com.novocode:junit-interface:0.11 → com.github.sbt:junit-interface:0.13.3
------------------------------------------------------------------------
9. Documentation site revamp
------------------------------------------------------------------------
The site is rebuilt around the new "every boundary, unified" narrative.
docusaurus.config.js collapses to a single `/typr/` route served from
site/docs-typr/. The legacy site/docs/ tree and its three sidebars
(sidebars-{api,db,jdbc}.js) are unhooked.
75 newly-written pages in site/docs-typr/:
- Unified Types: overview, domain-types, field-types, configuration
- Databases: setup, type-safety (id-types, precise-types, type-flow,
enums/open-enums, domains, struct/collection/array/maps,
date-time, defaulted-types, user-selected-types), customization,
patterns, advanced features, testing
- REST APIs: overview, type-safe-ids, response-types, server-frameworks,
client-generation, usage
- Events (Avro/Kafka): setup, schemas, wire-formats, effect-types,
Kafka producers/consumers/headers/multi-event, type-safety
(wrappers/precise/unions), Kafka RPC (Spring/Quarkus), reference
Sidebar: sidebars-typr.js (~200 LOC, 68 doc entries grouped by boundary).
Landing page (site/src/pages/index.js) replaced wholesale (+1069 LOC):
problem→solution narrative, side-by-side "without/with Typr" code
panels, a domain-type config preview, a precision section, a
boundaries section, a stack selector, a final CTA.
New React components: BoundaryDiagram, CodeSample, ShowcaseSnippet,
StackSelector, UsageExample, TypoLogo.
Showcase pipeline (site/scripts/extract-snippets.js + the
generate-showcase bleep script + site/showcase-generated/) lets docs
reference real generated code by stable markers, so doc snippets stay
in sync with what the generator actually produces.
Cross-language site/usage-examples/ (Java/Kotlin/Scala) hosts
runnable examples shown inline in docs.
------------------------------------------------------------------------
10. Tester sweeps & misc
------------------------------------------------------------------------
- oracle/scala uses summon[Connection] in tests after the
context-function conversion of withConnection helpers.
- sqlserver tests use compareToIgnoreCase to match SQL Server's
SQL_Latin1_General_CP1_CI_AS collation when assertions iterate
over data leaked from concurrent tests under READ_UNCOMMITTED.
- Per-test-class distinct Random seeds (hashed file paths → 31-bit)
to dodge MariaDB deadlocks from shared-seed parallel tests.
- .javafmt.conf added at repo root to skip
**/generated-and-checked-in/** from Java formatting.
- testers/combined/{java,kotlin} added — bundle Avro+Kafka+Mutiny+REST
in one tester to exercise cross-boundary type unification.
- New per-DB Kotlin testers (testers/{db2,duckdb,mariadb}/kotlin) under
template-kotlin-db-tester.
------------------------------------------------------------------------
Why one commit: every layer touches every other. The foundations split
forces the codegen rewrite, the codegen rewrite enables the Connection/
ConnectionRead split, that split surfaces in every generated repo
across every tester, the Bridge work needs new computed-type layers in
OpenAPI/Avro/gRPC and new file generators in codegen, the new boundary
types need Kafka/Avro/Mutiny deps, the new deps need bleep/Scala/Kotlin
bumps, the Gradle→Bleep migration came in along the way, and the site
is rewritten to document the unified result. Splitting cleanly was not
practical.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reworks site/src/pages/index.js and index.module.css end-to-end so the landing reads like a typesetter's specimen sheet meeting a structural engineer's blueprint — cream paper, deep ink, single vermillion register, hairline rules everywhere. Stands apart from the dark-mode-with-blue- accent SaaS pattern most JVM tooling defaults to. Type stack: - Fraunces (variable serif, dramatic optical sizing) — display - Bricolage Grotesque (variable grotesque) — body - JetBrains Mono — code & metadata Sections (no § numbering): - Hero with masthead, doc/rev/scope marginalia, type-spec spec sheet - "Every system bug starts at a boundary" — manifesto + the schematic diagram (see below) - Same bug, twice — code comparison on dark feature surface - Guardrails — 4-card grid (junior/contractor/AI/lead) - Precision specifications — DB and OpenAPI spec-sheet tables - Boundaries — numbered editorial entries (DB / API / events / gRPC) - Unified Types — feature spotlight with YAML config - Compatibility — stack table - Begin — colophon CTA with set-in / license / repo metadata Manifesto diagram is a real drafting-table schematic: the canonical Customer card with field rows on the left, four boundary stations stacked on the right (each with policy chip — anchor / exact / superset / subset — and a code preview), orthogonal connection lines fanning between domain fields and boundaries, dimensional callouts, edge coordinate marks (01-08 across, A-E down), corner register crosshairs, a real title block (DRAWING NO. / REVISION / SCALE / SHEET), a legend, and a vermillion flow dot animating along the primary anchor line. Theme-aware tokens: - Regular surfaces flip with theme (cream <-> dark navy paper). - Feature surfaces (.sectionDark / .sectionFeature / .specCallout) never flip — softer warm slate (#1d2944) in light mode, slightly elevated indigo (#161c30) in dark mode. New --feature-bg / --feature-fg / --feature-border / --feature-faint tokens replace the brittle var(--ink)/var(--paper) inversions that produced cream-on-cream in dark mode and aggressive-near-black in light. - Diagram fills use --paper / --vermillion (the actual variable names, not the broken --typr-paper / --typr-vermillion fallbacks). TypoLogo restored to the original purple-gradient blob. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Layers ~370 lines of editorial overrides on top of the existing custom.css so the docs match the landing — same Fraunces serif headings, Bricolage Grotesque body, JetBrains Mono labels & code, cream-paper / deep-ink / vermillion palette across both light and dark modes. - Fraunces with per-heading opsz axis (h1 144 → h4 36); italics get the soft axis treatment in vermillion - All Infima/Docusaurus tokens (--ifm-color-primary, background, content, link, navbar, footer, table, code, menu, blockquote, toc, etc.) repointed at the editorial palette - Site-wide paper grain via body::before - Sidebar: active link gets a vermillion left bar (no pill); category labels in mono small-caps - TOC, breadcrumbs, tabs, pagination sub-labels: mono small-caps - Tables: ink-band header, hairline borders, no shadow/radius - Code blocks: offset hairline shadow (matches landing figures) - Buttons: editorial flat with offset shadow on hover - HRs become hairlines; blockquotes become vermillion serif italics - Dark-mode override flips the palette but keeps vermillion accent - Footer: 4px double-rule top border, mono titles Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- bleep fmt: ConfigRoundtripTest.scala
- Remove the 6 'Run foundations-jdbc {DB} tests' workflow steps —
foundations-jdbc-test moved to the external foundations repo.
- Drop mdoc / DocusaurusPlugin pipeline. Docs site no longer needs
pre-processing; site/docs-typr/ is markdown that Docusaurus serves
directly. Removed:
- typr-scripts-doc/ (only file was GenDocumentation.scala)
- site-in/ (mdoc input tree, unused)
- bleep.yaml: typr-scripts-doc project + generate-docs script
- .github/workflows/build.yml build-docs job: now just
'npm ci && npm run build' in site/
- .github/workflows/deploy-docs.yml: same simplification
- CLAUDE.md: updated build-docs instructions
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
site/src/data/showcaseFiles.js uses webpack require.context against site/showcase-generated/, which is gitignored. Without the GeneratedShowcase script running first, webpack can't resolve the module and the build fails. The script is self-contained — no DB connections needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
This PR is one tightly-coupled chunk of work — every layer touches every other, so it didn't split cleanly. The pieces:
1. foundations becomes external (RC6)
foundations-jdbc{,-dsl,-hikari,-scala,-kotlin}were in-repo bleep projects. They're now published asdev.typr.foundations:*:1.0.0-RC6and the in-repo modules are deleted. Foundations itself reshaped on the way out:Connection(writable) split fromConnectionRead(read-only).Operation/OperationReadhierarchy.OperationReaddeclaresrun(ConnectionRead)and overridesrun(Connection)so Scala 3's overload resolver picks the most-specific candidate without ambiguity.Bijection.ofpublicly and exposesConnection.javaConnectionsotypr-dsl-kotlincan unwrap when delegating.2. Codegen rewrite
DbLibFoundations.scala(~2400 LOC) rebuilt around the Connection split:(using c: ConnectionRead); write methods take(using c: Connection).runOn(connParam)helper emits.run(using c)(Scala) or.run(c)(Java/Kotlin) viajvm.ApplyNullary.dbTypeArraynow generated aspgType.array()(PG) /duckDbType.list()(DuckDB) — the inner Bijection is reused rather than duplicated.pgTypeemitted beforepgTypeArrayto satisfy Java's static-field forward-reference rule.Six new database adapters replace inline dialect logic:
PostgresAdapter,OracleAdapter,MariaDbAdapter,DuckDbAdapter,SqlServerAdapter,Db2Adapter— each ~250–350 LOC, centralising quoting, type casting, null-safe equality (IS NOT DISTINCT FROM,<=>,IS b), and pagination.db.scala(~530 LOC) defines a typed model of every DB column type.FilePreciseType(~2200 LOC) andFilePgCompositeType(~250 LOC) handle precise-type and composite-type rendering.3. Unified Types / Bridge — headline feature
New
typr/src/scala/typr/bridge/tree introduces the domain model:DomainTypeDefinition,DomainField,PrimarySource,AlignedSource,FieldOverride(Forward / Drop / MergeFrom / SplitFrom / ComputedFrom / Enrichment),TypePolicy(Exact / AllowWidening / AllowNarrowing / AllowPrecisionLoss / AllowTruncation / AllowNullableToRequired),CompatibilityMode(Exact / Superset / Subset).FlowValidator,TypePolicyValidator,SmartDefaults.BridgeApi.{check, resolveFlows}.ColumnTokenizer,ColumnStemmer,ColumnGrouper,TypeSuggester,CompositeTypeSuggester. Suggests domain types from column naming patterns across sources.FileBridgeCompositeType(record + JSON codecs),FileBridgeProjectionMapper(fromXxx/toXxxmappers per aligned source).BridgeAvroAdapter,BridgeProtoAdaptertranslateComputedAvroRecord/ proto messages into Bridge'sExternalRecordso domain types align across DB rows, OpenAPI models, Avro records, and gRPC messages alike.Tests at
tests/src/scala/typr/bridge/(~67 cases / 1k LOC):FlowValidatorTest,SmartDefaultsTest,TypePolicyValidatorTest,TypeNarrowerIntegrationTest.4. typr DSL renamed and expanded
foundations-jdbc-dsl{,-scala,-kotlin}→typr-dsl{,-scala,-kotlin}, significantly expanded.Dialect.java(~860 LOC) with unified null-safe operators, per-dialect pagination, composite-type support;SelectBuilder,DeleteBuilder,UpdateBuilder,GroupedBuilder,SqlExpr,RenderCtx,GenericDbTypes,RowCodecDbType.5. CLI tool
typr/src/scala/typr/cli/rewritten.Main.scalaexposes:generate— two-phase parallel pipeline across six boundary kinds (Database, DuckDB, OpenAPI, JSON Schema, Avro, gRPC) with a per-output progress tracker.watch— re-runs Generate on schema/SQL changes.check— validates that domain types align across configured sources viaBridgeApi.TyprConfig(circe-driven) accepts both legacyboundaries:and newsources:keys, loadstypes:for Bridge domain types, and supports${ENV_VAR}substitution.New helpers:
ConfigParser,ConfigToOptions,ConfigWriter,EnvSubstitution,PatternMatcher(glob →typr.Selector),SourceEntityLoader,ProjectionFieldFormat.6. Boundary expansion: OpenAPI, Avro, gRPC
OpenAPI: full parser/computed/codegen split —
OpenApiParser,ModelExtractor,TypeResolver,SpecValidator→ computedApiService/Endpoint/Model/Parameter/Property→OpenApiCodegen/ModelCodegen/ApiCodegen. JSON Schema added alongside (JsonSchemaParser,JsonSchemaCodegen).Avro: parallel computed-types layer (
ComputedAvroRecord,ComputedAvroField,ComputedProtocol,ComputedEventGroup) plusKafkaFrameworkCatsfor Cats Effect.gRPC:
ComputedGrpcMethod,ComputedGrpcService,GrpcFrameworkCats.New
boundaries/framework abstraction replaces ad-hoc per-framework branching:Framework→HttpFramework/MessagingFramework/RpcFramework→SpringFramework/QuarkusFramework/CatsFramework.7. Build tool: Gradle → Bleep
Rewrote the Kotlin build from Gradle to Bleep. Single-tool monorepo, one project list, one compile graph across Java / Kotlin / Scala / Scala-2.13 cross-builds.
8. Documentation site overhaul
Site rebuilt around the new "every boundary, unified" narrative.
docusaurus.config.jscollapses to a single/typr/route served fromsite/docs-typr/.sidebars-typr.js, ~200 LOC, 68 entries grouped by boundary).site/src/pages/index.js) replaced wholesale with an Engineering Blueprint × Editorial Print theme: cream paper, deep ink, vermillion accent; Fraunces (variable serif), Bricolage Grotesque (variable grotesque), JetBrains Mono. Manifesto section ships with a real drafting-table schematic of the unified-types story (domain card, four boundary stations with policy chips, orthogonal connectors, dimensional callouts, register marks, title block).site/src/css/custom.css(~370 lines of overrides) so every docs page matches.BoundaryDiagram,CodeSample,ShowcaseSnippet,StackSelector,UsageExample,TypoLogo.site/scripts/extract-snippets.js+generate-showcasebleep script +site/showcase-generated/) lets docs reference real generated code by stable markers, so doc snippets stay in sync with what the generator actually produces.site/usage-examples/hosts cross-language runnable examples (Java/Kotlin/Scala) shown inline.9. Tester sweeps & misc
oracle/scalatests usesummon[Connection]after the context-function conversion ofwithConnectionhelpers.sqlservertests usecompareToIgnoreCaseto match SQL Server's CI collation underREAD_UNCOMMITTEDparallel runs.Randomseeds (hashed file paths → 31-bit) to dodge MariaDB deadlocks from shared-seed parallelism..javafmt.confadded at repo root to skip**/generated-and-checked-in/**from Java formatting.testers/combined/{java,kotlin}added — bundle Avro+Kafka+Mutiny+REST in one tester to exercise cross-boundary type unification.testers/{db2,duckdb,mariadb}/kotlin) undertemplate-kotlin-db-tester.Why one PR
The foundations split forces the codegen rewrite, the codegen rewrite enables the Connection/ConnectionRead split, that split surfaces in every generated repo across every tester, the Bridge work needs new computed-type layers in OpenAPI/Avro/gRPC and new file generators in codegen, the new boundary types need Kafka/Avro/Mutiny deps, and the site is rewritten to document the unified result. Splitting cleanly was not practical.
Test plan
bleep --no-color compile— all 79 projects compile (0 failed, 0 skipped)bleep --no-color run typr -- generate— all 36 outputs regenerate cleanlybleep --no-color test— full test suite with restarted containers (sqlserver in isolation: 243/243 passing)🤖 Generated with Claude Code