The generator
tinycld/scripts/generate.ts (with its gen-*.ts helper modules) is the one piece of code that stitches feature members into the app shell. It reads tinycld.packages.ts (which enumerates the present workspace members), loads each feature’s manifest, and produces a tree of thin re-exports, one typed config file, symlinks, and Go wiring - everything the app shell needs to find and load each package. The generator runs automatically on the workspace-root pnpm install (via postinstall) and again before pnpm run dev; you rarely invoke it directly.
It is a thin step: rather than emitting a file per concern, it writes a single typed tinycld.config.ts, and the runtime derives the package stores, registry, sidebars/providers/settings, and seeds from it.
What it does
Each run, the generator produces the following outputs. Every one of these files (and their parent directories, where relevant) is gitignored - they regenerate on every run.
Config source of truth
tinycld/tinycld.config.ts- a typeddefinePackageEntry<…>()array, one entry per present feature, carrying the manifest plus references to each package’sregisterCollections,sidebar,provider, andsettings. It also exportsMergedPackageSchema, a literal intersection of every package’s schema type. This file is the installed-package source of truth; the runtime helpers in@tinycld/core/lib/packages/derive stores, the registry, components, and seeds from it.tinycld/tinycld.seeds.ts- a Node-only seed list, kept out of the app bundle (seed modules use Node APIs Hermes can’t bundle).tinycld/lib/generated/tinycld-config.ts- a re-export shim so@tinycld/corecan import@tinycld/app-generated/tinycld-configwithout a hard dependency on the app.
Route re-exports
For each package with routes.directory, every .tsx/.ts/.jsx/.js file in that directory becomes a thin re-export under tinycld/app/a/[orgSlug]/<slug>/:
export { default } from '@tinycld/mail/screens/index'
Nested folders and layout files are preserved. Non-route extensions (helpers, styles) are ignored.
For each package with publicRoutes.directory, files are re-exported under tinycld/app/p/<slug>/<relpath>. drive/public-screens/share/[token].tsx becomes tinycld/app/p/drive/share/[token].tsx. The hand-written tinycld/app/p/_layout.tsx wraps the whole tree with a bare <Slot /> — no auth gate, since this is where pre-auth entry points live.
Other generated wiring under tinycld/lib/generated/
package-help.ts- parsed help-topic frontmatter + bodies for every package’s (and core’s)help/directory, consumed by the in-app help hub.uniwind-sources.css- one@source "<real-path>";line per present member (core + features), so Tailwind/Uniwind scans class names used inside members.
Server-side outputs under tinycld/server/
pb_migrations/- one symlink per migration file in core’spb_migrations/plus every feature’spb-migrations/directory.pb_hooks/- one symlink per file in every feature’spb-hooks/directory.package_extensions.go- a generated Go file whoseregisterPackageExtensions(app)calls each package server’sRegister(app).go.work- a Go workspace file listing the app, core, and each feature server module (written only when at least one feature ships a server; removed otherwise).bundled-packages.json- the seed manifest core’s Go server uses to hydrate itspkg_registrycollection at boot.
Cleanup is per-target: the generator wipes and rebuilds the migration/hook symlink dirs each run, and removes each present feature’s own tinycld/app/a/[orgSlug]/<slug>/ route dir before regenerating it. App-owned files in the route tree (_layout.tsx, index.tsx, settings/**) are left untouched.
When it runs
pnpm install # workspace root: postinstall → app packages:generate
cd tinycld && pnpm run dev # dev.ts: packages:generate → expo + pocketbase + proxy
cd tinycld && pnpm run packages:generate # manual re-run, sometimes useful after editing a manifest
cd tinycld && pnpm run export:web # production web build (runs the generator first)
If a package’s manifest or directory layout changes and you haven’t restarted dev, pnpm run packages:generate (from tinycld/) by hand picks up the new output. Bringing a new member in or removing one is just pnpm install at the root.
Footguns
Reference
For the complete list of generated artifacts and where each lives, see Generated files. For the manifest fields that drive the generator, see Manifest schema.