skills/objectenvy/SKILL.md
Automatically map process.env to strongly-typed, nested config objects with camelCase fields Use when working with config, configuration, env, environment, type-safe, zod, nested, camelcase.
npx skillsauth add pradeepmouli/objectenvy objectenvyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Automatically map process.env to strongly-typed, nested config objects with camelCase fields
process.env into a typed, nested config object at application startup.prefix: 'APP' and strip the prefix from keys.LOG__LEVEL) and want { log: { level } } nesting.env object in tests while keeping the same schema and prefix.objectify + envy)..env file from a config object (e.g., for CI scaffolding or test fixtures).ToEnv<T> for compile-time validation and need the runtime values to match.objectify() → mutate config → envy() → write back to env.concat or concat-unique).envy()..env documentation or scaffolding from TypeScript property names.objectify() uses internally to an individual value.objectify() and need consistent boolean/number parsing.Avoid when:
.required() / .asInt() semantics — use env-var instead.override().env:.objectEnvy instances instead.ToEnv<T> type at compile time — no need to call envy() at runtime.Date, Map, Set, or class instances — envy() serializes them as[object Object] via String().merge() instead.override() calls.override() instead.merge(merge(a, b), c) calls.[a-z] after the underscore.PascalCase output — capitalise the first character of the result separately.toCamelCase(toSnakeCase('apiURL')) yields 'apiUrl','apiURL'.'123' must stay '123') — passcoerce: false to objectify() instead, or handle the type downstream.parseFloat/parseInt are locale-independent but only'1e5') is NOT coerced to a number.PORT_* variable later silently restructures { portNumber } into { port: { number } },SCREAMING_SNAKE_CASE env object when relying on FromEnv types — BECAUSEcoerce: true (the default) if a value looks like a number but must stay a string —'01' becomes 1 (integer parse), losing the leading zero.objectEnvy() — BECAUSE theprocess.env after caching returns stale data.process.env after calling the inner objectify() expecting the result to update —objectEnvy instance across packages that need independent schemas — BECAUSE theenvy() to round-trip arrays of objects faithfully — BECAUSE object items areJSON.stringify-ed then joined; when objectify() re-reads the comma-separated string, itnull or undefined values in the config — BECAUSE envy() silently skipsnull/undefined entries, leaving no env key for them; the round-trip loses those fields.envy() to honour a prefix — BECAUSE it outputs bare SCREAMING_SNAKE_CASE keysAPP_PORT rather than PORT.defaults or config arguments after calling override() — BECAUSE theoverride() to handle class instances or special objects (Date, Map, Set) — BECAUSEtypeof === 'object' and recurses, which may produce unexpected results formerge() to deep-clone the inputs — BECAUSE nested sub-objects are shallow-copied'concat-unique' to deduplicate object items if equality matters beyond JSON serialisation —JSON.stringify for comparison, which is order-sensitive and ignoresundefined values, Date objects, and prototype methods.merge() handles non-plain objects (Map, Set, Date, class instances) correctly —typeof === 'object' and recurses, producing incorrect results fortoCamelCase(toSnakeCase(x)) === x for all inputs — BECAUSE acronym boundariesapiURL → API_URL → apiUrl) collapse consecutive capitals, so the round-trip isgetHTTPSUrl → GET_HTTPS_URL →getHttpsUrl, losing the original casing of consecutive uppercase letters.PORT_NUMBER → PORT__NUMBER (double underscore)_N boundary.coerceValue on values that use commas as decimal separators (e.g., '3,14' in[3, 14] rather than the3.14.'01234') —parseInt('01234', 10) returns 1234.'on'/'off' being coerced to booleans — BECAUSE only true/false/yes/no/y/n'on' stays as the string 'on'.2 configuration interfaces — see references/config.md for details.
objectify() — controls prefix filtering,
env source, Zod schema validation, camelCase nesting behaviour, and include/exclude patterns.merge() and override().Parsing: objectify, objectEnvy, toCamelCase, coerceValue
Serialization: envy, toSnakeCase
Merging: override, merge
Type Utilities: ConfigObject, ConfigValue, ArrayMergeStrategy, ToEnv, FromEnv, WithPrefix, WithoutPrefix, SchemaToEnv
development
ObjectEnvy monorepo - strongly-typed environment configuration for TypeScript projects
documentation
Documentation site for objectenvy
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------