@mccaskie-labs/workbench-config
v0.4.10
Published
Workbench app configuration: WORKBENCH_ENV, typed variables that fail by name, secrets that are never printed, and the capabilities manifest.
Readme
@mccaskie-labs/workbench-config
Configuration for apps built on Workbench, a private platform. Published publicly so Workbench projects can install it with no token; it is not supported for other uses.
npm install @mccaskie-labs/workbench-config zodimport { z } from 'zod'
import { defineConfig, workbenchEnv } from '@mccaskie-labs/workbench-config'
const config = defineConfig({
WORKBENCH_GATEWAY_KEY: z.string().startsWith('wbk_'),
SITE_NAME: z.string().default('my-app'),
})
const stage = workbenchEnv(env) // 'development' | 'staging' | 'production'; throws if WORKBENCH_ENV is missing
const { WORKBENCH_GATEWAY_KEY } = config.parse(env)| Export | What it does |
| --- | --- |
| workbenchEnv(env) | Reads WORKBENCH_ENV. Throws if it is missing or not one of the three environments. Never reads NODE_ENV |
| defineConfig(shape).parse(env) | Validates the named variables with zod. An empty string counts as missing. Throws WorkbenchConfigError naming every bad variable; the error never holds a value |
| workerSecret(env, name) | A Worker secret or variable by name; throws, naming it, if it is missing or empty |
| sharedSecret(binding, name?) | Reads a Secrets Store binding; throws if it is empty |
| redact(value), redactAll(text, secrets) | [redacted] in place of a secret, for logs |
| capabilities, MANIFEST_VERSION, capabilitySchema | The Workbench capabilities manifests and their schema. The JSON files are also at @mccaskie-labs/workbench-config/capabilities/<component>.json |
| defineBrand(json), brandSchema, resolveBrand, BRAND_DEFAULTS, BRAND_FILE | The app's brand file, brand.json at the repo root: name, siteUrl (https), logo.url (https PNG, JPEG or SVG; optional alt, width, height), colours.primary (#rrggbb; text, background, muted default), optional fonts.heading/fonts.body ({ family, url? }, url an https stylesheet), supportEmail and footer. Unknown keys fail. Account emails, PDFs and Supabase's sign-in emails all read it |
| checkLogo(bytes), placeholderLogo(name, colour), colourForId(id), parseColour, whiteContrast, shownSize, LOGO_PATHS, MAX_LOGO_BYTES, BrandAssetError | Setting a brand from an upload: the logo is checked by its own bytes (PNG or JPEG, at most 256 KiB; SVG refused because Gmail and Outlook don't show it), a project with no logo gets its initials on its colour as a 96 × 96 PNG, and a project with no colour gets a steady one from its id that white text reads on (WCAG 4.5:1). Runs in Workers, the browser and Node |
| VENDOR_SETTINGS, resolveVendorSettings(file, env), vendorSettingsFileSchema, VENDOR_SETTINGS_FILE, SEND_EMAIL_HOOK, SEND_EMAIL_HOOK_PATH, SEND_EMAIL_HOOK_SECRET | The vendor settings baseline: settings that live in a vendor dashboard (field, value, where it is, what breaks if it changes). A project changes a row in vendor-settings.json at its repo root, with a reason. Control applies it with vendor_settings_apply and compares it every day |
npx workbench-config check [dir] compares the variable names in .dev.vars with .dev.vars.example and prints names only.
npx workbench-config skills [--check] [dir] writes a project's .claude/skills: one skill for each Workbench tool a client's Claude Code works with, and workbench-start, which introduces them to the owner. --check fails when a file differs from what the installed version writes.
npx workbench-config status [dir] prints what Claude Code needs to know at the start of a session: optional tools the owner hasn't decided on (workbench/tools.json), answers files still a draft, and skills that are out of date. It prints nothing when all is settled and always exits 0, so it can run from a SessionStart hook.
Runs on Node 24 and the Cloudflare Workers runtime. zod 4 is a peer dependency.
