Makes the public module-development package set usable from a module
repository outside the monorepo. Nothing is published.
- Curated @ekklesia/module-sdk: an explicit author API, no contracts
barrel, no identity/authorization internals, no Drizzle and no legacy
ModuleDatabase type. defineModuleRuntime returns the SDK's own named
interfaces so a module's emitted declarations never reach into
@ekklesia/contracts. defineModuleSchema is gone; createModuleTable and
defineModuleSchemaMetadata live in @ekklesia/module-database.
- Drizzle: no longer a dependency of module-sdk or contracts. Core keeps
the legacy Drizzle schema validator (moved to core/src/modules) and
its legacy runtime support; drizzle-orm is an optional peer only.
- React is a peer (plus devDependency) of @ekklesia/ui; the boundary
checker allows exactly that consumer-selected peer.
- @ekklesia/typescript-config is publishable; module-ui-host is private.
Every public package carries "ekklesia.distribution":
"module-development" and no monorepo-root prepack.
- module-pack reads the Node.js range from the module's own engines.node
and recognizes Ekklesia packages by name plus that marker, so
registry-installed packages are incorporated, SDK-compatibility
checked, and never credited as third-party.
- scripts/pack-public-packages.ts (pnpm packages:pack) rebuilds, packs
and inspects the nine public tarballs; scripts/test-standalone-module.sh
(pnpm test:standalone-module, new CI job) installs them into a fixture
module outside the repository and proves it typechecks, builds,
packages, and verifies.
- Public-package boundary tests and module-development docs.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
@ekklesia/module-sdk imports drizzle-orm at run time but declared it
only as a peer and a development dependency. A workspace package is
linked into its consumers as a directory, so its imports resolve from
its own node_modules, where a consumer never satisfies a peer; a
production install omits development dependencies. In the production
image this made every module with a schema fail: the API exited at
startup and Doctor reported NOT READY.
- Move drizzle-orm to module-sdk's dependencies, keeping the peer.
- Move react to @ekklesia/ui's dependencies, keeping the peer. The new
guard flags it the same way; it is bundled at build time today, so
it was not a live failure. Both lockfile entries keep the identical
resolution, so nothing new is installed and the shell bundles still
contain one React.
- Add the boundary rule runtime-imports-are-production-dependencies:
code a package ships (src/, bin/, excluding tests and .d.ts) must
declare every runtime import in dependencies or optionalDependencies.
Type-only imports are exempt; .tsx/.jsx implies react (automatic
JSX runtime). Fixtures cover peer-only, dev-only, JSX, undeclared,
and the accepted cases.
Co-Authored-By: Claude Opus 5.5 <[email protected]>