walkeros-create-cmp-so…
A CMP source is a specialized walkerOS source that listens to a consent management platform's events and translates consent…
Step examples are structured `{ in, out }` pairs (with optional `mapping` for destinations) that define the expected input/output behavior of each step in a flow. They serve as:
$ npx -y skills add elbwalker/walkerOS --skill walkeros-using-step-examples --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/walkeros-using-step-examplesContext preview
The summary Claude sees to decide when to auto-load this skill.
Step examples are structured `{ in, out }` pairs (with optional `mapping` for destinations) that define the expected input/output behavior of each step in a flow. They serve as:
name: walkeros-using-step-examples description: Use when writing, simulating, validating, or testing with walkerOS step examples. Covers the complete lifecycle from authoring examples to CI integration.
Step examples are structured `{ in, out }` pairs (with optional `mapping` for destinations) that define the expected input/output behavior of each step in a flow. They serve as:
`--event`; the CLI does not compare the result against `out`)
Every source, transformer, and destination can ship step examples alongside its code.
Each step in a flow sits at a boundary between arbitrary external formats and the walkerOS event model:
Source Transformer Destination ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ in: arbitrary │ │ in: walkerOS │ │ in: walkerOS │ │ (HTTP req, DOM) │ │ Event │ │ Event │ │ │ │ │ │ │ │ │ │ │ ▼ │ │ ▼ │ │ ▼ │ │ out: walkerOS │ │ out: walkerOS │ │ out: arbitrary │ │ Event │ │ Event | false │ │ (gtag, API) │ └─────────────────┘ └─────────────────┘ └─────────────────┘ arbitrary ──────────── walkerOS.Event ──────────── arbitrary
Every step example is an object with `in` (input), `out` (array of observable effects), and optional `trigger` (how to invoke):
type StepEffect = readonly [callable: string, ...args: unknown[]];
type StepOut = readonly StepEffect[];
interface StepExample {
in: unknown; // Platform-specific input
out: StepOut; // Array of effect tuples - see shape rules below
trigger?: { type?: string; options?: unknown }; // How to invoke
mapping?: unknown; // Destination mapping rule
command?: 'config' | 'consent' | 'user' | 'run'; // Route to walker command
}`out` is **always an array of effect tuples**, even for a single effect. Each tuple is `[callable, ...args]`. The first element is the callable's public name (the SDK function users would write). Remaining elements are the arguments.
| Component type | Callable | Notes | | ------------------------------ | --------------------------------------- | --------------------------------------------------------------------------------------- | | Destination (SDK function) | `'gtag'`, `'fbq'`, `'ttq.track'` | Public SDK name. Dotted paths render literally. | | Destination (method on global) | `'analytics.track'`, `'dataLayer.push'` | Method notation. | | Destination (HTTP) | `'fetch'`, `'sendServer'` | The actual call users would make. NOT `env.*` prop names - those are internal plumbing. | | Source | `'elb'` | The walker public push API. | | Transformer | `'return'` | Reserved keyword. Renders as `return <value>` (no parens). |
`'return'` is reserved. Don't use it for anything else.
Empty `out: []` means the step produced no observable effect (filtered input, transformer passthrough, validator rejection). Reserved only for cases where the destination/source deliberately emits nothing.
`in` is an HTTP request shape, `out` is a tuple of the `elb()` call the source makes:
export const checkoutPost: Flow.StepExample = {
trigger: { type: 'POST' },
in: {
method: 'POST',
path: '/collect',
body: { name: 'order complete', data: { id: 'ORD-123', total: 149.97 } },
},
out: [
['elb', { name: 'order complete', data: { id: 'ORD-123', total: 149.97 } }],
],
};A source that issues walker commands records them in its own call shape: the first argument verbatim, callable `'elb'`. Commands come first, in call order, then the events. A CMP source:
out: [['elb', 'walker consent', { functional: true, marketing: true }]],The session source (`env.command('user' | 'session', ...)`, then its event):
out: [
['elb', 'user', { session: 's3ss10n-id', device: 'd3v1c3-id' }],
['elb', 'session', { id: 's3ss10n-id', isStart: true /* ... */ }],
['elb', { name: 'session start', data: { id: 's3ss10n-id' /* ... */ } }],
],A source simulation (`walkeros push --simulate source.X`, MCP `flow_simulate`) returns exactly these calls: `call elb("walker consent",{...})`. The collector's own commands (starting consent from `--consent`, globals, custom, shutdown) and the wiring commands `on`, `hook`, `destination` are never part of a source's `out`. A consent-gated source needs `--consent` (MCP `state.consent`) to emit anything.
`in` is an HTML string, `out` is a tuple of the `elb()` call:
export const clickEvent: Flow.StepExample = {
trigger: { type: 'click', options: 'button' },
in: '<button data-elb="cta" data-elb-cta="label:Sign Up" data-elbaction="click:click">Sign Up</button>',
out: [
[
'eFrom browser to BigQuery and ad platforms - warehouse-native, and ready for AI agents via MCP.
A CMP source is a specialized walkerOS source that listens to a consent management platform's events and translates consent…
Use when creating a new walkerOS destination to send events to a vendor or API (GA4/gtag, Meta/Facebook Pixel, Mixpanel,…
Use when creating a new walkerOS source to capture events (browser source, dataLayer interception, server/HTTP source, webhook…
| Symptom | Likely Cause | Check | | ---------------------------------- | ---------------------------- |…
Read [understanding-mapping](../walkeros-understanding-mapping/SKILL.md) first for core concepts.