Two cleanups, one cause each. The root tsconfig.json carried the compilerOptions directly with no `include`, which made `tsc -b` treat the whole repository as one project: it ignored each package's `outDir` and emitted .js/.d.ts next to every source file, which then got committed. So every typecheck dirtied the tree and the build output was in git. The root is now a solution file that only references the real projects, shared options moved to tsconfig.base.json, and the six emitted files are removed from the index. Output goes to packages/ts-types/dist, which was already gitignored. @sinclair/typebox is now pinned exactly rather than by caret range. It is load-bearing in a way a range should not be allowed near: continuum-backend's Elysia requires it at runtime without declaring it as a dependency at all, and @continuum/ts-types resolves its own copy from here, so two different versions mean two structurally incompatible TSchema types and nothing from this package validates anything there. Worth recording what that looked like, because the error pointed elsewhere. Elysia accepts `TSchema | StandardSchemaV1Like`; when the TSchema branch failed on the version skew, TypeScript reported the *other* branch's failure, `'~standard' is missing`. That reads as "Elysia wants a Standard Schema validator, TypeBox is wrong here", which is not true - Elysia is TypeBox-native and Standard Schema is just the alternative for Zod/Valibot users. The fix was only ever to make the versions match. 0.34.52 rather than 0.33.x because Elysia 1.4 calls `t.Module`, which 0.34 introduced. continuum-backend pins the identical version and tests/dependency_identity.test.ts there fails if the two ever drift again. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
continuum-schemas
Single source of truth for the Continuum data model. Everything here is JSON Schema, compiled into two consumer packages:
packages/ts-types- hand-written TypeBox schemas undersrc/schemas/used for runtime validation incontinuum-backend's ElysiaJS routes.packages/rust-types- a Rust crate (continuum-rust-types) with hand-written,serde-derived structs forcontinuum-proxyandcontinuum-ai-worker.
Layout
schemas/continuum/v1/ Continuum's own domain model (PrintJob, Template, ...)
schemas/bambulab/ Bambu Lab MQTT wire schemas (v1/v2, report + request)
packages/ts-types/ TypeBox schemas (hand-written, mirrors schemas/)
packages/rust-types/ serde structs (hand-written, mirrors schemas/)
schemas/continuum/v1/*.schema.json is the canonical shape for each
domain object; packages/ts-types/src/schemas/ and
packages/rust-types/src/lib.rs both mirror it by hand. There are only
four small, stable DTOs here (PrintJob, MaterialProfile,
PrintParameters, Template), so keeping two hand-synced copies in sync
is less overhead than running a codegen pipeline (protoc/ts-proto/
prost-build) nothing actually consumed - see git history for the
protobuf version this replaced, and why it was dropped: every service in
this system talks JSON (JSON Schema for the wire, TypeBox/serde for
runtime validation), so protobuf's actual value - a single schema compiled
into a compact binary wire format for both languages - never applied.
Whenever a domain schema changes, update all three by hand: the JSON Schema file, the TypeBox schema, and the Rust struct.
Build / verify
Requires npm install at the repo root, and a Rust toolchain, first.
npm install
npm run build:rust # cargo build, confirms the Rust structs compile
npm run typecheck # tsc -b, confirms the TypeBox schemas compile
There's no build:ts step - the TS side is hand-written, not generated.