walkerOS CLI
The walkerOS CLI (@walkeros/cli) is a command-line tool for building, testing, and running event collection flows. It handles the complete workflow from configuration to deployment. It bundles flows into optimized JavaScript, testing with simulated events, and running collection servers locally or in Docker.
Installation
Global Installation (Recommended)
Install globally to use the walkeros command anywhere:
Local Installation
Install in your project for team consistency:
Commands overview
| Command | Purpose | Use Case |
|---|---|---|
bundle | Build production-ready bundle from flow config | Create deployable JavaScript from configuration |
push | Execute event with real API calls (or --simulate for mocked) | Testing and production validation |
setup | Run the optional setup() lifecycle on one component | Provision external resources (BigQuery datasets, Pub/Sub topics, SQLite tables, webhook registrations) |
validate | Validate events, flows, mappings, contracts, or entries | Check configuration before bundling |
run | Start HTTP event collection server | Accept incoming events via HTTP POST |
cache | Manage CLI package and build caches | Clear stale caches, view cache statistics |
auth | Authentication and identity | Log in, log out, check identity |
projects | Manage walkerOS projects | Create, list, update, delete projects |
flows | Manage walkerOS flows | Create, list, update, delete, duplicate flows |
deploy | Create and manage deployments | Deploy flows to walkerOS cloud or self-hosted |
previews | Manage preview bundles | Test flow changes on live sites before deploying |
The push command accepts either a config JSON or a pre-built bundle as input.
Configuration types
The CLI uses types from @walkeros/core:
Flow.Json- Root config file format (version,flows)Flow- Single flow (hasconfig,sources,destinations,transformers,collector)Flow.Config- Per-flow config block (platform,url,settings,bundle)Collector.InitConfig- Runtime type passed tostartFlow()
The CLI transforms Flow.Json → Flow (per flow) → bundled code that uses Collector.InitConfig at runtime.
Packages and overrides
Build-time concerns live under each flow's config.bundle block. Three fields are supported:
packages: the list of npm packages (or local paths) the bundler should install for this flow. Pacote downloads them based on this list. You do not need to runnpm installyourself for step packages; the CLI handles it transparently.overrides: pin transitive dependency versions, matching npm'soverridessemantics. Useful when an upstream package declares an overly narrow version range that conflicts with a newer transitive version in the same tree.traceInclude(server flows only): an escape hatch for the file tracer. See below.
Server bundles use nft tracing
Server flows (platform: "server") are traced automatically with @vercel/nft. The bundler externalizes every step package, then nft walks the entry to figure out which files are actually reachable at runtime, and copies only those files into dist/node_modules/. Native add-ons, .proto files, and __dirname-loaded assets are picked up.
There is no walkerOS.bundle.external annotation: nft figures out the externalization automatically.
Escape hatch: traceInclude
If nft cannot statically reach a file (rare: dynamic require(somePath) constructed from a runtime variable, dynamically loaded data files), declare it explicitly with flow.<name>.config.bundle.traceInclude. Paths and globs are both supported (matched via picomatch). Paths resolve against the install root, not your project directory.
Range conflict resolution
When two transitive consumers declare incompatible ranges for the same dependency (e.g., arrify@^3.0.0 from one package, arrify@^2.0.0 from another), the bundler now resolves the chosen range to a concrete version via the npm registry and nests any non-satisfying spec under its consumer's node_modules/. This kills classes of upstream chaos (like arrify is not a function from @google-cloud/common) before they can reach runtime. After install, a defense-in-depth check warns when any installed package's declared deps don't match what's reachable on its resolution path; if you see those warnings, add an overrides entry to your flow's config.bundle.overrides to pin the offending dep. If the npm registry is unreachable during validation, set BUNDLER_STRICT_RANGES=0 to bypass strict validation with a warning instead of failing the build.
Schema version
The flow.json schema stays at version: 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.
Package imports
Implicit collector
The collector is added automatically. To pin a specific version (recommended for production), add the collector explicitly:
Default exports (sources & destinations)
Sources and destinations automatically use their default export - no imports needed:
Utility imports
Use imports when you need specific utility functions from a package:
Named-export selection with import
For packages without a default export, or to pick a specific named export, set import on the step alongside package. The bundler adds the name to the imports list automatically.
The legacy code: "namedExport" form is no longer accepted. Validation raises OBSOLETE_CODE_STRING with a rename hint pointing to import.
Local packages
By default, the CLI downloads packages from npm. For development or testing unpublished packages, you can use local packages instead by specifying a path property.
Configuration
Add a path property to any package to use a local directory instead of npm:
Resolution Rules
pathtakes precedence - When bothpathandversionare specified,pathis used- Relative paths - Resolved relative to the config file's directory
- Absolute paths - Used as-is
- dist folder - If a
dist/folder exists, it's used; otherwise the package root is used
Dependency Resolution
When a local package has dependencies on other packages that are also specified with local paths, the CLI will use the local versions for those dependencies too. This prevents npm versions from overwriting your local packages.
In this example, even though @walkeros/collector depends on @walkeros/core, the local version of core will be used (not downloaded from npm). This is essential when testing changes across multiple interdependent packages.
Use Cases
Development of custom packages:
Testing local changes to walkerOS packages:
When ready for production, simply remove the path property to use the published npm version.
Getting started
Before using the CLI, you need a flow configuration file. Here's a minimal example:
The @walkeros/collector package is automatically added when your flow has sources or destinations.
Save this as flow.json.
Bundle command
The bundle command builds production-ready JavaScript bundles from flow configurations.
Use Case
You've defined your sources, destinations, and transformations in a flow configuration file. Now you need to:
- Download the required npm packages
- Bundle everything into a single optimized JavaScript file
- Deploy it to production (Docker, Cloud Run, serverless functions)
The bundle command handles all of this.
Basic Usage
This writes the optimized bundle to stdout (web flows only). Use -o to write to a file or directory (e.g., -o ./dist/walker.js for web, -o ./dist/ for server, which produces dist/{flow.mjs, package.json, node_modules/}).
Step-by-Step Guide
1. Create a flow configuration
Create server-collect.json:
2. Bundle the flow
Output:
📦 Downloading packages from npm...
✓ @walkeros/collector@latest
✓ @walkeros/server-source-express@latest
✓ @walkeros/destination-demo@latest
🔨 Bundling...
✓ Bundle created: ./dist/flow.mjs
📊 Bundle Statistics:
Size: 45.2 KB (minified)
Packages: 3
Format: ESM
3. Review the bundle
The bundle is now ready to deploy!
Options
| Option | Description |
|---|---|
-o, --output <path> | Write bundle to file, directory, or presigned URL |
-f, --flow <name> | Build specific flow (for multi-flow configs) |
--all | Build all flows |
-s, --stats | Show bundle statistics |
--json | Output statistics as JSON (for CI/CD) |
--no-cache | Skip package cache, download fresh |
-v, --verbose | Detailed logging |
When --output is a URL (e.g., a presigned S3 URL), the CLI bundles to a temp file and uploads via HTTP PUT. This is used by the walkerOS cloud service for remote builds.
For server flows, -o resolves to a directory: dist/{flow.mjs, package.json, node_modules/}. For multi-flow --all, each flow gets its own subdirectory: dist/<flowName>/....
Multi-Flow Example
Push command
The push command executes your flow with a real event. By default it makes actual API calls to your configured destinations. Use --simulate to mock specific steps for safe testing. It accepts either a config JSON (which gets bundled) or a pre-built bundle.
Use Case
You want to:
- Test event processing with mocked destinations (
--simulate) - Test with real third-party APIs (GA4, Meta, BigQuery, etc.)
- Verify production credentials and endpoints work
- Debug actual API responses and errors
- Perform integration testing before deployment
- Execute a pre-built bundle without rebuilding
Push handles both safe local testing (with --simulate) and real integration testing.
Basic Usage
Step-by-Step Guide
1. Create a flow configuration
Create api-flow.json with a destination that makes real HTTP calls:
2. Create an event file
Create event.json:
3. Push the event
4. Review the output
📥 Loading event...
📦 Loading flow configuration...
🔨 Bundling flow configuration...
🖥️ Executing in server environment (Node.js)...
Pushing event: order complete
✅ Event pushed successfully
Event ID: 1701234567890-abc12-1
Entity: order
Action: complete
Duration: 1234ms
The event was sent to your real API endpoint!
Options
| Option | Description |
|---|---|
-e, --event <source> | Required. Event to push (JSON string, file path, or URL) |
-f, --flow <name> | Flow name (for multi-flow configs) |
-p, --platform <platform> | Platform override (web or server) |
--simulate <step> | Simulate a step (repeatable). Mocks the step's push, captures result. Use destination.NAME or source.NAME. |
--mock <step=value> | Mock a step with a specific return value (repeatable). Use destination.NAME=VALUE. |
--snapshot <source> | JS file to eval before execution. Sets global state (window.dataLayer, process.env, etc.). |
-o, --output <path> | Write result to file |
--json | Output results as JSON |
-v, --verbose | Verbose output with debug information |
-s, --silent | Suppress output (for CI/CD) |
Input Types
The CLI auto-detects the input type by attempting to parse as JSON:
- Config JSON - Bundled and executed
- Pre-built bundle (
.js/.mjs) - Executed directly
When using pre-built bundles, platform is detected from file extension:
.mjs→ server (ESM, Node.js).js→ web (IIFE, JSDOM)
Use --platform to override if extension doesn't match intended runtime.
Event Input Formats
The --event parameter accepts three formats:
Inline JSON string:
File path:
URL:
Push modes
| Mode | Flag | API Calls | Use Case |
|---|---|---|---|
| Real | (none) | Real HTTP requests | Integration testing, production validation |
| Simulate | --simulate | Mocked (captured) | Safe local testing |
| Mock | --mock | Returns mock value | Controlled testing |
Recommended workflow:
- Use
push --simulatefirst to validate configuration without side effects - Use
push(without flags) to verify real integrations work before deployment
JSON Output
For CI/CD pipelines, use --json for machine-readable output:
Output:
{
"success": true,
"event": {
"id": "1701234567890-abc12-1",
"name": "page view",
"entity": "page",
"action": "view"
},
"duration": 1234
}
On error:
{
"success": false,
"error": "Connection refused: https://your-endpoint.com/events",
"duration": 5023
}
Multi-Flow
Push to specific flows:
Setup command
The setup command runs the optional setup() lifecycle on a single component to provision external resources before traffic flows. Use it for one-time provisioning steps like creating a BigQuery dataset and table, declaring a Pub/Sub topic and subscription, creating SQLite tables, or registering a webhook with a third-party API.
For the conceptual overview of the lifecycle (when to implement setup() in a component, how it relates to the runtime hot path, and the operator separation rationale), see Setup lifecycle.
Use case
Setup is for the operator-time, "do this once before traffic" step that sits between writing config and accepting events:
- A BigQuery destination needs its dataset and table to exist with the right schema before rows can be streamed in.
- A Pub/Sub source needs a subscription against a topic before it can pull messages.
- A SQLite store needs its tables created before reads and writes work.
- A webhook integration needs to register its callback URL with the upstream service.
Setup is explicit only. It is never triggered by push, simulate, deploy, or the long-running runtime. You run it once when provisioning, then again only when external resources need to be re-provisioned (for example, after changing the table schema in config). The runtime never tries to "fix" missing resources on its own.
Basic usage
Target syntax
The target uses the same <kind>.<name> syntax as walkeros push --simulate. Valid kinds are source, destination, and store. Transformers are pure functions and have no setup.
| Target | Resolves to |
|---|---|
destination.bigquery | The destination named bigquery in the resolved flow |
source.events-in | The source named events-in |
store.session | The store named session |
Options
| Option | Description |
|---|---|
-c, --config <path> | Flow config file (default: ./flow.json) |
-f, --flow <name> | Flow name for multi-flow configs |
--json | Output as JSON (passed to the package's setup logger) |
-v, --verbose | Verbose output |
-s, --silent | Suppress output |
What "skip" means
The framework narrates one of three reasons when nothing runs and exits successfully:
| Reason | Trigger |
|---|---|
no setup function | The package does not export a setup function on its default export |
config.setup is false | The flow config explicitly opts out with "setup": false |
config.setup is unset | The flow config does not declare setup at all |
In all three cases the exit code is 0. Setup is a single-purpose command, not a tiered status check.
Result output
When the package's setup() returns a non-undefined value, the CLI emits it as JSON on stdout for jq-style scripting. This lets you script around what was provisioned:
If the package returns nothing, no JSON is emitted; you only see the framework narration.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success or skip (any of the three skip reasons above) |
| non-zero | Failure (resolution error, missing default export, package threw) |
IAM note
Setup typically needs higher permissions than runtime push: "create dataset" or "create subscription" vs "write rows" or "pull messages". Operators commonly run setup with a separate service account, or different credentials, than the runtime uses. Plan your IAM accordingly: grant the runtime only what it needs to push, and grant setup the broader provisioning scope.
Examples
Validate command
The validate command checks the structure and correctness of events, flow configurations, mapping configurations, contracts, or individual flow entries before bundling or deployment.
Use case
Before bundling or deploying your flow, you want to:
- Catch configuration errors early
- Verify event structure follows walkerOS conventions
- Check mapping patterns are valid
- Validate contracts define proper entity-action schemas
- Validate a specific destination, source, or transformer entry against its package's published JSON Schema
- Integrate validation into CI/CD pipelines
Validate gives you fast feedback without the overhead of bundling.
Basic usage
Validation types
The --type option accepts four validation types. Default is flow:
| Type | What it validates |
|---|---|
event | Event structure: name field exists, follows "entity action" format with space, valid data types |
flow (default) | Flow.Json config: schema, references, packages, and cross-step example compatibility |
mapping | Mapping rules: event patterns use "entity action" or wildcard format, rule structures are valid |
contract | Contract structure: entity-action entries map to JSON Schema objects, optional $tagging metadata |
Use --path for entry validation against package schemas (e.g., --path destinations.snowplow).
Step-by-step guide
1. Validate a flow configuration
Output (valid):
Validating flow...
Validation Results:
✓ All checks passed
Summary: 0 error(s), 0 warning(s)
2. Validate with errors
Output:
Validating event...
Validation Results:
✗ name: Event name must be "entity action" format with space (e.g., "page view")
Summary: 1 error(s), 0 warning(s)
3. Validate with warnings
Output:
Validating event...
Validation Results:
✓ All checks passed
⚠ consent: No consent object provided
→ Consider adding a consent object for GDPR/privacy compliance
Summary: 0 error(s), 1 warning(s)
Options
| Option | Description |
|---|---|
-t, --type <type> | Validation type (default: flow). Also: event, mapping, contract |
--path <path> | Validate a specific entry against its package schema (e.g., destinations.snowplow) |
-f, --flow <name> | Flow name to validate (for multi-flow configs) |
-o, --output <path> | Write result to file |
--strict | Treat warnings as errors (exit code 2) |
--json | Output results as JSON |
-v, --verbose | Show detailed validation information |
-s, --silent | Suppress banner output |
Exit codes
| Code | Meaning |
|---|---|
| 0 | Valid (no errors) |
| 1 | Validation errors found |
| 2 | Warnings found (with --strict) |
| 3 | Input error (file not found, invalid JSON, etc.) |
CI/CD integration
Use --json and exit codes for automated pipelines:
JSON output format:
{
"valid": true,
"type": "flow",
"errors": [],
"warnings": [
{
"path": "packages.@walkeros/destination-demo",
"message": "Package \"@walkeros/destination-demo\" has no version specified",
"suggestion": "Consider specifying a version for reproducible builds"
}
],
"details": {
"flowNames": ["default"],
"flowCount": 1,
"packageCount": 2
}
}
Multi-flow validation
Validate a specific flow in a multi-flow configuration:
If the flow doesn't exist:
Validation Results:
✗ flows: Flow "production" not found. Available: default, staging
Summary: 1 error(s), 0 warning(s)
Event validation details
Event validation checks (see event.ts):
- Name field exists - Required field
- Name is non-empty - Cannot be empty string
- Entity-action format - Must contain space (e.g.,
"page view"not"pageview") - Schema validation - Data types match expected structure
- Best practices - Warns if consent object is missing
Mapping validation details
Mapping validation checks (see mapping.ts):
- Object structure - Must be an object with event patterns as keys
- Event patterns - Must be
"entity action"format or contain wildcard (*) - Rule structure - Each rule must be an object or array of objects
- Catch-all position - Warns if
*is not the last pattern
Contract validation details
Contract validation checks (see contract.ts):
- Root structure - Must be an object (not array or primitive)
$taggingmetadata - If present, must be a non-negative integer- Entity keys - Cannot be empty strings
- Action entries - Each entity must contain an object of action entries
- Schema entries - Each action value must be a JSON Schema object
Entry validation (--path)
Entry validation checks a specific destination, source, or transformer in your flow config against the package's published JSON Schema. The CLI fetches the schema from the package on the CDN and validates the config.settings object using AJV.
The entry validator:
- Resolves the entry from the flow config (first flow is used)
- Reads the
packagefield to identify the npm package - Fetches the package's JSON Schema from the CDN
- Validates the entry's
config.settingsagainst the schema
Auth commands
The auth command group manages authentication with the walkerOS cloud service. Authentication is required for cloud commands (projects, flows, deploy).
Login
Log in to walkerOS via an OAuth browser flow. The CLI requests a device code, opens your browser for authorization, and polls for the resulting token.
Output:
! Your one-time code: ABCD-1234
Authorize here: https://app.walkeros.io/auth/device?code=ABCD-1234
Opening browser...
Waiting for authorization... (press Ctrl+C to cancel)
✓ Logged in as user@example.com
Token stored in ~/.config/walkeros/config.json
The token is stored in ~/.config/walkeros/config.json with 0600 permissions. You can also set the WALKEROS_TOKEN environment variable instead of using auth login.
| Option | Description |
|---|---|
--url <url> | Custom app URL (default: https://app.walkeros.io) |
--json | Output as JSON |
-v, --verbose | Verbose output |
-s, --silent | Suppress output |
Logout
Remove stored credentials from disk.
| Option | Description |
|---|---|
--json | Output as JSON |
-v, --verbose | Verbose output |
-s, --silent | Suppress output |
Whoami
Show the current authenticated user's identity, including email, user ID, and project ID (if the token is project-scoped).
Output:
user@example.com
User: usr_abc123
Project: proj_def456
| Option | Description |
|---|---|
-o, --output <path> | Write result to file |
--json | Output as JSON |
-v, --verbose | Verbose output |
-s, --silent | Suppress output |
Token resolution
The CLI resolves authentication tokens in this order:
WALKEROS_TOKENenvironment variable- Config file (
~/.config/walkeros/config.json, written byauth login) - Not authenticated (cloud commands will fail)
Projects commands
The projects command group manages walkerOS cloud projects. All commands require authentication (see Auth commands).
List projects
| Option | Description |
|---|---|
--cursor <c> | Resume from a pagination cursor returned by a previous list call |
--limit <n> | Maximum number of projects to return |
Get project details
Create a project
Update a project
Delete a project
Common options
All projects subcommands support:
| Option | Description |
|---|---|
-o, --output <path> | Write result to file |
--json | Output as JSON |
-v, --verbose | Verbose output |
-s, --silent | Suppress output |
Flows commands
The flows command group manages flow configurations within a project. All commands require authentication and a project context (either --project or WALKEROS_PROJECT_ID).
List flows
| Option | Description |
|---|---|
--project <id> | Project ID (defaults to WALKEROS_PROJECT_ID) |
--cursor <c> | Resume from a pagination cursor returned by a previous list call |
--limit <n> | Maximum number of flows to return |
--sort <field> | Sort by: name, updated_at, created_at |
--order <dir> | Sort order: asc, desc |
--include-deleted | Include soft-deleted flows |
Get a flow
Retrieves a flow with its full Flow.Json content.
| Option | Description |
|---|---|
--project <id> | Project ID (defaults to WALKEROS_PROJECT_ID) |
Create a flow
| Option | Description |
|---|---|
--project <id> | Project ID (defaults to WALKEROS_PROJECT_ID) |
-c, --content <json> | Flow.Json string or file path |
Update a flow
| Option | Description |
|---|---|
--project <id> | Project ID (defaults to WALKEROS_PROJECT_ID) |
--name <name> | New flow name |
-c, --content <json> | New Flow.Config JSON string or file path |
Delete a flow
Soft-deletes a flow configuration.
Duplicate a flow
Creates a copy of an existing flow configuration.
| Option | Description |
|---|---|
--project <id> | Project ID (defaults to WALKEROS_PROJECT_ID) |
--name <name> | Name for the copy (defaults to "Copy of ...") |
Common options
All flows subcommands support:
| Option | Description |
|---|---|
-o, --output <path> | Write result to file |
--json | Output as JSON |
-v, --verbose | Verbose output |
-s, --silent | Suppress output |
Deploy commands
The deploy command group handles deploying flows to the walkerOS cloud or managing self-hosted deployments with heartbeat registration. All commands require authentication.
deploy create
Create a new deployment. The CLI infers the deployment type (web or server) from the flow configuration.
On success, the CLI displays the deployment ID, slug, type, and a one-time deploy token. It also shows example commands for running the deployment locally or via Docker.
| Option | Description |
|---|---|
--label <string> | Human-readable label for the deployment |
-f, --flow <name> | Flow name for multi-flow configs |
--project <id> | Project ID (defaults to WALKEROS_PROJECT_ID) |
-o, --output <path> | Write result to file |
--json | Output as JSON |
-v, --verbose | Verbose output |
-s, --silent | Suppress output |
deploy start
Deploy a remote flow to walkerOS cloud infrastructure. Auto-detects whether to use web (script hosting) or server (container) deployment based on the flow content. Streams deployment progress via SSE.
Output (web deployment):
Building bundle...
Publishing to web...
✓ Published: https://cdn.walkeros.io/proj_xxx/walker.js
Output (server deployment):
Building bundle...
Deploying container...
Starting container...
✓ Active: https://collect-abc123.walkeros.io
| Option | Description |
|---|---|
--project <id> | Project ID (defaults to WALKEROS_PROJECT_ID) |
-f, --flow <name> | Flow name for multi-config flows |
--no-wait | Return immediately after triggering (do not stream progress) |
--timeout <seconds> | Timeout for deployment polling (default: 120) |
-o, --output <path> | Write result to file |
--json | Output as JSON |
-v, --verbose | Verbose output |
-s, --silent | Suppress output |
deploy list
List all deployments in a project.
| Option | Description |
|---|---|
--project <id> | Project ID (defaults to WALKEROS_PROJECT_ID) |
--cursor <c> | Resume from a pagination cursor returned by a previous list call |
--limit <n> | Maximum number of deployments to return |
--type <type> | Filter by type: web, server |
--status <status> | Filter by status |
deploy status
Get deployment details by ID or slug.
| Option | Description |
|---|---|
--project <id> | Project ID |
deploy delete
Delete a deployment by ID or slug.
| Option | Description |
|---|---|
--project <id> | Project ID |
--json | Output as JSON |
Common options
All deploy subcommands support:
| Option | Description |
|---|---|
-o, --output <path> | Write result to file |
--json | Output as JSON |
-v, --verbose | Verbose output |
-s, --silent | Suppress output |
Previews command
The previews command group manages preview bundles — short-lived flow bundles
used to test configuration changes on a real production site before deploying.
Each preview gets a short token; visiting any page of your site with
?elbPreview={token} activates preview mode for that browser (7-day cookie).
All commands require authentication and a project (set via WALKEROS_PROJECT_ID
or --project).
previews list
List all previews for a flow.
| Option | Description |
|---|---|
--project <id> | Project ID (overrides default) |
previews get
Get details for a single preview.
| Option | Description |
|---|---|
--project <id> | Project ID (overrides default) |
previews create
Create a preview bundle for a specific flow settings entry.
| Option | Description |
|---|---|
-f, --flow <name> | Flow settings name (resolved to an ID) |
-s, --settings-id <id> | Flow settings ID (alternative to --flow) |
-u, --url <siteUrl> | Your site URL; prints a ready-to-open activation URL on stdout |
--project <id> | Project ID (overrides default) |
Without --url, the CLI prints the activation fragment (?elbPreview=...) to
stdout — append it to any URL on your site to activate preview mode. With
--url, it prints the full {siteUrl}?elbPreview={token} URL, plus a
deactivation URL on stderr. Most modern terminals make the URL clickable.
You must provide either --flow or --settings-id to pick which flow settings
the preview should bundle.
previews delete
Delete a preview. Removes both the DB row and the S3 bundle immediately; the
production walker on visitors' browsers self-heals on the next page load by
clearing the elbPreview cookie and loading the production flow.
| Option | Description |
|---|---|
-y, --yes | Skip confirmation (required to run non-interactively) |
--project <id> | Project ID (overrides default) |
Example
Run command
The run command starts an HTTP server that accepts events and processes them through your flow.
Use Case
You need an HTTP endpoint to:
- Receive events from browser clients, mobile apps, or server-side sources
- Process events through your collector and destinations
- Test the full event pipeline locally before deploying to production
This is similar to running a Segment or Jitsu collection endpoint.
Basic Usage
Step-by-Step Guide
1. Create a collection flow
Create collect.json:
2. Start the collector
Output:
📦 Bundling flow...
✓ Bundle ready
🚀 Starting collection server...
✓ Server running on http://localhost:8080
✓ Endpoint: POST http://localhost:8080/collect
✓ Health check: GET http://localhost:8080/health
3. Send test events
Open a new terminal and send events:
4. See events in console
The collector terminal shows:
[Event Collector] page view
data: {"title":"Home Page","path":"/"}
user.id: user123
timestamp: 1701234567890
[Event Collector] product view
data: {"id":"P123","name":"Laptop","price":999}
timestamp: 1701234567891
Options
| Option | Description |
|---|---|
-p, --port <number> | Server port (default: 8080) |
-h, --host <address> | Host address (default: 0.0.0.0) |
--deploy <id-or-slug> | Deployment ID or slug (enables heartbeat to walkerOS cloud) |
--project <id> | Project ID (used with --deploy) |
--url <url> | Public URL of this server (used with --deploy) |
--health-endpoint <path> | Health check path (default: /health) |
--heartbeat-interval <seconds> | Heartbeat interval in seconds (default: 60) |
--json | Output as JSON |
-v, --verbose | Detailed logging |
-s, --silent | Suppress output |
Heartbeat registration
When --deploy is provided, the collector registers itself with the walkerOS cloud via periodic heartbeats. This makes the running instance visible in the project dashboard and enables remote management.
The heartbeat sends instance ID, uptime, CLI version, and mode. The server can respond with update (triggering a bundle refresh) or stop (graceful shutdown).
Running Pre-Built Bundles
You can also run pre-built bundles directly:
Complete example: Web → Server flow
This example demonstrates a complete analytics pipeline:
- Browser events captured by web flow
- Sent to server collection endpoint
- Logged to console (swap for BigQuery in production)
1. Create Server Collection Flow
Create server-collect.json:
2. Create Web Tracking Flow
Create web-track.json:
3. Start Collection Server
Terminal 1:
4. Start Web Server
Terminal 2:
5. Test in Browser
Create demo.html:
Open in browser. Terminal 1 shows:
[Server Logger] page view
[Server Logger] promotion view
[Server Logger] promotion cta
[Server Logger] custom event
Cache command
The cache command manages the CLI's package and build caches.
Use Case
The CLI caches downloaded npm packages and compiled builds to speed up repeated operations. You may need to:
- Clear stale cached packages when debugging version issues
- Free up disk space by removing old cached builds
- View cache statistics to understand cache usage
How Caching Works
Package Cache (.tmp/cache/packages/):
- Mutable versions (
latest,^,~) are re-checked daily - Exact versions (
0.4.1) are cached indefinitely - Saves network time on repeated builds
Build Cache (.tmp/cache/builds/):
- Caches compiled bundles based on flow.json content + date
- Identical configs reuse cached builds within the same day
- Dramatically speeds up repeated builds (~100x faster)
Basic Usage
Commands
View cache info:
Output:
Cache directory: .tmp/cache
Cached packages: 12
Cached builds: 5
Clear all caches:
Clear only package cache:
Clear only build cache:
Bypassing Cache
To skip the cache for a single build operation:
This downloads fresh packages and rebuilds without using or updating the cache.
Options
| Option | Description |
|---|---|
--packages | Clear only the package cache |
--builds | Clear only the build cache |
Global options
These options work with all commands:
| Option | Description |
|---|---|
--verbose | Show detailed logs |
--silent | Suppress output |
--json | Output as JSON (for CI/CD) |
--help | Show help for command |
--version | Show CLI version |
Environment variables
| Variable | Purpose |
|---|---|
WALKEROS_TOKEN | API token for cloud commands (overrides auth login config) |
WALKEROS_PROJECT_ID | Default project ID for projects, flows, and deploy commands |
WALKEROS_APP_URL | Base URL override (default: https://app.walkeros.io) |
WALKEROS_DEPLOY_TOKEN | Deploy token for container heartbeat authentication |
WALKEROS_CLIENT_TYPE | Override client identity sent to the app. Defaults to cli; set to runner for long-lived flow runners. Used by the runtime image. |
API version compatibility
Official clients (CLI, MCP, runner image) send three headers on every request to the walkerOS app so the server can tell them apart and enforce minimum versions per endpoint:
User-Agent: e.g.walkeros-cli/1.4.0 (node/18.19.0; linux)X-WalkerOS-Client:cli,mcp, orrunnerX-WalkerOS-Client-Version: the installed package version
If you call an endpoint that has been updated in a way that requires a newer
client, the app responds with 426 Upgrade Required. The CLI prints the
required minimum version and the upgrade command, then exits with code 2:
Error: This walkerOS app endpoint requires @walkeros/cli >= 1.5.0
(you have 1.4.0). Upgrade with: npm install -g @walkeros/cli@latest
See https://walkeros.io/docs/upgrading for details.
The MCP server surfaces the same information in tool error responses so AI assistants can tell the user to upgrade. See Upgrading for the full version-negotiation rules.
Set WALKEROS_CLIENT_TYPE=runner to identify the CLI binary as a long-lived
flow runner instead of an interactive CLI session. The official runner Docker
image sets this automatically.
CI/CD integration
GitHub Actions
Docker Build
The canonical multi-stage Dockerfile installs the CLI in the build stage, bundles the flow into a dist/ directory, then copies the directory into the runtime image. You do not need to declare step packages in package.json; pacote installs them transparently from flow.json.
Troubleshooting
Package Download Issues
If packages fail to download:
Build Issues
If you encounter build issues:
Port Already in Use
If the port is already in use:
Authentication Issues
If cloud commands fail with authentication errors:
nft cannot trace a runtime asset
If a runtime asset is missing in dist/node_modules/ (typically because the dep loads it via a dynamically constructed path), declare it explicitly under the flow's config.bundle.traceInclude. Paths and globs both work, resolved against the install root:
Caching pacote downloads in CI
The bundler caches downloads under process.env.NPM_CACHE_DIR (default
<tmpDir>/cache/npm). On CI, persist that path with actions/cache:
Bundle output is large
dist/node_modules/ for a server flow with the GCP destination typically holds 30-50MB across 10k+ files (grpc, protobufjs, etc.). Recommendations:
- Use
.dockerignoreto exclude irrelevant build output from non-bundle contexts. - Prefer
COPY --from=builder /build/dist/ /app/flow/over file-by-file in your Dockerfile. - Expect ~30s artifact upload time on slow CI.
Next steps
- Flow Configuration - Learn about flow config structure
- Docker Deployment - Deploy flows to production
- Runner - Self-hosted runner with config polling and hot-swap
- MCP Server - Use CLI tools from AI assistants
- Sources - Explore event sources
- Destinations - Configure analytics tools
- Mapping - Transform events for destinations
See Also
Using Integrated mode instead? The CLI uses JSON configuration (Bundled mode). If you prefer TypeScript and want the collector built into your application, see Integrated Mode and the Collector documentation.
Both approaches use the same underlying architecture. The difference is how you configure and deploy.