How to install create-evlog-enricher
npx skills add https://github.com/hugorcd/evlog --skill create-evlog-enricherFull instructions (SKILL.md)
Source of truth, from hugorcd/evlog.
name: create-evlog-enricher description: Create a new built-in evlog enricher to add derived context to wide events. Use when adding a new enricher (e.g., for deployment metadata, tenant context, feature flags, etc.) to the evlog package. Covers source code, tests, and all documentation.
Create evlog Enricher
Add a new built-in enricher to evlog. Every enricher is built on the public toolkit primitive defineEnricher from evlog/toolkit — so a community enricher has the same shape as a built-in one.
PR Title
Recommended format for the pull request title:
feat: add {name} enricher
The exact wording may vary depending on the enricher (e.g., feat: add user agent enricher, feat: add geo enricher), but it should always follow the feat: conventional commit prefix.
Touchpoints Checklist
| # | File | Action |
|---|---|---|
| 1 | packages/evlog/src/enrichers/index.ts | Add enricher source (one defineEnricher call) |
| 2 | packages/evlog/test/enrichers.test.ts | Add tests |
| 3 | apps/docs/content/4.enrichers/2.built-in.md | Add enricher to built-in docs |
| 4 | apps/docs/content/4.enrichers/1.overview.md | Add enricher to overview cards |
| 5 | skills/review-logging-patterns/SKILL.md | Add enricher to the Built-in line in the Enrichers section |
| 6 | README.md + packages/evlog/README.md | Add enricher to README enrichers section |
Important: Do NOT consider the task complete until all 6 touchpoints have been addressed.
Naming Conventions
| Placeholder | Example (UserAgent) | Usage |
|---|---|---|
{name} | userAgent | camelCase for event field key |
{Name} | UserAgent | PascalCase in function/interface names |
{DISPLAY} | User Agent | Human-readable display name |
Step 1: Enricher Source — built on defineEnricher
Add the enricher to packages/evlog/src/enrichers/index.ts. Read references/enricher-template.md for the full annotated template.
The contract is defineEnricher<T>({ name, field, compute }, options?). You only ship one piece of logic:
compute(ctx)— return the computed value (typed asT) orundefinedto skip.
defineEnricher handles the rest:
- merging via
mergeEventField(respectingoptions.overwrite) - error isolation (throws are caught and logged, never propagated)
- skipping when
computereturnsundefined
Key rules:
- Use the toolkit helpers:
getHeader()for case-insensitive header lookup,normalizeNumber()for numeric strings — both from../shared/headers(re-exported byevlog/toolkit). - Single event field — each enricher writes one top-level field on
ctx.event. - Factory pattern —
create{Name}Enricher(options?: EnricherOptions)always returns the result ofdefineEnricher(...). - No side effects — never throw, never log; rely on
defineEnricher's built-in error handling if something goes wrong.
Step 2: Tests
Add tests to packages/evlog/test/enrichers.test.ts.
Required test categories:
- Sets field from headers — verify the enricher populates the event field correctly
- Skips when header missing — verify no field is set when the required header is absent
- Preserves existing data — verify
overwrite: false(default) doesn't replace user-provided fields - Overwrites when requested — verify
overwrite: truereplaces existing fields - Handles edge cases — empty strings, malformed values, case-insensitive header names
Follow the existing test structure in enrichers.test.ts — each enricher has its own describe block.
Step 3: Update Built-in Docs
Edit apps/docs/content/4.enrichers/2.built-in.md to add a new section for the enricher.
Each enricher section follows this structure:
## {DISPLAY}
[One-sentence description of what the enricher does.]
**Sets:** `event.{name}`
\`\`\`typescript
const enrich = create{Name}Enricher()
\`\`\`
**Output shape:**
\`\`\`typescript
interface {Name}Info {
// fields
}
\`\`\`
**Example output:**
\`\`\`json
{
"{name}": {
// example values
}
}
\`\`\`
Step 4: Update Overview Page
Edit apps/docs/content/4.enrichers/1.overview.md to add a card for the new enricher in the ::card-group section (before the Custom card).
Step 5: Update skills/review-logging-patterns/SKILL.md
In skills/review-logging-patterns/SKILL.md, find the Enrichers section and add the new enricher to the Built-in: line.
Step 6: Update README
Add the enricher to the enrichers section in packages/evlog/README.md (the root README.md is a symlink to it).
Verification
cd packages/evlog
pnpm run lint
pnpm run typecheck
pnpm run test
pnpm run build
Related skills
More from hugorcd/evlog and the wider catalog.

create-evlog-adapter
Create a new built-in evlog adapter to send wide events to an external observability platform. Use when adding a new drain adapter (e.g., for Datadog, Sentry, Loki, Elasticsearch, etc.) to the evlog package. Covers source code, build config, package exports, tests, and all documentation.

detect-ai
Analyze text to detect if it was written by AI. Returns a score from 0-100 with detailed metrics. Use when checking content before publishing or submitting.

shadcn-svelte
Manages shadcn-svelte components and projects — adding, updating, fixing, debugging, styling, and composing UI. Provides project context, component docs, and usage examples. Applies when working with shadcn-svelte, the CLI, design-system presets, or any project with a components.json file. Also triggers for "shadcn-svelte init", "add component", or registry URLs.

nushell-pro
|

vue-best-practices
Vue 3 best practices guide: Composition API, TypeScript, and component architecture patterns.

vue-debug-guides
Debug Vue 3 runtime errors, reactivity issues, async failures, and hydration problems with targeted guides.