원클릭으로
walkeros-using-cli
// Use when bundling walkerOS flows, testing events with simulate/push, running local servers, validating configs, or configuring Flow JSON files.
// Use when bundling walkerOS flows, testing events with simulate/push, running local servers, validating configs, or configuring Flow JSON files.
Use when adding read-through caching to a walkerOS store, memoizing a slow API/Sheets backing, composing multi-tier cache chains, or deduplicating concurrent store reads. Covers recipes, TTL choice, error policy, and observability counters.
Use when configuring walkerOS event mappings for specific use cases. Provides recipes for GA4, Meta, custom APIs, and common transformation patterns.
Use when transforming walkerOS events in the flow (source→collector or collector→destination), configuring data/map/loop/set/condition/policy, or using $code: syntax in JSON configs.
Use when wiring `@walkeros/transformer-ga4` into a server flow, overriding default GA4 event mappings, dropping events, adding custom event keys, or troubleshooting GA4 Measurement Protocol decoding. Covers the `before`-chain wiring contract, configuration recipes, and per-field patching with extend/remove.
Use when writing or updating walkerOS documentation - README, website docs, or skills. Covers quality standards, example validation, and DRY patterns.
Use when learning walkerOS architecture, understanding data flow, or designing composable event pipelines. Covers Source→Collector→Destination pattern and separation of concerns.
| name | walkeros-using-cli |
| description | Use when bundling walkerOS flows, testing events with simulate/push, running local servers, validating configs, or configuring Flow JSON files. |
The walkerOS CLI (walkeros) bundles, tests, and runs event collection flows.
Core workflow:
# Install
npm install -g @walkeros/cli
# Bundle a flow
walkeros bundle flow.json
# Test with simulated event
walkeros push flow.json -e '{"entity":"page","action":"view"}' --simulate destination.demo
# Push real event
walkeros push flow.json -e '{"entity":"page","action":"view"}'
| Command | Purpose | Safe? |
|---|---|---|
bundle | Generate JS bundle from config | ✅ |
push | Execute with real API calls (or --simulate for mocked) | ⚠️ |
run | Local HTTP event collection | ✅ |
deploy | Deploy flows to cloud | ⚠️ |
previews | Manage preview bundles for testing on live sites | ⚠️ |
validate | Validate configs/events | ✅ |
cache | Manage caching | ✅ |
For detailed command reference, see commands-reference.md.
1. Write flow.json config
2. Bundle: walkeros bundle flow.json
3. Simulate: walkeros push flow.json -e event.json --simulate destination.demo
4. Fix issues, repeat 2-3
5. Push test: walkeros push flow.json -e event.json
6. Deploy: walkeros deploy start <flowId>
# Bundle specific flow
walkeros bundle flow.json --flow myFlow
# Bundle all flows
walkeros bundle flow.json --all
# Test specific flow
walkeros push flow.json --flow myFlow -e event.json --simulate destination.demo
# HTTP event collection server
walkeros run flow.json --port 3000
Server port note: The --port flag (or PORT env var) is forwarded at
runtime to all source configs that have a port setting. You don't need to
hardcode ports in the flow config — set port: 8080 as a default and let the
runtime override it.
{
"version": 4,
"flows": {
"default": {
"config": {
"platform": "web",
"bundle": {
"packages": {
"@walkeros/web-destination-gtag": {}
}
}
},
"destinations": {
"gtag": {
"package": "@walkeros/web-destination-gtag",
"config": { "measurementId": "G-XXXXXX" }
}
}
}
}
}
{
"version": 4,
"flows": {
"<flowName>": {
"config": {
"platform": "web" | "server", // Platform (required)
"settings": {}, // Platform-specific settings (optional)
"bundle": {
"packages": {}, // NPM packages pacote will install
"overrides": {}, // Transitive dep version pins (npm-style)
"traceInclude": [] // Optional: nft escape hatch (paths/globs)
}
},
"sources": {}, // Event sources
"destinations": {}, // Event destinations
"transformers": {}, // Transformer chain (optional)
"mappings": {}, // Event transformation rules
"collector": {} // Collector configuration
}
}
}
You do NOT need npm install for step packages. flow.json's
config.bundle.packages is the single source of truth. Pacote installs them
transparently when you run walkeros bundle. Only @walkeros/cli belongs in
your project's package.json (as a devDependency).
config.bundle.overrides pins transitive dependency versions. Use it when a
vendor SDK's declared peer/dep range conflicts with another required version in
the same tree. Example: {"@amplitude/analytics-types": "2.11.1"} forces that
exact version everywhere in the install graph. Direct packages specs always
win over overrides; overrides only substitute transitive resolution.
Schema version stays at 4. Build-time fields live under
flow.<name>.config.bundle.{packages, overrides, traceInclude}. The
flow.<name>.config.bundle.external sub-field is no longer supported in
@walkeros/cli@4.x.
For detailed configuration options, see flow-configuration.md.
--stepTarget a specific step and provide input as SourceInput
({ content, trigger? }):
# Simulate a source step with trigger metadata
walkeros push flow.json --simulate source.browser --event '{"content":"<html>...","trigger":{"type":"click"}}'
# Simulate a destination step with an event
walkeros push flow.json --simulate destination.gtag -e '{"entity":"order","action":"complete","data":{"total":149.97}}'
Example output:
Step: destinations.gtag
in: { name: "order complete", data: { id: "ORD-123", total: 149.97 } }
out: ["event", "purchase", { transaction_id: "ORD-123", value: 149.97 }]
Status: PASS
Validate schema, references, and cross-step example compatibility:
walkeros validate flow.json
All checks run automatically — schema validation, reference checking, and cross-step example compatibility. No flags needed for full validation.
For full details on writing and testing with step examples, see using-step-examples.
Embed JavaScript functions in JSON configs:
{
"fn": "$code:(event) => event.data.price * 100",
"condition": "$code:(event) => event.data?.value > 100"
}
Important: The CLI bundler converts $code: strings to actual JavaScript
functions during build. This is essential for mappings in JSON configs.
For mapping patterns, see understanding-mapping.
walkeros bundle <config> [options]
Options:
--flow <name> Bundle specific flow (default: "default")
--all Bundle all flows
--stats Show bundle statistics
--json JSON output
--no-cache Skip build cache
-v, --verbose Verbose output
-s, --silent Silent mode
Output:
dist/walker.js (single self-contained IIFE)dist/{flow.mjs, package.json, node_modules/} (always a directory;
nft-traced)Use -o ./dist/walker.js for web or -o ./dist/ for server.
walkeros push <config|bundle> [options]
Options:
-e, --event <json|file|url> Event to process (required)
--flow <name> Flow to use
-p, --platform <web|server> Platform override
--simulate <step> Simulate a step (repeatable for destination.*). Format: source.NAME | destination.NAME | transformer.NAME
--mock <step=value> Mock a step with a specific return value (repeatable)
--snapshot <source> JS file to eval before execution (sets global state)
walkeros validate <input> [options]
Options:
--type <type> Validation type (default: flow). Also: event, mapping, contract
--path <path> Validate entry against package schema (e.g. destinations.snowplow)
--flow <name> Flow name for multi-flow configs
--strict Treat warnings as errors
--json JSON output
Exit codes:
0 = Valid
1 = Errors found
2 = Warnings (with --strict)
3 = Input error
# HTTP event collection server
walkeros run <config|bundle> [options]
Options:
-p, --port <number> Port (default: 8080)
-h, --host <string> Host (default: 0.0.0.0)
include: ["./dist"] when output is dist/). The CLI detects this and
errors.settings resolve relative to the bundle, not the project root.gtag-wrapper cause
syntax errors — use gtagWrapper instead.arrify@^3.0.0 vs arrify@^2.0.0), the bundler
resolves the chosen range to a concrete version and nests non-satisfying specs
under their consumer. If a post-install warning surfaces declared-vs-installed
mismatches, pin the dep in config.bundle.overrides. Set
BUNDLER_STRICT_RANGES=0 to bypass strict range validation when the npm
registry is unreachable.Server flows are bundled with @vercel/nft.
The CLI:
flow.<name>.config.bundle.packages into a per-build install root. Users do
not run npm install for step packages; only @walkeros/cli lives in
their package.json.flow.mjs that imports from those
externalized packages.flow.mjs, finds every file actually reachable at runtime
(including __dirname-loaded .proto files and other assets), and copies
only those files into dist/node_modules/.There is no walkerOS.bundle.external annotation. nft figures it out.
Output shape (always a directory for server flows):
dist/
├── flow.mjs # ESM entry, expects to be at /app/flow/flow.mjs in prod
├── package.json # informational sidecar (not used by the runner)
└── node_modules/ # only the files nft traced
Web flows are unchanged: a single dist/walker.js.
FROM node:22-alpine AS builder
WORKDIR /build
RUN npm init -y && npm install --save-dev @walkeros/cli
COPY flow.json ./
RUN npx walkeros bundle flow.json -o dist/
FROM walkeros/flow:4
WORKDIR /app/flow
COPY --from=builder /build/dist/ ./
ENV PORT=8080
EXPOSE 8080
Notes:
@walkeros/cli. flow.json drives every step
package install; pacote handles it.COPY --from=builder /build/dist/ ./ copies the whole directory (flow.mjs +
package.json + node_modules/) into /app/flow/./app/flow/flow.mjs. No BUNDLE env var
needed.traceIncludeIf nft cannot statically reach a runtime asset (rare: require() of a path
constructed from a runtime variable), declare it explicitly under
flow.<name>.config.bundle.traceInclude. Paths and globs both work; both
resolve against the install root, not the project directory:
"flows": {
"default": {
"config": {
"platform": "server",
"bundle": {
"packages": { "@walkeros/server-destination-gcp": {} },
"traceInclude": [
"node_modules/some-pkg/data/*.json",
"node_modules/another-pkg/lib/runtime-loaded.js"
]
}
}
}
}
The bundler caches pacote downloads under process.env.NPM_CACHE_DIR (default
<tmpDir>/cache/npm). On CI, persist that path with actions/cache:
- uses: actions/cache@v4
with:
path: .walkeros-cache/npm
key: walkeros-${{ hashFiles('**/flow.json') }}
- run: WALKEROS_TMP_DIR=.walkeros-cache npx walkeros bundle flow.json -o dist/
CI smoke check:
cd dist && node -e "import('./flow.mjs').then(()=>console.log('ok'))" plus
du -sh node_modules (typical: 30-50MB for GCP destination, 10k+ files; use
.dockerignore).
walkeros validate flow.json --flowwalkeros cache clearwalkeros validate event.jsonwalkeros push flow.json -e event.json --simulate destination.demo -vIf --simulate destination.NAME errors with "not found in collector", the
destination likely has require: ["consent"] in its config. This delays
initialization until a walker consent event fires — which doesn't happen
during simulation.
Fix: Remove or comment out the require field for simulation testing:
{
"destinations": {
"gtag": {
"package": "@walkeros/web-destination-gtag",
"config": {
"settings": { "measurementId": "G-XXXXXX" }
}
}
}
}
If the destination is found but receives 0 events:
consent: { marketing: true }, the
event must include matching consent. Add to event JSON:
{ "name": "page view", "data": {...}, "consent": { "marketing": true } }Web simulations run in JSDOM. fetch and navigator.sendBeacon are polyfilled
as tracked no-ops -- no real HTTP requests are made. Captured network calls are
included in PushResult.networkCalls when present.
Use absolute or relative paths in flow.<name>.config.bundle.packages:
{
"config": {
"platform": "web",
"bundle": {
"packages": {
"my-destination": {
"path": "./local/my-destination"
}
}
}
}
}
The walkerOS app requires a newer @walkeros/cli version for the endpoint you
just called. Upgrade and retry:
npm install -g @walkeros/cli@latest
See Upgrading for the full version-negotiation rules.
| Location | Purpose |
|---|---|
packages/cli/ | CLI source code |
packages/cli/src/commands/ | Command implementations |
packages/cli/examples/ | Example flow configs |
packages/cli/README.md | Full CLI documentation |
Outbound requests to a configured WALKEROS_APP_URL carry an
X-Walkeros-Client: walkeros-cli/{version} header so the host can attribute
usage. No PII; the header is the only client identifier.
The CLI supports anonymous usage telemetry (installation id, command name, outcome, duration, environment) to help improve the tool. Telemetry is off by default and requires explicit opt-in. No persistent identifier is written before consent.
walkeros telemetry enable.walkeros telemetry disable.walkeros telemetry status.DO_NOT_TRACK=1 or
WALKEROS_TELEMETRY_DISABLED=1.WALKEROS_TELEMETRY_DEBUG=1 to print the payload to stderr
(requires opt-in; no network traffic).packages/cli/src/telemetry/flow.json.Detailed References: