Repository navigation
every-plugin@3.0.0-rc.0
Pre-releaseMajor Changes
-
d57b8f4: Upgrade build toolchain to Rspack 2.2 / Rsbuild 2.2 / Module Federation 2.9
Version catalog bumps: @rspack/core + @rspack/cli → 2.2.6, @rsbuild/core → 2.2.8,
@rsbuild/plugin-react → 2.1.0, @module-federation/* → latest 2.x (enhanced 2.9.0,
node 2.7.50). @module-federation/runtime-tools and @rspack/dev-server are now
explicit dependencies where used.BREAKING (every-plugin): EveryPluginDevServer removed from every-plugin/build/rspack.
Plugin dev serving is now standalone —every-plugin-serve(supervised
rspack build --watch+ plain node:http server with the same contract: health,
remoteEntry statics, oRPC RPC/OpenAPI, sibling composition, effect context).
Plugin dev scripts useevery-plugin-serveinstead ofrspack serve.
EveryPluginBuild carries the build-side responsibilities only.Deploy note:
bos mf checkcompares host and remote pluginVersion exactly, so
after the 2.9.0 host deploys, remote-only plugins must be redeployed on
Module Federation 2.9.0 to stay compatible. -
d57b8f4: Adopt the Effect DevTools toolchain: native TypeScript 7 (
@effect/tsgo) with the Effect language-service plugin, and Oxlint with type-aware Effect rules.TypeScript peer/dev ranges are narrowed to
^7.0.2(no more^5support):every-plugin,better-near-auth, and@everything-dev/auth-pluginnow require TypeScript 7, andeverything-devmoves its devDependency to^7.0.2. Builds are unaffected (rspack/rsbuild transpile); typechecks and the editor language service run on the patched TS 7 native compiler.TS 7 compatibility fixes: the test-plugin fixture consumes the built
every-plugindeclarations, and a new roottsconfig.base.jsonconsolidates shared compiler options across parent-owned workspace tsconfigs (scaffoldedui//api//plugins/*tsconfigs stay self-contained since they are copied verbatim into child projects).Contract declarations move into the plugin build entirely:
every-plugin build/deploy/devregeneratetypes/contract.d.tsfromsrc/contract.tsvia the patched TypeScript 7 binary whenever it is stale (rspack watch keeps dev types fresh automatically), andEmitPluginManifestembeds the fresh file with a verified sha256. The per-workspacetsconfig.contract.jsonfiles are removed —bos syncmigrates child projects, andevery-plugin typesregenerates manually.bos typechecknow regenerates client-stub types itself before type-checking, so the roottypes:genscript is gone. Remote plugin-manifest fetches duringtypes genretry on transient network failures. -
d57b8f4: Effect-native plugins:
.effect()handlers, Layer-returninginitialize, router merging, and direct package imports. Implementsplans/infra/effect-native-plugins.md(the handler-idiom half of the oRPC v2 + Effect 4 migration).every-plugin — breaking
createPluginAPIinitializereturns an EffectLayerinstead of a deps record. The runtime builds the Layer in the plugin's lifecycle scope and exposes services through the oRPC context (effect/context), so handlers access them withyield* Tagin.effect()generators orContext.get(context["effect/context"], Tag)in plain/streaming handlers.Layer.buildWithScope+Context.getextraction in plugin code is gone.createRouter(builder, plugins)— the deps parameter is removed. Sibling plugin entries inpluginscarry{ client, router }for cross-plugin router merging (nesting a sibling's router also surfaces its routes in the host's OpenAPI spec and MCP tools).shutdownis removed — Layer finalizers scoped to the plugin handle teardown.- New optional
servicesTagon the plugin definition lets the host read a plugin's services from the built Effect context without importing the plugin module (used by the host to mount the auth plugin's Better Auth handler). @orpc/experimental-effect(.effect()builder extension) and@orpc/openapi.route()extension are pre-loaded by the runtime; plugins importoc,ORPCError,zod,effectdirectly and theevery-plugin/orpc,every-plugin/effect,every-plugin/zodre-export barrels (plus therunEffect/flattenErrorbridges) are deleted.@orpc/openapi,@orpc/experimental-effect, and@orpc/publisherare now Module Federation shared singletons.InitializedPlugin.context(deps record) is replaced byInitializedPlugin.effectContext;usePlugin'screateClientinjectseffect/contextso server-side/SSR calls work with.effect()handlers.
Host
/api/rpc/*and/apihandlers inject the serving plugin's Effect context; the base API handler receives the merged context of all initialized plugins so merged sub-routers resolve their own services. MCP tool invocations get the same injection.
API plugin
- The four template-plugin passthrough handlers and their re-declared schemas are deleted; the template router is merged directly as
things, so its routes appear under/apiOpenAPI docs and MCP automatically.
Plugins
_template(reference implementation),apps,auth,proposals, andvotesmigrated to the new API. Streaming handlers stay async generators and read services synchronously from the injected Effect context.bos upgrade'sensureEffectImportscodemod now rewrites legacyevery-plugin/effectimports toeffectdirectly.
Atomic deploy required — unchanged from the parent migration: old remote plugins are incompatible and all remotes must be redeployed together (
bos publish --deploy). -
d57b8f4: Migrate the framework to Effect 4 (
4.0.0-rc.112) and oRPC v2 (2.0.0-beta.35).every-plugin
- Layer-based plugin
initialize: services are built withLayer.mergeAll+Layer.buildWithScopeinside anEffect.gen, replacing the removedtools.buildServiceAPI.PluginServicesToolsis gone. Context.Tagreplaced byContext.Service<Self, Shape>()("id")throughout.- Effect 4 API migration:
Effect.eitherremoved (use tagged results orrunPromiseExit),Effect.catchAll→Effect.catch,Effect.async→Effect.callback,Layer.scoped→Layer.effect,Cause.isInterruptedOnly→Cause.hasInterruptsOnly,Fiber.RuntimeFiber→Fiber.Fiber. PLUGIN_ERROR_STATUS_MAPnow spreads oRPC v2'sCOMMON_ERROR_STATUS_MAP(providing a map replaces the default entirely) and keeps the v1 TIMEOUT → 504 / CONNECTION_ERROR → 502 overrides.getMajorMinorVersionpreserves prerelease segments (4.0.0-rc.112→^4.0.0-rc.112) so Module Federation requiredVersion ranges keep host/plugin lockstep on RC builds.- Publisher retention option renamed to
resume: { enabled, seconds }.
everything-dev
- CLI runtime fully migrated to Effect 4; the orchestrator no longer depends on
@effect/platform/@effect/experimental(no Effect 4 release) and spawns processes viachild_process.spawnwithEffect.callbackexit handling andStream.fromReadableStreamoutput pipelines. bos upgradecodemod rewritesEffect.provide(Layer)call sites to the v4Layer.buildWithScope+Context.getpattern and emits balanced-import rewrites.- Contract parsing reads zod 4 schema internals (
definstead of_def) and oRPC v2~orpc.inputSchemas[0], fixing boolean/negated flag parsing.
Host / API / plugins / UI
- All workspaces on the same Effect 4 + oRPC v2 versions via the catalog. oRPC v2 OpenAPI generator/reference plugin wiring, RPCLink
origin/urlsplit,errorStatusMapon all handlers. - Breaking change for deployed remotes: hosts and plugins must be redeployed together (
bos publish --deploy). v1 remote bundles are incompatible with the v2 host.
- Layer-based plugin
-
d57b8f4: Export map is now generated from the tsdown entry table, and the dead build surface is gone.
every-plugin: the
package.jsonexports map'sbun/developmentblocks are stamped fromtsdown-entries.ts— one table is the source of truth for the tsdown entry list and the export subpaths (bun run --cwd packages/every-plugin exports:syncto stamp,exports:checkfor CI; a unit test pins the stamp, andtsdownself-stamps on every build). Resolution semantics are unchanged:bun/developmentstill resolvesrc/, default still resolvesdist/(ADR 0018). Removed with zero in-repo callers: theevery-plugin/testingexport (never imported),RuntimeOptions(never read), the publicEveryPluginComposedBuild/EveryPluginComposedBuildOptionsre-exports (the composed stack stays, internal tocreatePluginBaseConfig; no custom stacks exist), theadditionalExportsbuild option inEmitPluginManifest(manifest consumption ofadditionalExportsfrom deployed plugins is untouched), and the deprecatedCommonPluginErrorsalias (usePluginErrorsor individual imports). Consumers of deployed-plugin manifests are unaffected.everything-dev: internal refactor only — the three near-identical prerequisite builders collapse into one
buildPackageQuietly(cwd, packageName, force);buildWorkspaceTargetsand thebos devboot build are unchanged in behavior, and the regression prod-stack runner (image-stage builds viascripts/regression/container-build.ts/ thebos buildCLI) is untouched. -
d57b8f4: Plugin identity unified and shared dependencies specified once.
every-plugin: new
every-plugin/identity— one derivation for npm/remote/container names from the config layout key (remoteName,containerName,identity,pluginLayoutKey,resolveDevPluginId);plugin.dev.tsno longer carriespluginId(the dev server derives it from the workspacepackage.json, fixing thedependsOnsibling lookup). Newevery-plugin/shared-deps-spec— the canonical shared-dependency lists, criticality, and version resolution; unresolved versions now fail the build loudly (SharedDependencyResolutionError) instead of silently degrading to*/latestand disabling the strict-singleton guard; all four consumers (rspack, rsbuild, runtime mf-config, host pre-registration) derive from it. Theappsplugin is renamedregistry(dir, package@everything-dev/registry-plugin, config attachment keyplugins.registry,apiClient.registry.*) — the attachment-key rename is a published-config break; land it with the bundle deploy.everything-dev: consumes both modules; scaffold (
_template) stops emittingpluginId. -
9191ab3: pnpm/node runtime alignment (ADR 0026)
- The
every-pluginCLI bins are node-first: the dist path runs plain node,
and the bootstrap tsx fallback (fresh checkout, no dist yet) passes
--conditions=developmentso the config chain resolves source over a dist
that does not exist yet. Emitted bin shebangs are#!/usr/bin/env node. every-plugin/identityinside the rspack config chain resolves relatively
(a package self-import fell through to the default condition and hit a
missing dist under node).PLUGIN_VERSIONreads the package manifest vianode:fs— the previous
createRequire(import.meta.url)came up empty under tsx in spawned
processes, reading 0.0.0 and tripping the shared-identity check.exports:sync,build:test, and the integration test scripts run through
node/tsx/pnpm;@types/bunandbun-typesare dropped.
- The
Minor Changes
-
d57b8f4: Atomic deploys phase A (tickets 01-02 of .scratch/atomic-deploys): builds emit content-hashed entrypoints (
remoteEntry.[contenthash].js,remoteEntry.server.[contenthash].js), immutable hashedmf-manifest.jsonandstyle.csscopies, and a per-distbuild-report.jsonfor the deploy leg — fixed-name entry aliases are fully retired (hard break; dev servers keep the fixed dev names as the dev serving contract). Bundle cache classification now treats any content-hashed name as immutable regardless of base name. Newevery-plugin/version-manifestexport defines the immutable per-deployWorkspaceVersionManifestdocument, and config slots accept amanifestpointer (versioned manifest filename) — the deploy unit for atomic, additive deploys. -
d57b8f4: Atomic deploys phase A completed (tickets 03-04 of .scratch/atomic-deploys): the deploy leg now composes an immutable per-workspace version manifest from the server-computed SRI map, uploads it additively at
versions/<id>.json, and pins slots by manifest pointer (manifest+ the manifest's SRI) — a dist that cannot pin (no build report / no entry SRI) aborts the train instead of writing fallback pointer entries (hard break). Upload transport hardened: status-0 retries on fresh connections (connection: close, 5 attempts, backoff+jitter), retryable statuses capped at 3. Resolution derives entry-level fields (entryUrl, hashed browser-manifestentry, entry SRI,ssrEntryUrl) from the version manifest behind a content-addressed per-pin cache; consumers (host html/head/ui-compose/plugins SSR loads/federation SSR entries/mf type inference, hydrate manifest registration) prefer the derived hashed URLs with fixed-name fallbacks only for dev and local slots. -
95261fe: Finish ADR 0023: the generated bootstrap stubs now read two authored override exports from
ui/src/app.ts—appLocale(SSR locale negotiation: locales, defaultLocale, cookieName) andapiConnectionError(localized API connection-failure toast copy). Default error/pending/not-found components are set inside the authoredcreateRouterfactory inui/src/router.tsx. Hard break to v2: children that hand-customizedhydrate.tsx/router.server.tsxget them backed up and deleted bybos sync/bos upgrade, and must port the customizations into the authored seams (the sync output prints the port guide; originals land in.bos/sync-backup/<timestamp>/). -
d57b8f4: Add
buildScoped(tag, layer)andbuildScopedContext(layer)helpers for building scoped resources inside plugininitialize(replaces the hand-writtenLayer.buildWithScope+Effect.scope+Context.getincantation), and export aPluginEnvalias for theinitializeeffect's environment (Scope.Scope | PluginIdTag). -
f151e1b: Differential bundle uploads: each deploy's version manifest now records the dist's full per-file SRI map (
files), the next deploy hashes its local dist against it and re-uploads only new or changed files. Previous pins resolve from a new.bos/deploy-state.jsonpointer (written after every confirmed publish) with the published config as fallback; any unusable previous manifest degrades to a full upload.--full-upload/BOS_FULL_UPLOAD=1bypasses the diff. -
9191ab3: Declare the shipped surface's real runtime dependencies
Under Bun's
bunexport condition (and node'sdevelopmentcondition), every-plugin resolves from source, so every value import in the shippedsrcgraph is a runtime dependency — and the build surface (build/ui,build/rspack,ui/manifest-generator,dev) is part of that graph. The following were resolvable only through hoisting luck or misdeclared as peers and are now properdependencies:@tanstack/router-generator(was undeclared entirely — crashed at boot once the image's node_modules was pruned)@module-federation/rsbuild-plugin(was a peer; value-imported bybuild/ui/rsbuild-config.ts)sirv(was undeclared; used bydev/serve.ts)@rsbuild/core,@rsbuild/plugin-react,@tanstack/router-plugin(were peers; value-imported by the build/ui factories)
@rspack/corestays a peer — its imports in the shipped surface are type-only. -
d57b8f4: Complete folder-form plugin UI sources: a
ui/directory with route files but no ownpackage.jsonis now built entirely by the plugin'severy-plugin dev/build(a generated rsbuild config under.every-plugin/), replacing the separate plugin-ui workspace.- Dev orchestrator passes
BOS_UI_PORTto the plugin dev process — including the auth app slot, whoseplugin:authdescriptor is never spawned — so the plugin ui dev server always listens on the port the runtime config advertises (previously it auto-picked a port, breaking client-side compose of plugin routes) - Folder-form ui builds output to the ui source root's
dist/(web +ssr/containers), matching what the host's local SSR container server and manifest reads expect - Generated rsbuild config now carries a
deployLabel bos devwarns and suggests a single restart when its build step finds the everything-dev dist stale — the running CLI keeps the previously imported build, so orchestrator changes are one session behind without it- New
csrbrowser-regression mode (regression:start:csr/test:regression:browser:csr): the dev stack without--ssr, running a focused spec set that pins client-side manifest composition of plugin routes (including a no-CSP-violation assertion) — the default dev path was previously untested by the regression suite
- Dev orchestrator passes
-
f9d2dce: Manifest contract v2 (ADR 0024): route records adopt the TanStack virtual-file-routes vocabulary —
type: "route" | "layout" | "index"replaces theisLayout/isIndexbooleans — and the manifest version is enforced at every load: the host's manifest loads and the client's compose-payload parse reject a skewed major with one diagnostic (a version-skewed payload degrades to the core-only tree instead of silently mis-constructing). The folder-form ui's composition key now derives solely from theplugins/<key>layout — a non-derivable key fails the build loudly instead of silently falling back to the container name (the drift that mis-keyed manifests). Mount registry version bumps to 5, invalidating all compose digests once. -
d57b8f4: No-watch regression stacks:
BOS_NO_WATCH=1makes every local service build once and serve the built output instead of running rspack/rsbuild watchers — the regression suite needs no hot reload, and the watchers were the stack's heaviest processes (freezing shared CI runners under their accumulated footprint ~26 tests in). Plugin API services run a one-shotrspack buildand servediststatically; folder-form ui sources build once and serve the ui source root'sdistonBOS_UI_PORT; the core ui gains adev:builtscript (rsbuild build && rsbuild preview). Localbos devstays watch-mode. The CI regression suite also splits into two parallel jobs (SSR + CSR), each with its own 20-minute budget and a resource watchdog logging memory/top processes to the failure artifacts. -
d57b8f4: Plugin build framework consolidation:
EveryPluginComposedBuild(the rspack stack — manifest emission + Module Federation + MF data-URI fix — in one composed plugin) andcreatePluginBaseConfig()replace per-workspace config boilerplate. Newevery-plugin <dev|types|build|deploy>CLI is the plugin package contract, absorbing thebuild:types → tsc → rspackchain; per-workspace scripts shrink to one-liners andevery-plugin-servebin is a single source import. Per-workspacerspack.config.jsfiles are deleted — the CLI synthesizes the composed config (opt-in typedbuild.config.tsoverrides).deploybuilds the same asbuild— deploy URLs are written bybos publish --deploy(image-native), not by build hooks. -
d57b8f4: One shared Effect-native plugin-load retry policy (
loadRemoteWithRetry): capped exponential backoff bounded by a wall-clock budget, per-attempt failure logging deduped by classification signature, the poisoned global entry cache purged between attempts, and fail-fast on permanent failures (classifyPluginFailure().retryable— MF identity skew, schema validation, dead remotes, TLS verification) instead of silently burning the budget.withRemoteEntryResilienceand the dev-server's duplicate loop are absorbed by it. MF service logs now read[MF][<pluginId>] ✅ Registered/✅ Loaded constructor(plugin id no longer duplicated as a log annotation). -
d57b8f4: Purge the stale public surface: delete dead every-plugin exports (
PluginMetadataRegistry,LegacyPluginRuntimeConfig,PluginConstructor,ERROR_PATTERNS,getPluginSharedDependenciesVersionRange, and the deprecatedcreateLocalPluginRuntime/createTestPluginRuntime/PluginMap/InferBindingsFromMaptesting helpers), restore thebos upgradelegacy dist-import rewrite to its originaleverything-dev/dist/→everything-dev/pattern (the mapping table had degenerated to an identity rewrite that could never fire), and replace the dead subaccount workflow in generated child AGENTS.md with the DAO-owned tenant flow. -
d57b8f4: Fix the recurring post-sign-in redirect loop structurally: the session read path and auth redirect policy now have one owner (
everything-dev/ui/auth), shared across the core ui and plugin ui remotes as a strict Module Federation singleton. A mixed deploy can no longer run two divergent session-read copies whose guard decisions disagree into "Too many redirects" — the login guard and the authenticated guard read through exactly one module, and a version mismatch fails loudly at load instead of silently loading a second copy. Child projects receive the consolidated guards viabos sync(ui/src/lib/auth-guards.ts,ui/src/lib/plugin-path.ts, and the plugin's driftedsession-cache.tscopy exit sync ownership). See ADR 0018.Also kills the silent dist-staleness class for build tooling: the bundler-configuration factories (
every-plugin/ui/mf-build,every-plugin/build/rspack) resolve from source under bun (the workspace runtime) while node/npm consumers resolve the immutable published dist, and theeverything-dev/ui/mf-buildre-export shim is deleted (ui/rsbuild.config.tsimportsevery-plugin/ui/mf-builddirectly, like the generated plugin configs already do). Shipped code still resolves dist, withbos build/bos deployunconditionally staleness-checking the framework prerequisites before any target — the train is the only supported build path. -
d57b8f4: Source-first local dev for the framework packages plus quieter builds.
every-plugin
- Silenced route-generator build warnings: colocated
*.test/*.specroute files are excluded from route scans viarouteFileIgnorePattern(prefix with-to fully opt out), and the node-environment UI build no longer races the web environment writingsrc/routeTree.gen.ts(its write goes to a scratch path). every-plugin devre-execs with--conditions=development(guarded byEVERY_PLUGIN_DEV_CONDITIONS=1) so the runtime resolves framework packages from TS source.- Plugin rspack builds resolve
every-plugin/everything-dev/better-near-auththrough thedevelopmentexport condition (TS source) for all local flows; the gate isDEPLOY !== "true"(the rspack CLI defaults NODE_ENV to production even for dev watch). Adds json and.js→.tsextensionAlias rules to make source-resolved packages (package.json imports, node-style specifiers) bundler-compatible. Deploy builds keep the dist-first snapshot that ships.
everything-dev
bos devspawns services withbun --conditions=development, so bun-runtime chains (plugin dev servers, MF runtime requires) consume framework sources directly; the host dev server getsNODE_OPTIONS=--conditions=development(tsx is TS-capable node).- Root
dev*/bosscripts run the CLI with the development condition, so the CLI itself starts from source on fresh clones without a prebuilt dist. - The quiet dist rebuilds at
bos devbootstrap remain: rsbuild/rspack config loaders (jiti / native.mjsimport) are conditions-inert and require dist.
- Silenced route-generator build warnings: colocated
-
f5f1a5f: Serve the platform skill family from the core UI build —
node_modules/{everything-dev,every-plugin,better-near-auth}/skillscopy intodist/skills/<package>/and are reachable at/skills/<package>/<skill>/SKILL.md(with the rest of the family listed from/skill.md). Children get the same copies from the published npm tarballs. -
d57b8f4: The slot pin gets an explicit representation: config slots carry
pin: { manifest, integrity }(the versioned WorkspaceVersionManifest
filename + that document's SRI) instead of the overloaded flat pair — the
top-levelintegrityis now always a direct entry SRI, only for unpinned
fixed-name slots. Breaking: the flatmanifestkey is retired (deploy
write-backs scrub it), and outside development every remote slot MUST pin a
version manifest — an unpinned remote slot fails config resolution loudly
(pre-pin configs are pre-atomic-deploy and not servable). Fixed-name entry
fallbacks are development-only at every consumer (host html shell, head
scripts, SSR entry loads, compose webEntry); a production slot without a
derivedentryUrlfails loudly. Extends merge treats the pin atomically (a
child pin replaces the parent's whole). Also addsresolveEntryUrlForEnv
toevery-plugin/ui/manifest— the shared consumer contract for entry-URL
resolution. -
f9d2dce: The core ui's bootstrap stubs are now generated, not authored: the web entry, hydrate bootstrap, SSR router module, compose expose, and globals are emitted as
.gen-suffixed, gitignored files by the framework's code-artifact generation pass (bos dev/build/typecheck), regenerated from the installed package version. The build surface retargets to the generated paths and core-ui detection no longer requires an entry stub. Sync drops the retired stub files from its ownership list and tolerates templates that no longer ship a file. Per ADR 0023.
Patch Changes
-
d57b8f4: Compile login catalogs before loading them into Lingui, preserve the NEP-413 callback URL throughout wallet signing and verification, and keep local plugin manifests and source-first runtime loading working on Windows.
-
d57b8f4: Fix
every-plugin devafter per-workspace rspack config deletion: the dev server spawned a barerspack build --watchwith no config, falling back to rspack defaults (entry./src, no.tsresolve extensions) so every local plugin's watch build failed withCan't resolve './src'. The generated-config synthesis from the CLI (build/deploypaths) is now shared (ensureGeneratedRspackConfig) and the dev watcher passes--config .every-plugin/rspack.config.generated.mjs(barerspack build --watchremains for workspaces that ship their ownrspack.config.js). -
c520871: Harden error rendering: unknown throwables (symbols, objects, unserializable values) stringify safely in runtime error messages and plugin-load logs instead of throwing or printing
[object Object]. -
9191ab3: Bin scripts run on node
every-plugin/every-plugin-servebins drop the bun shebang: they re-exec through tsx (dev carries thedevelopmentexport condition), and non-dev commands run the builtdist/cli.cjswhen present — falling back to tsx + src only for the fresh-checkout bootstrap build. -
4d8efd1: Fix stale
metadata.sourcesin theplugin-clientandplugin-testingskills (api/src/lib/auth.ts→ the auth-middleware module,src/testing/index.ts→ the runtime entry). -
d57b8f4: Fix dev/regression builds shipping hashed MF entry names, and make the regression start fixture pin its slots.
isBuildInvocationnow keys on an explicitBOS_DEV_SERVER=1stamp (dev servers mark their own bundler children) instead of NODE_ENV/DEPLOY — vitest'stestenv and the bundler CLIs'productiondefault can no longer misclassify a dev server, and every non-dev build (local, host-test, container, deploy) emits content-hashed entries + build reports. The host rsbuild config adopts the same hashed-entry + report contract, makingapp.hostpinnable by the deploy train. Slot pins resolve against the slot's remote base (remoteUrl), not the host's listening URL. The regression container-build composes per-slot version manifests (local SRI) and stampspin: {manifest, integrity}into the variant configs — ADR 0009 amendment: pins are the only production slot shape — and the version manifests'ssr.entrycarries itsssr/path segment so derivedssrEntryUrlpoints at the real bytes. -
f151e1b: FixMfDataUriPlugin now resolves what it rewrites. The data-URI normalizer strips machine-absolute
node_modulesprefixes from generated runtime imports (MF runtime, rsbuild's HMR entry) and records each bare specifier's on-disk target, then redirects resolution back through a NormalModuleFactoryresolvetap. This replaces the hardcodedmfDataUriAliases()list, which missed specifiers it didn't know about —@rsbuild/core@2.2.8's exports map doesn't expose./dist/client/hmr.js, so any workspace with a browser dev build (ui, auth, ai) failed withPackage subpath './dist/client/hmr.js' is not defined by "exports"immediately after "Rspack compiled successfully". Module ids stay machine-independent: the request remains the bare specifier; only the resolution target is machine-specific. -
d57b8f4: Fix the folder-form no-watch UI static server: it derived the dist directory from
path.dirname(cwd)— serving<parent>/ui/dist, a directory that does not exist for plugins underplugins/<id>/— while the generated rsbuild config (correctly) writes<cwd>/ui/dist. Every asset 404'd, so the browser's manifest-driven remote registration failed and client composition silently fell back to the core-only route tree (plugin routes like/loginand/settingsvanished into the_public/$accountIdcatch-all). The server now also fails loud at listen time when the built UI dist is missing. -
d57b8f4: Composed routes now keep their authored route contract. The generated
routeConfig.gen.tsandconstructTreecarryvalidateSearch,searchmiddlewares,params,loaderDeps,context,ssr,staleTime,gcTime,preloadStaleTime,pendingMs,pendingMinMsandshouldReloadalongside the loader, head, static data and components they already passed, for plugin routes, mount layouts and the core root route. Previously these were dropped, so search validation (including redirect sanitization) in plugin routes was not applied,loaderDepsnever reached loaders, andssr: falseroutes were server-rendered. Route configs are regenerated byevery-plugin build/bos dev; deployed UI remotes pick up the fix once rebuilt and republished. -
d57b8f4: The plugin dev server's build watchers (
rspack build --watch,rsbuild dev) are now killed with SIGTERM-then-SIGKILL escalation on shutdown — rspack's watch mode ignores SIGTERM, so previously every non-graceful dev session left its watchers orphaned (reparented to PID 1, invisible tobos kill --all, squatting CPU and file watchers forever). The dev server also watches its own parent process and tears down (with the same escalation) if the wrapper chain above it dies, matching the orchestrator's orphan-watch behavior. -
784fcad: Restore the v1-proven core sharing set:
@orpc/openapi,@orpc/experimental-effect, and@orpc/publisherleaveCORE_SHARED_DEPSand the runtime's core module loaders. Consuming them through the share scope crashed every plugin bundle that imports them at runtime (__webpack_modules__[r] is not a function— the runtime'simport()-based provide hands the rspack consumer an ESM namespace object where a module factory is expected; the first-ever runtime load of this bundle generation failed on six of seven plugins, and template only survived because it is the one workspace that does not import@orpc/openapi). They are declared in each workspace'spackage.json(the phantom-dep fix stays) and are bundled per workspace instead, matching v1's proven production shape. Also logs the failing error's stack alongside the classified message in the plugin-load retry reporter — the message alone turned this diagnosis into hours. -
d57b8f4: Reuse plugin initialization and routers for equivalent configuration, evict failed instances, and release scopes even when initialization or shutdown defects.
-
d57b8f4: Establish strict version identity for Module Federation shared dependencies to eliminate silent Effect-RC cross-bundle skew.
The effect-critical shared deps (
every-plugin,effect,@orpc/contract,@orpc/server,@orpc/client,@orpc/experimental-effect), now carry exactrequiredVersion(the installed version) withstrictVersion: true, single-sourced from every-plugin's shared-deps module across bundle-time, runtime pre-registration, and the host build.bos mf checkcompares bundle versions exactly for these deps and treats non-caret constraints as exact matches. The plugin loader rejects a remote whose mf-manifest.json shared identity disagrees with the local runtime (BOS_MF_IDENTITY=warnopts out to warn-and-load), and skipped plugins surface in /api/_health with full detail. Deploy workflow gates Railway redeploys onbos mf checkso an inconsistent release train fails CI. -
c23dfb6: Fix plugin load failures under rspack 2.2.8 + MF runtime 2.9.x ("webpack_modules[r] is not a function"):
- The build composition disables
optimization.splitChunks, which re-ids the
final chunk graph while the federation get-factory codegen keeps pre-split
ids — emitted container entries then eagerly load chunks that were never
emitted. A newChunkCompletenessPluginfails the build loudly if any entry
references an unemitted chunk, so the regression can never ship silently. - The runtime service now registers and loads remotes under the container's
own name (mf-manifest.jsonmetaData.name). The node runtime's chunk
loader falls back to resolving chunk URLs from the remote's entry URL keyed
by that self name; a mismatch made the fallback miss,resolveUrlreturn
null, and the loader hand back an empty chunk as if it had loaded — the
exposed module then required ids nothing registered. An integration test
registers the fixture under a mismatched alias key to pin this. - Module ids are now named (context-relative requests) instead of
rspack's default deterministic hashes, which fold machine-absolute paths
into the id space: the same source built different ids on the host deploy
train and inside the image's dist-builder stage, so a mixed-generation
load (CDN-pinned entry + staged chunks) spliced two incompatible id
spaces. FixMfDataUriPlugin now also rewrites the data-URI runtime module's
machine-absolute node_modules imports to bare specifiers, with resolve
aliases restoring on-disk resolution.
- The build composition disables
-
ed70808: Two-database contract: production deployments now need only
AUTH_DATABASE_URLandAPI_DATABASE_URL; plugin*_DATABASE_URLsecrets fall back to the shared API database (per-plugin tables isolate inplugin_<slug>schemas). Explicit per-plugin values still win.bos startno longer manufactures.env/.env.example/.env.testat boot — the production container previously generated a dev-convention.env(localhost Postgres URLs) and dotenv-loaded it, feeding plugin DB secrets unreachable URLs (ECONNREFUSED).bos startonly loads an operator-provided.env;bos dev/bos initkeep the bootstrap.- Plugin
*_DATABASE_URLsecrets missing from the host environment resolve toAPI_DATABASE_URL(host plugin composition). - Generated
.env.exampleomits plugin database secrets (they are fallback-covered);.env.testkeeps explicit test-database values for isolation.
-
8a06f6b: Introduce typed Effect errors across host, CLI, and plugin runtimes.
every-plugin'sPlugin.initializecontract now types its layer error channel asErrorand its failure channel asPluginRuntimeError(mapped viatoPluginRuntimeError), andPluginRuntimeErrorexposes a readable message.everything-devgains exportedOrchestratorErrorandencodeRuntimeConfig—BOS_RUNTIME_CONFIGis now schema-encoded with undefined fields omitted (undefined array entries become null) instead of rawJSON.stringify— plus tagged error conversions in migrations, preflight, integrity, near-cli, and storage-upload, and schema-validated migration journal loading. -
f9d2dce: Trim the core ui's declared MF surface to consumed exposes (drop
./providersand./hooks), construct the core-only tree on the client when a deployment carries no compose payload or a malformed one (plugin-free CSR apps no longer crash on "no route tree"), and correct ownership headers. The ui globals ambient file is trimmed to the rsbuild types reference.