بنقرة واحدة
walkeros-writing-documentation
// Use when writing or updating walkerOS documentation - README, website docs, or skills. Covers quality standards, example validation, and DRY patterns.
// Use when writing or updating walkerOS documentation - README, website docs, or skills. Covers quality standards, example validation, and DRY patterns.
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 bundling walkerOS flows, testing events with simulate/push, running local servers, validating configs, or configuring Flow JSON files.
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 learning walkerOS architecture, understanding data flow, or designing composable event pipelines. Covers Source→Collector→Destination pattern and separation of concerns.
| name | walkeros-writing-documentation |
| description | Use when writing or updating walkerOS documentation - README, website docs, or skills. Covers quality standards, example validation, and DRY patterns. |
| Type | Purpose | Audience |
|---|---|---|
| Package README | Installation, basic usage, API reference | Package users |
| Website docs | Guides, integration examples, detailed config | Integrators |
| Skills | Process knowledge, workflows | AI assistants, contributors |
Keep these separate - don't mix tutorials with reference:
| Type | Purpose | User State |
|---|---|---|
| Tutorial | Learning | Studying, beginner |
| How-To Guide | Problem-solving | Working, knows what they need |
| Reference | Information lookup | Working, needs facts |
| Explanation | Understanding | Studying, needs context |
AI-generated examples can be:
TIER 1: apps/quickstart/
✓ Tested ✓ Compiled ✓ CI-validated
→ USE FOR: All code examples
TIER 2: packages/core/src/eventGenerator.ts
✓ Canonical events ✓ Real data structures
→ USE FOR: Event examples
TIER 3: packages/*/src/index.ts exports
✓ Actual public API
→ USE FOR: Verifying API names exist
TIER 4: Package READMEs & Website docs
⚠ May contain errors
→ VERIFY against Tier 1-3 before trusting
Before publishing ANY code example:
packages/*/src/index.ts exportsapps/quickstart/eventGenerator.ts| Red Flag | What It Indicates |
|---|---|
| API name not in package exports | Hallucinated or outdated API |
| Import path doesn't match package.json | Wrong package reference |
| Event name with underscore | Wrong format (should be space) |
| No imports shown | Context missing, harder to validate |
When to use: Every package page for destinations, sources, transformers, and
stores. The <Configuration> snippet owns the ## Configuration,
## Settings, ## Mapping, and ## Examples H2 sections. One callsite per
page, after ## Installation.
import data from '@walkeros/web-destination-gtag/walkerOS.json';
import Configuration from '@site/src/components/snippets/_configuration.mdx';
## Installation
<CodeSnippet
code={`npm install @walkeros/web-destination-gtag`}
language="bash"
/>
<Configuration type="destination" data={data} />
type must be one of destination, source, transformer, store. data is
the full walkerOS.json import. The snippet:
## Configuration with a short pointer to the shared group-level
configuration reference,## Settings using <PropertyTable schema={data.schemas.settings} />
when the schema is present, otherwise a "no package-specific settings" note,## Mapping using <PropertyTable schema={data.schemas.mapping} />
when present, otherwise a pointer to the standard rule fields,## Examples only if data.examples.env.init or data.examples.step.*
is present; iterates examples.step and renders each through <StepExample>.Never hand-roll ## Configuration, ## Settings, ## Mapping, or
## Examples on a package page. Place package-specific content (vendor quirks,
advanced usage, platform-specific setup) BELOW the <Configuration> block with
its own sentence-case H2 heading. Fold ## Features bullet lists into the intro
paragraph as prose — no ## Features heading on package pages.
On group index pages (docs/destinations/index.mdx, sources/index.mdx,
transformers/index.mdx, stores/index.mdx), add a ## Configuration section
that documents the wrapper fields around settings — fields shared across all
packages of that type (consent, mapping, env, id, …).
Drive the table from the core Zod schemas, filtering dev-only fields at the representation layer:
import { schemas } from '@walkeros/core/dev';
import { omitSchemaProperties } from '@site/src/utils/schema';
export const destinationConfig = omitSchemaProperties(
schemas.DestinationSchemas.configJsonSchema,
['settings', 'init', 'mock', 'onError', 'onLog'],
);
## Configuration
<PropertyTable schema={destinationConfig} />
Available schemas:
schemas.DestinationSchemas.configJsonSchemaschemas.SourceSchemas.configJsonSchemaschemas.TransformerSchemas.configJsonSchemaschemas.StoreSchemas.configJsonSchemaUse omitSchemaProperties to hide settings (documented per-package) and any
dev-only fields (init, mock, chainMocks, onError, onLog) from the
user-facing table.
@walkeros/explorer exports two components for code display:
<CodeBox> renders Monaco, the full editor. Use when the user can edit
the code (playgrounds, interactive demos). Ships the IDE.<CodeView> renders Shiki, read-only. Use for static code in docs,
marketing pages, and anywhere editing is not a requirement. Same <Box> frame
as <CodeBox> (traffic lights, header, copy button, tabs) so visuals match.
Zero Monaco runtime cost.Tokens match because Shiki uses the same TextMate grammars as VS Code / Monaco,
with the matching dark-plus / light-plus themes.
Rule: default to <CodeView>. Only reach for <CodeBox> when the code must
be editable.
<PropertyTable schema={...} /> from @walkeros/explorer is the primitive. It
renders a pure table — no heading, no captions. Never wrap it in a custom
heading on package pages; use the <Settings /> snippet instead.
When NOT to use:
Every destination/source should export schemas:
// src/dev.ts
export * as schemas from './schemas';
export * as examples from './examples';
apps/quickstart/ examples instead of writing from scratchsrc/hints.ts)Hints are the "experienced colleague" layer in walkerOS.json — they tell AI
agents when, why, and what to watch out for beyond what schemas and
examples convey. Surfaced via MCP package_get. Not human-facing docs.
Audience: AI agents configuring packages on behalf of users.
Hints should open up the space of what's possible, not prescribe a single path. An LLM reading hints should think "I have more options than I realized" — not "I must follow these steps exactly."
| Rule | Do | Don't |
|---|---|---|
| Describe capabilities | "Supports SA key, ADC, and custom client" | "Use a SA key file when outside GCP" |
| Reference schemas/examples | "See settings.projectId in the schema" | Repeat what the schema description says |
| Explain why behind defaults | "Defaults to EU location; override via location" | "Set location to US" |
| Flag non-obvious interactions | "When snakeCase: true, all data keys transform before send" | Describe obvious behavior |
| Symptoms → causes | "Empty table? Check projectId and dataset existence" | Step-by-step fix instructions |
auth-*, storage-*,
query-*, troubleshoot-*auth-methods not a1Most packages don't need hints — schemas and examples cover the common case. Add hints when:
Before publishing hints, verify each claim is factually correct. Don't describe features that aren't implemented. Don't assume behavior — confirm it.
.describe() already says// src/hints.ts
import type { Hints } from '@walkeros/core';
export const hints: Hints = {
'auth-methods': {
text: 'Supports three auth methods: ...',
code: [{ lang: 'json', code: '{ "settings": { ... } }' }],
},
};
// src/dev.ts
export * as schemas from './schemas';
export * as examples from './examples';
export { hints } from './hints';
Note: hints is a direct export (not * as), because it's already a
Record<string, Hint>.
<details> for advanced content"entity action" format with spacewalkerOS.json convention followed (walkerOS field in package.json,
buildDev in tsup)READMEs are thin pointers to the website docs, which are the single source
of truth. A README carries only: logo, title, one-line description, install, ONE
current version: 4 Quick Start, and a prominent link to the package's docs
page. No ## Features, no ## Configuration Reference, no inline API
reference, no ## Examples block. All reference content lives on the website so
it can never drift in two places.
The docs link MUST be an absolute https://www.walkeros.io/docs/... URL, never
a relative path: packages publish to npm individually and relative links break
on npmjs.com. These absolute docs links are validated by
npm run validate:links (it maps the URL to the website/docs/ source file and
asserts it exists).
<p align="left">
<a href="https://www.walkeros.io">
<img alt="walkerOS" title="walkerOS" src="https://www.walkeros.io/img/walkerOS_logo.svg" width="256px"/>
</a>
</p>
# @walkeros/[package-name]
[one-sentence description, adapted from the docs page intro]
[Documentation](https://www.walkeros.io/docs/[path]) •
[NPM Package](https://www.npmjs.com/package/@walkeros/[package-name]) •
[Source Code](https://github.com/elbwalker/walkerOS/tree/main/packages/[path])
## Installation
```bash
npm install @walkeros/[package-name]
```
## Quick start
```json
{
"version": 4,
"flows": {
"default": {
"config": { "platform": "[web|server]" },
"[sources|destinations]": {
"[name]": {
"package": "@walkeros/[package-name]",
"config": {}
}
}
}
}
}
```
## Documentation
Full configuration, mapping, and examples live in the docs:
**https://www.walkeros.io/docs/[path]**
## Contribute
Feel free to contribute by submitting an
[issue](https://github.com/elbwalker/walkerOS/issues), starting a
[discussion](https://github.com/elbwalker/walkerOS/discussions), or getting in
[contact](https://calendly.com/elb-alexander/30min).
## License
MIT
Verify the Quick Start against apps/quickstart/ and the package's real export
name before publishing. Platform-agnostic packages (core, collector) show their
most representative current usage instead of a config.platform flow.
Every package should document its walkerOS.json convention in the README:
{
"walkerOS": { "type": "destination", "platform": "web" }
}
The walkerOS field is an object with type and platform metadata describing
the package's role in the walkerOS ecosystem.
Website docs fold features into the intro paragraph (no ## Features heading).
Thin-pointer READMEs also have no ## Features heading; key capabilities go
into the one-line description. This template is website-only.
---
title: [Title]
description: [SEO description]
sidebar_position: [N]
---
import data from '@walkeros/[package]/walkerOS.json';
import Configuration from '@site/src/components/snippets/_configuration.mdx';
# [Title]
<PackageLink package="@walkeros/[package]" />
[1-sentence description that folds in key features as prose — no separate `##
Features` heading on website docs.]
## Quick start
```json
// Flow config example (<15 lines)
```
<CodeSnippet code={npm install @walkeros/[package]} language="bash" />
---
## Priority Matrix
### Issue Classification
| Priority | Criteria | Action |
|----------|----------|--------|
| **P0 Critical** | Incorrect examples, wrong APIs, security issues | Fix immediately |
| **P1 High** | Missing PropertyTable, outdated domains, missing sections | Fix soon |
| **P2 Medium** | Inconsistent terminology, skipped headings | Plan to fix |
| **P3 Low** | Style issues, minor wording | Backlog |
---
## Non-Negotiables
### Punctuation
Never use em dashes (`—`). Use a comma, period, or rephrase the sentence
instead.
```text
CORRECT: "free and without sampling caps"
WRONG: "free — without sampling caps"
```
### Event Naming
```text
CORRECT: "page view", "product add", "order complete" WRONG: "page_view",
"pageView", "PAGE VIEW"
```
CORRECT: `@walkeros/collector` (with backticks) WRONG: @walkeros/collector (no
backticks)
CORRECT: `www.walkeros.io` or relative paths DO NOT USE: legacy domain
references
apps/quickstart/ or create them first.meta({id, title}))Every exported schema in packages/core/src/schemas/*.ts (and in the *Schema
exports of destination / source / transformer / store packages) must carry
.meta({ id, title, description }) so the generated JSON Schema links back to
the canonical TypeScript name. Without meta, the website's PropertyTable falls
back to __schema0, object, or any.
Convention:
packages/core/src/schemas. Examples: WalkerOSConsent,
DestinationConfig, CollectorPushContext, LoggerConfig.WalkerOS.Consent,
Destination.Config, Collector.PushContext, Logger.Config..describe()
where both are present.Reference implementation (copy this shape for new schemas):
export const ConsentSchema = z.record(z.string(), z.boolean()).meta({
id: 'WalkerOSConsent',
title: 'WalkerOS.Consent',
description: 'Consent state mapping (group name to granted state).',
});
Coverage is enforced by
packages/core/src/schemas/__tests__/meta-coverage.test.ts. When adding a new
schema, run that test — it will fail with the exact schema name if meta is
missing.
Destination / source / transformer / store packages that ship their own
SettingsSchema should also call .meta({ id, title }) on it, e.g.
DestinationGtag.Settings / GtagDestinationSettings.