walkeros-create-cmp-so…
A CMP source is a specialized walkerOS source that listens to a consent management platform's events and translates consent…
Sources capture events from the external world (browser DOM, dataLayer, HTTP requests, cloud functions) and feed them to the collector.
$ npx -y skills add elbwalker/walkerOS --skill walkeros-understanding-sources --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/walkeros-understanding-sourcesContext preview
The summary Claude sees to decide when to auto-load this skill.
Sources capture events from the external world (browser DOM, dataLayer, HTTP requests, cloud functions) and feed them to the collector.
name: walkeros-understanding-sources description: Use when working with walkerOS sources, understanding event capture, or learning about the push interface. Covers browser, dataLayer, and server source patterns.
Sources capture events from the external world (browser DOM, dataLayer, HTTP requests, cloud functions) and feed them to the collector.
**Core principle:** Sources capture. They don't process or deliver—that's collector and destinations.
See [packages/core/src/types/source.ts](../../packages/core/src/types/source.ts) for canonical interface.
Sources use a context-based initialization pattern:
import type { Source } from '@walkeros/core';
export const sourceMySource: Source.Init<Types> = async (context) => {
const { config = {}, env, logger, id } = context;
// ...
};**Context contains:**
| Property | Type | Purpose | | ----------- | -------------------------------------- | ------------------------------------------------------------------------------------------- | | `config` | `Source.Config<T>` | Settings, mapping, options | | `env` | `Types['env']` | Environment (push, logger) | | `logger` | `Logger` | Logging functions | | `id` | `string` | Source identifier | | `collector` | `Collector.Instance` | Reference to collector | | `withScope` | `(scope, respond, body) => Promise<R>` | Bind ingest + respond to a single scope (server sources). Takes a normalized `Source.Scope` |
| Method | Purpose | | ------------- | ----------------------------------- | | `push(input)` | Receive external input, emit events |
`init?: () => void | Promise<void>` — Optional eager-startup hook on the returned `Source.Instance`. The factory must be **side-effect-free**: build the instance and return it. The collector calls `init()` on every source eagerly after all factories register, regardless of `config.require`. Use `init` for work that previously sat in the factory body: adopting a pre-init window queue (e.g., `window.elbLayer`), attaching DOM listeners, opening sockets, intercepting `window.dataLayer`. After `init` runs the collector flips `Source.Config.init` to `true`.
`queueOn?: Array<{ type: On.Types; data: unknown }>` — Optional buffer on the `Source.Instance` for lifecycle events delivered before the source is **started** (started ≡ `config.init === true && !config.require?.length`). The collector pushes `{ type, data }` here when it would otherwise call `source.on(type, data)`. Once the source becomes started, the collector replays each entry via `source.on(...)` and clears the queue.
`destroy?: DestroyFn` — Optional cleanup method. Called during `command('shutdown')`. Use to close HTTP servers, timers, or connections. Receives `{ id, config, env, logger }`.
The collector and every source agree on three lifecycle markers, all on `Source.Config`:
| Field | Purpose | | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `init?: boolean` | Set by the collector to `true` after `Instance.init()` resolves. Authors do not write to it. Reflects "init has run", not "is started". | | `require?: string[]` | Author-supplied **timing hint**. Lists collector state a source needs before its first `on()` delivery. Satisfied by the collector's **current recorded state** (level), not only by a future event — so order does not matter: the gate clears whether the required state was recorded before or after this source registered. It is not a correctness dependency: a source reacts to state correctly whether or not it declares `require`. | | `disabled?: boolean` | Hard skip — no factory invocation, no init, no event capture. |
The flow is:
1. **Register** — c
From 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.