pleach
Plugins

Branding

White-label primitives — override the brand string, log prefixes, and error-message text the runtime emits so output reads as your product, not as Pleach. configureBranding / getBrandingConfig / resolveLogPrefix / resolveErrorMessage.

White-label primitives let a host override the brand string, log prefixes, and error-message text the runtime emits. Output reads as the host's product instead of as Pleach. The surface is opt-in; with nothing configured, the runtime's output is byte-identical to running without branding.

Two consumer types reach for this earliest. Consultancies ship the same runtime to N tenants under N brands — agency-style hosts that need each deployment to wear a different name. ISVs embed @pleach/core inside a product where exposing the underlying runtime would dilute their own brand. End-user-facing SaaS rarely needs it; if your users never see a log line or an error string, there is nothing to rename.

The contract

Four functions, all from the top-level @pleach/core export.

FunctionRole
configureBranding(config)Installs an override. Every field is optional and defaults to identity.
getBrandingConfig()Returns the active configuration with defaults filled in.
resolveLogPrefix(defaultPrefix)The call-site hook log emitters route through.
resolveErrorMessage(defaultMessage)The call-site hook throw new Error(...) sites route through.

configureBranding({ brandName, logPrefix, errorMessage }) is the whole installation surface. logPrefix and errorMessage are transform functions — each receives the default and returns the branded form, so you rename rather than hard-code.

import { configureBranding } from "@pleach/core"

configureBranding({
  brandName: "Acme",
  logPrefix: (defaultPrefix) => defaultPrefix.replace("Pleach", "Acme"),
  errorMessage: (defaultMessage) => `[Acme] ${defaultMessage}`,
})

Adoption is incremental

v0.x ships the contract. You can call configureBranding today and the resolvers honor it. What's still landing is the substrate retrofit — replacing every hard-coded [ToolNode] / [SessionRuntime] literal with a call through resolveLogPrefix — which arrives as part of the broader logging-refactor track. The override surface widens transparently as call sites adopt the resolvers; nothing you write against the contract breaks when they do.

Why it's multi-call, unlike @pleach/observe.init

@pleach/observe.init is single-init: it owns infrastructure state — destinations, sampling decisions, async-local-storage scope — that would race or leak across reconfigurations. Branding owns none of that. It's a UX preference, so the constraint is looser.

configureBranding MAY be called multiple times. The last call wins, and partial overrides do not merge with the prior config — each call replaces the whole branding state. A multi-tenant process can adjust branding at the boundary of a request handler without a process teardown.

The @pleach/core/branding subpath

The same four functions are available at the @pleach/core/branding subpath when you only want this slice in your bundle.

import { configureBranding } from "@pleach/core/branding"

Where to go next

On this page