From d3e917627f0637ccf0f77ed89c2d13e096647b10 Mon Sep 17 00:00:00 2001 From: jonaslagoni Date: Thu, 22 Jan 2026 19:42:42 +0100 Subject: [PATCH 1/2] chore: add blog update --- docs/ai-assistants.md | 17 +++ mcp-server/lib/resources/bundled-docs.ts | 14 +-- mcp-server/lib/tools/config-tools.ts | 2 +- website/blog/2026-01-28-update-3/index.md | 128 ++++++++++++++++++++++ 4 files changed, 153 insertions(+), 8 deletions(-) create mode 100644 website/blog/2026-01-28-update-3/index.md diff --git a/docs/ai-assistants.md b/docs/ai-assistants.md index aaae1266..18db0f86 100644 --- a/docs/ai-assistants.md +++ b/docs/ai-assistants.md @@ -71,3 +71,20 @@ https://the-codegen-project.org/api/mcp ## Self-Hosting You can run your own instance of the MCP server for development or private use. See the [MCP server repository](https://github.com/the-codegen-project/cli/tree/main/mcp-server) for setup instructions. + +## Q&A + +### Q: If AI can generate code, why use The Codegen Project? +The generator gives you deterministic, repeatable output from a stable input (spec + config). That makes CI consistent, supports large-team conventions, and lets you regenerate code without drift across runs or models. + +### Q: Won’t AI output be maintained by developers anyway? +Yes, but generators keep a traceable “source of truth” in the configuration. That means you can explain why code exists, regenerate it reliably, and keep updates consistent across many services. + +### Q: When should I prefer AI over a generator? +Use AI for exploration, prototypes, or one-off scripts. Use the generator when you want consistent output, shared conventions, automated regeneration. + +### Q: Does this project compete with AI assistants? +It complements them. The MCP server gives assistants a deterministic interface to create and adjust configs, while the generator produces the exact code your repo expects. + +### Q: What’s the biggest advantage over “just using AI”? +Repeatability. The same input produces the same output every time, which is critical for CI, refactors, and multi-team consistency. diff --git a/mcp-server/lib/resources/bundled-docs.ts b/mcp-server/lib/resources/bundled-docs.ts index 13d960f1..6ec25101 100644 --- a/mcp-server/lib/resources/bundled-docs.ts +++ b/mcp-server/lib/resources/bundled-docs.ts @@ -18,11 +18,11 @@ export const docs: Record = { title: "TypeScript", content: "# TypeScript\nAll decision worth mentioning about TypeScript can be found here, simply to keep track.\n\n### 21.08.2024\n\n1. All functions in channel protocols are to be designed arrow function as it's more versatile when combining it together with other code sections.\n\n### 28.04.2025\n\n1. All function parameters MUST be object parameters to better support many optional parameters without having to write `functionCall(undefined, undefined, 'value')`", }, - "configurations": { + configurations: { title: "Configurations", content: "# Configurations\n\nThere are 5 possible configuration file types, `json`, `yaml`, `esm` (ECMAScript modules JavaScript), `cjs` (CommonJS modules JavaScript) and `ts` (TypeScript).\n\nThe only difference between them is what they enable you to do. The difference is `callbacks`, in a few places, you might want to provide a callback to control certain behavior in the generation library.\n\nFor example, with the [`custom`](./generators/custom.md) generator, you provide a callback to render something, this is not possible if your configuration file is either `json` or `yaml` format.\n\nReason those two exist, is because adding a `.js` configuration file to a Java project, might confuse developers, and if you dont need to take advantage of the customization features that require callback, it will probably be better to use one of the other two.\n\n## Creating Configurations with the CLI\n\nThe easiest way to create a configuration file is by using the `codegen init` command. This interactive command will guide you through setting up a configuration file for your project, allowing you to specify:\n\n- Input file (AsyncAPI or OpenAPI document)\n- Configuration file type (`esm`, `json`, `yaml`, `ts`)\n- Output directory\n- Language and generation options\n\n```sh\ncodegen init --input-file ./ecommerce.yml --input-type asyncapi --config-type ts --languages typescript\n```\n\nFor detailed usage instructions and all available options, see the [CLI usage documentation](./usage.md#codegen-init).\n\n## Configuration File Lookup\n\nIf no explicit configuration file is sat, it will be looked for in the following order:\n- package.json\n- .codegenrc\n- .codegenrc.json\n- .codegenrc.yaml\n- .codegenrc.yml\n- .codegenrc.js\n- .codegenrc.ts\n- .codegenrc.cjs\n- .config/codegenrc\n- .config/codegenrc.json\n- .config/codegenrc.yaml\n- .config/codegenrc.yml\n- .config/codegenrc.js\n- .config/codegenrc.ts\n- .config/codegenrc.mjs\n- .config/codegenrc.cjs\n- codegen.config.js\n- codegen.config.ts\n- codegen.config.mjs\n- codegen.config.cjs\n- codegen.json\n- codegen.yaml\n- codegen.yml\n- codegen.js\n- codegen.ts\n- codegen.mjs\n- codegen.cjs", }, - "contributing": { + contributing: { title: "Contributing to The Codegen Project", content: "# Contributing to The Codegen Project\n\n\n\n\n\n- [Acceptance criteria and process](#acceptance-criteria-and-process)\n * [Fixing bugs](#fixing-bugs)\n * [New features](#new-features)\n- [Repository Architecture](#repository-architecture)\n- [Getting started](#getting-started)\n- [Contribution recogniton](#contribution-recogniton)\n- [Summary of the contribution flow](#summary-of-the-contribution-flow)\n- [Code of Conduct](#code-of-conduct)\n- [Our Development Process](#our-development-process)\n- [Pull Requests](#pull-requests)\n- [Conventional commits](#conventional-commits)\n\n\n\nFirst of all, thank you 🙇🏾‍♀️ for considering contributing to The Codegen Project\n\nIf you have any questions, are unsure how your use-case fits in, or want something clarified, don't hesitate to reach out, we are always happy to help out!\n\n## Acceptance criteria and process\n\nEven though we love contributions, we need to maintain a certain standard of what can be merged into the codebase. \n\nThe below sections provide information about our acceptance criteria, based on the type of contribution you make.\n\n### Fixing bugs \n\nThe Acceptance Criteria for _fixing any bug_ means that you should be able to reproduce the error using tests that will fail, unless a fix is implemented.\n\n### New features\n\nThe Acceptance Criteria for _adding new features_ requires a few things in order to be accepted. This ensures all features are well described and implemented before being released.\n\n1. **Not all feature requests from the community (or maintainers!) are accepted:** Even though you are welcome to create a new feature without an issue, it might be rejected and turn out to be a waste of your time. We don't want that to happen, so make sure to create an issue first and wait to see if it's accepted after community discussion of the proposal.\n1. **When creating tests for your new feature, aim for as high coverage numbers as possible:** When you run the tests (`npm run test`), you should see a `./coverage/lcov-report/index.html` file being generated. Use this to see in depth where your tests are not covering your implementation.\n1. **No documentation, no feature:** If a user cannot understand a new feature, that feature basically doesn't exist! Remember to make sure that any and all relevant [documentation](./) is consistently updated.\n - New features such as new generators or inputs, etc, need associated use case documentation along side [examples](../examples).\n\n## Repository Architecture\n\nThe repository is setup with multiple functions to keep it simple.\n- `src`; includes the CLI and library code both exposed through the same package.\n- `website`; is... Well the website.\n- `scripts`; includes helpfull scripts for the release flow such as for building JSON Schema files from the code for configuration validation and CLI release configurations\n- `test`; include all the testing done for the repository\n - `blackbox`; is a quick and dirt syntax testing of different configurations against different inputs to quickly detect problems\n - `runtime`; is sematic testing of the generated code in the corresponding languages they generate for, ensuring correct behaviour at runtime\n - The rest normal unit and integration testing of the actual CLI and library\n- `examples`; is the showcase of actual projects using the CLI to simplify the implementation phase of software development.\n- `schemas`; is the autogenerated JSON schemas for validating configurations.\n\n## Getting started\n\nHere is a quick litle get started quick tutorial;\n\n1. Fork the repository\n2. Create a branch from the upstream repository\n3. Install the dependencies `npm install`\n4. Make sure test pass `npm run test`\n5. Adapt the source code as well as test and documentation\n6. Push the changes\n7. Create a PR with the proposed change\n8. Get the change reviewed and merged :tada:\n\nHappy contributing :heart:\n\n## Contribution recogniton\n\nWe use [All Contributors](https://allcontributors.org/docs/en/specification) specification to handle recognitions.\n\n## Summary of the contribution flow\n\nThe following is a summary of the ideal contribution flow. Please, note that Pull Requests can also be rejected by the maintainers when appropriate.\n\n```\n ┌───────────────────────┐\n │ │\n │ Open an issue │\n │ (a bug report or a │\n │ feature request) │\n │ │\n └───────────────────────┘\n ⇩\n ┌───────────────────────┐\n │ │\n │ Open a Pull Request │\n │ (only after issue │\n │ is approved) │\n │ │\n └───────────────────────┘\n ⇩\n ┌───────────────────────┐\n │ │\n │ Your changes will │\n │ be merged and │\n │ published on the next │\n │ release │\n │ │\n └───────────────────────┘\n```\n\n## Code of Conduct\nWe have adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://github.com/the-codegen-project/cli/blob/main/CODE_OF_CONDUCT.md) so that you can understand what sort of behaviour is expected.\n\n## Our Development Process\nWe use Github to host code, to track issues and feature requests, as well as accept pull requests.\n\n## Pull Requests\n\n**Please, make sure you open an issue before starting with a Pull Request, unless it's a typo or a really obvious error.** Pull requests are the best way to propose changes to the specification. \n\n## Conventional commits\n\nOur repositories follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) specification. Releasing to GitHub and NPM is done with the support of [semantic-release](https://semantic-release.gitbook.io/semantic-release/).\n\nPull requests should have a title that follows the specification, otherwise, merging is blocked. If you are not familiar with the specification simply ask maintainers to modify. You can also use this cheatsheet if you want:\n\n- `fix: ` prefix in the title indicates that PR is a bug fix and PATCH release must be triggered.\n- `feat: ` prefix in the title indicates that PR is a feature and MINOR release must be triggered.\n- `docs: ` prefix in the title indicates that PR is only related to the documentation and there is no need to trigger release.\n- `chore: ` prefix in the title indicates that PR is only related to cleanup in the project and there is no need to trigger release.\n- `test: ` prefix in the title indicates that PR is only related to tests and there is no need to trigger release.\n- `refactor: ` prefix in the title indicates that PR is only related to refactoring and there is no need to trigger release.\n\nWhat about MAJOR release? just add `!` to the prefix, like `fix!: ` or `refactor!: `\n\nPrefix that follows specification is not enough though. Remember that the title must be clear and descriptive with usage of [imperative mood](https://chris.beams.io/posts/git-commit/#imperative).", }, @@ -54,7 +54,7 @@ export const docs: Record = { title: "🐔 Payloads", content: "# 🐔 Payloads\n\n```js\nexport default {\n ...,\n generators: [\n {\n preset: 'payloads',\n outputPath: './src/payloads',\n serializationType: 'json', \n language: 'typescript'\n }\n ]\n};\n```\n\n`payloads` preset is for generating models that represent typed models that can be serialized into message payloads for communication use-cases.\n\nThis is supported through the following inputs: `asyncapi`, `openapi`\n\nIt supports the following languages; [`typescript`](#typescript)\n\n## Languages\nEach language has a set of constraints which means that some typed model types are either supported or not, or it might just be the code generation library that does not yet support it.\n\n| | Circular models | Enums | Tuples | Arrays | Nested Arrays | Dictionaries | Json Serialization | Validation |\n|---|---|---|---|---|---|---|---|---|\n| **TypeScript** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |\n\n### TypeScript\n\nDependencies: \n- If validation enabled, [ajv](https://ajv.js.org/guide/getting-started.html): ^8.17.1\n\n#### Validation\nEach generated class includes built-in JSON Schema validation capabilities through two static methods:\n\n- `validate`: Validates data against the schema. Use this method when you want to validate data.\n\n```typescript\n// Example\nconst result = UserSignedUp.validate({ data: userData });\nif (!result.valid) {\n console.error('Validation errors:', result.errors);\n}\n```\n\n- `createValidator`: Creates a reusable validator function. Use this when you need to validate multiple instances of the same type and want to avoid recreating the validator each time.\n\n```typescript\n// Example\nconst validator = UserSignedUp.createValidator();\nconst result = UserSignedUp.validate({ data: userData, ajvValidatorFunction: validator });\nif (!result.valid) {\n console.error('Validation errors:', result.errors);\n}\n```\n\nBoth methods support custom Ajv instances and options for advanced validation scenarios.", }, - "generators": { + generators: { title: "Generators", content: "# Generators\nGenerators, or preset's are the core of **The Codegen Project**, that determines what is generated for your project.\n\nEach language and inputs have specific generators;\n\nAll available generators, across languages and inputs:\n- [`payloads`](./payloads.md)\n- [`parameters`](./parameters.md)\n- [`headers`](./headers.md)\n- [`types`](./types.md)\n- [`channels`](./channels.md)\n- [`client`](./client.md)\n- [`models`](./models.md)\n- [`custom`](./custom.md)\n\n| **Inputs** | [`payloads`](./payloads.md) | [`parameters`](./parameters.md) | [`headers`](./headers.md) | [`types`](./types.md) | [`channels`](./channels.md) | [`client`](./client.md) | [`models`](./models.md) | [`custom`](./custom.md) |\n|---|---|---|---|---|---|---|---|---|\n| AsyncAPI | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |\n| OpenAPI | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ |\n| JSON Schema | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ |\n\n| **Languages** | [`payloads`](./payloads.md) | [`parameters`](./parameters.md) | [`headers`](./headers.md) | [`types`](./types.md) | [`channels`](./channels.md) | [`client`](./client.md) | [`models`](./models.md) | [`custom`](./custom.md) |\n|---|---|---|---|---|---|---|---|---|\n| TypeScript | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |", }, @@ -94,7 +94,7 @@ export const docs: Record = { title: "TypeScript Project", content: "---\r\nsidebar_position: 99\r\n---\r\n\r\n# TypeScript Project\r\n\r\nSimple TypeScript library that use AsyncAPI as input to generate payload models that is serialized and printed in the console.\r\n\r\n[See the project in action 🎬](https://github.com/the-codegen-project/cli/tree/main/examples/typescript-library)", }, - "migrations": { + migrations: { title: "Migrations", content: "# Migrations\nThese are the migration documents\n- [v0, migrating between v0 versions](v0.md) can be found here.", }, @@ -130,15 +130,15 @@ export const docs: Record = { title: "WebSocket", content: "# WebSocket\n\nWebSocket is currently supported through the following generators ([channels](#channels)):\n\n| **Languages** | Client Publish | Client Subscribe | Server Register |\n|---|---|---|---|\n| TypeScript | ✅ | ✅ | ✅ |\n\nAll of this is available through [AsyncAPI](../inputs/asyncapi.md).\n\n## ⚠️ Important: External Connection Management\n\nThe WebSocket generator assumes that WebSocket connections are managed externally by your application. The generated functions accept already-connected WebSocket instances and focus on message handling rather than connection establishment.\n\n```typescript\n// ✅ You manage the connection\nconst clientWs = new WebSocket('ws://localhost:8080/user/events');\nconst server = new WebSocketServer({ port: 8080 });\n\n// ✅ Generated functions use your connections\nawait publishMessage({ message, parameters, ws: clientWs });\nregisterHandler({ wss: server, onConnection, onMessage });\n```\n\n**Why External Connection Management:**\n- Gives you full control over connection lifecycle\n- Allows custom authentication and authorization\n- Enables connection pooling and reconnection strategies\n- Separates transport concerns from message handling\n\n## Channels\n\nRead more about the [channels](../generators/channels.md) generator here before continuing.\n\nThis generator provides support functions for each resource ensuring you use the right payload and parameters.\n\n\n\n \n \n \n \n\n\n \n \n\n\n\n
Input (AsyncAPI)Using the code
\n\n```yaml\nasyncapi: 3.0.0\ninfo:\n title: User Service\n version: 1.0.0\n description: WebSocket-based user event system\nchannels:\n userEvents:\n address: user/events/{userId}\n parameters:\n userId:\n description: The user identifier\n messages:\n userSignedUp:\n $ref: '#/components/messages/UserSignedUp'\noperations:\n sendUserEvent:\n action: send\n channel:\n $ref: '#/channels/userEvents'\n receiveUserEvent:\n action: receive\n channel:\n $ref: '#/channels/userEvents'\ncomponents:\n messages:\n UserSignedUp:\n payload:\n type: object\n properties:\n userId:\n type: string\n email:\n type: string\n required:\n - userId\n - email\n```\n\n\n\n**Client-side publishing:**\n```typescript\nimport { publishToSendUserEvent } from './channels';\nimport { UserSignedUp } from './payloads';\nimport { UserEventsParameters } from './parameters';\nimport WebSocket from 'ws';\n\n// Create connection (your responsibility)\nconst ws = new WebSocket('ws://localhost:8080/user/events/user123');\n\nawait ws.on('open', async () => {\n // Use generated publish function\n await publishToSendUserEvent({\n message: new UserSignedUp({\n userId: 'user123',\n email: 'user@example.com'\n }),\n parameters: new UserEventsParameters({\n userId: 'user123'\n }),\n ws\n });\n});\n```\n\n**Client-side subscribing:**\n```typescript\nimport { subscribeToReceiveUserEvent } from './channels';\n\nws.on('open', () => {\n // Set up subscription\n subscribeToReceiveUserEvent({\n onDataCallback: (params) => {\n const { err, msg, parameters, ws } = params;\n if (err) {\n console.error('Error:', err);\n return;\n }\n \n console.log('Received:', msg?.marshal());\n console.log('User ID:', parameters?.userId);\n },\n parameters: new UserEventsParameters({\n userId: 'user123'\n }),\n ws\n });\n});\n```\n\n**Server-side handling:**\n```typescript\nimport { registerSendUserEvent } from './channels';\nimport WebSocket from 'ws';\n\n// Create server (your responsibility)\nconst wss = new WebSocket.WebSocketServer({ port: 8080 });\n\n// Register message handler\nregisterSendUserEvent({\n wss,\n onConnection: (params) => {\n const { parameters, ws, request } = params;\n console.log(`User ${parameters.userId} connected`);\n \n // Perform authentication, logging, etc.\n },\n onMessage: (params) => {\n const { message, ws } = params;\n console.log('Received message:', message.marshal());\n \n // Process the message\n // Send response if needed\n const response = new UserSignedUp({\n userId: message.userId,\n email: 'updated@example.com'\n });\n ws.send(response.marshal());\n }\n});\n```\n\n
\n\n## Function Types\n\nThe WebSocket generator creates three types of functions:\n\n### Client Functions\n\n**Publish Functions** (`publishTo*`):\n- Send messages from client to server\n- Require connected WebSocket instance\n- Handle message serialization automatically\n- Return Promise for async operation\n\n**Subscribe Functions** (`subscribeTo*`):\n- Listen for messages from server\n- Set up message handlers on WebSocket\n- Handle message parsing and validation\n- Support error handling through callbacks\n\n### Server Functions\n\n**Register Functions** (`register*`):\n- Handle incoming client connections\n- Process messages from clients\n- Support both connection and message callbacks\n- Enable URL parameter extraction\n\n## URL Pattern Matching\n\nThe WebSocket generator automatically creates URL pattern matching for channels with parameters:\n\n```yaml\n# AsyncAPI Channel\nchannels:\n userEvents:\n address: user/events/{userId}/{eventType}\n```\n\n```typescript\n// Generated pattern matching\n// Matches: /user/events/123/signup\n// Extracts: userId=\"123\", eventType=\"signup\"\n\nregisterSendUserEvent({\n wss,\n onConnection: (params) => {\n // Parameters automatically extracted from URL\n const { parameters } = params;\n console.log(parameters.userId); // \"123\"\n console.log(parameters.eventType); // \"signup\"\n },\n onMessage: (params) => {\n // Handle the message\n }\n});\n```\n\n## Error Handling\n\nThe WebSocket generator includes comprehensive error handling:\n\n```typescript\n// Client-side error handling\nsubscribeToReceiveUserEvent({\n onDataCallback: (params) => {\n const { err, msg } = params;\n if (err) {\n // Handle parsing errors, validation errors, etc.\n console.error('Message error:', err.message);\n return;\n }\n // Process successful message\n },\n ws\n});\n\n// Connection state checking\nawait publishToSendUserEvent({\n message,\n parameters,\n ws // Function checks if WebSocket is open\n});\n```\n\n## Best Practices\n\n### Connection Management\n```typescript\n// ✅ Handle connection lifecycle\nconst ws = new WebSocket('ws://localhost:8080/user/events/123');\n\nws.on('open', () => {\n // Set up subscriptions after connection opens\n subscribeToReceiveUserEvent({ ... });\n});\n\nws.on('close', (code, reason) => {\n // Handle disconnection, implement reconnection logic\n});\n\nws.on('error', (error) => {\n // Handle connection errors\n});\n```\n\n### Message Validation\n```typescript\n// ✅ Use validation in production\nsubscribeToReceiveUserEvent({\n onDataCallback: (params) => {\n const { err, msg } = params;\n if (err) {\n // Generated functions include validation errors\n console.error('Invalid message received:', err);\n return;\n }\n // Message is guaranteed to be valid\n },\n skipMessageValidation: false, // Enable validation (default)\n ws\n});\n```\n\n### Server Setup\n```typescript\n// ✅ Proper server setup with error handling\nconst wss = new WebSocket.WebSocketServer({ \n port: 8080,\n verifyClient: (info) => {\n // Implement authentication logic\n return true;\n }\n});\n\nregisterSendUserEvent({\n wss,\n onConnection: (params) => {\n const { parameters, ws, request } = params;\n \n // Validate parameters\n if (!parameters.userId) {\n ws.close(1008, 'Invalid user ID');\n return;\n }\n \n // Set up user session\n },\n onMessage: (params) => {\n const { message, ws } = params;\n \n try {\n // Process message safely\n } catch (error) {\n ws.close(1011, 'Processing error');\n }\n }\n});\n```\n\n## Dependencies\n\nThe generated WebSocket code requires the `ws` library:\n\n```bash\nnpm install ws\nnpm install @types/ws # For TypeScript projects\n```", }, - "index": { + index: { title: "Documentation", content: "# Documentation\n\n\n\n\n\n- [Configurations](#configurations)\n- [Getting Started](#getting-started)\n- [Contributing](#contributing)\n- [Usage](#usage)\n- [Generators](#generators)\n- [Architectural Decisions](#architectural-decisions)\n- [Inputs](#inputs)\n- [Protocols](#protocols)\n- [Migrations](#migrations)\n- [Telemetry](#telemetry)\n\n\n\nThis document gives the overview of all the available documentation for The Codegen Project.\n\n### [Configurations](./configurations.md)\nContains all the information about the how the configuration file works and how it's loaded and in what order.\n\n### [Getting Started](./getting-started/)\nGet started in 5 minutes :fire:\n\n### [Contributing](./contributing.md)\nGet an overview of how to contribute to the project\n\n### [Usage](./usage.md)\nContains all the information about what the CLI can do and how.\n\n### [Generators](./generators/README.md)\nFor all available generators, this document describes what is possible.\n\n### Architectural Decisions\nIf there has been a decision about certain technical solutions it will be marked in the architectural decision document.\n- [TypeScript](./architectural-decisions/typescript.md)\n\n### Inputs\nEach input has its own limitations, corner cases, and features; thus, each has separate documentation.\n- [AsyncAPI](./inputs/asyncapi.md)\n- [OpenAPI](./inputs/openapi.md)\n- [JSON Schema](./inputs/jsonschema.md)\n\n### Protocols\nEach protocol has its own limitations, corner cases, and features; thus, each has separate documentation.\n- [NATS](./protocols/nats.md)\n- [AMQP](./protocols/amqp.md)\n- [Kafka](./protocols/kafka.md)\n- [MQTT](./protocols/mqtt.md)\n- [EventSource](./protocols/eventsource.md)\n- [HTTP Client](./protocols/http_client.md)\n- [WebSocket client and server](./protocols/websocket.md)\n\n### [Migrations](./migrations/README.md)\nGet an overview of how to contribute to the project\n\n### [Telemetry](./telemetry.md)\nGet an overview of how telemetry works for this project", }, - "telemetry": { + telemetry: { title: "Telemetry", content: "# Telemetry\n\nThe Codegen Project CLI collects **anonymous** usage data to help us understand how the tool is being used and make data-driven improvements.\n\n## Privacy First\n\nWe take your privacy seriously. Here's what we collect and what we don't:\n\n### ✅ What We Collect\n\n- **Command usage**: Which commands you run (e.g., `generate`, `init`)\n- **Generator types**: Which generators you use (e.g., `payloads`, `channels`)\n- **Input source types**: Whether you use remote URLs, local relative paths, or absolute paths (not the actual paths)\n- **Feature usage**: Which flags and options you use\n- **Error categories**: Types of errors that occur (not error messages or stack traces)\n- **System information**: CLI version, Node.js version, OS platform\n- **Execution metrics**: Command duration and success rates\n\n### ❌ What We DON'T Collect\n\n- ❌ File paths or file names\n- ❌ Actual URLs or file locations\n- ❌ File contents or schema details\n- ❌ Project names\n- ❌ User names or emails\n- ❌ API keys or credentials\n- ❌ IP addresses (anonymized by analytics provider)\n- ❌ Hostnames\n- ❌ Environment variable values\n- ❌ Git repository information\n- ❌ Custom schema structures\n\n## Managing Telemetry\n\n### Check Status\n\nView your current telemetry settings:\n\n```bash\ncodegen telemetry status\n```\n\nThis shows:\n- Whether telemetry is enabled or disabled\n- Configuration file location\n- What data is collected\n- Environment variable overrides\n\n### Disable Telemetry\n\nYou can disable telemetry in several ways:\n\n#### Option 1: Using the CLI command\n\n```bash\ncodegen telemetry disable\n```\n\n#### Option 2: Environment variable (permanent)\n\nAdd to your shell profile (`.bashrc`, `.zshrc`, etc.):\n\n```bash\nexport CODEGEN_TELEMETRY_DISABLED=1\n```\n\nOr use the standard DO_NOT_TRACK variable:\n\n```bash\nexport DO_NOT_TRACK=1\n```\n\n#### Option 3: Environment variable (per-command)\n\n```bash\nCODEGEN_TELEMETRY_DISABLED=1 codegen generate\n```\n\n#### Option 4: Project-level configuration\n\nIn your `codegen.config.js`:\n\n```javascript\nexport default {\n inputType: 'asyncapi',\n inputPath: './asyncapi.yaml',\n generators: [/* ... */],\n \n // Disable telemetry for this project\n telemetry: {\n enabled: false\n }\n}\n```\n\n### Re-enable Telemetry\n\n```bash\ncodegen telemetry enable\n```\n\n## First-Run Notice\n\nWhen you run any command for the first time, you'll see a notice about telemetry:\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ │\n│ The Codegen Project CLI collects anonymous usage data │\n│ to help us improve the tool. │\n│ │\n│ To disable: codegen telemetry disable │\n│ Learn more: https://the-codegen-project.org/docs/telemetry │\n│ │\n└─────────────────────────────────────────────────────────────┘\n```\n\nThis notice is shown only once. Telemetry is **opt-out by default**, meaning it's enabled unless you explicitly disable it.\n\n## Debug Mode\n\nTo see what telemetry data is being sent:\n\n```bash\nCODEGEN_TELEMETRY_DEBUG=1 codegen generate\n```\n\nThis logs telemetry events to the console, including:\n- The event being tracked\n- The telemetry configuration state\n- The full payload being sent to the analytics endpoint\n- HTTP response status (success/failure)\n\nEvents are still sent to the analytics endpoint in debug mode, but you can see exactly what's being transmitted. The events will also appear in **GA4 DebugView** when debug mode is enabled.\n\n## Custom Tracking Endpoint (for Organizations)\n\nOrganizations can point telemetry to their own analytics endpoint using environment variables. These environment variables have the **highest priority** and will override any configuration from project-level config or global config files:\n\n```bash\n# Set custom endpoint (highest priority - overrides all other configs)\nexport CODEGEN_TELEMETRY_ENDPOINT=https://analytics.mycompany.com/telemetry\nexport CODEGEN_TELEMETRY_ID=custom-tracking-id\nexport CODEGEN_TELEMETRY_API_SECRET=your-api-secret\n```\n\n**Configuration Priority Order (highest to lowest):**\n1. **Environment variables** (highest priority):\n - `CODEGEN_TELEMETRY_DISABLED` / `DO_NOT_TRACK` - disable telemetry\n - `CODEGEN_TELEMETRY_ENDPOINT` - custom analytics endpoint\n - `CODEGEN_TELEMETRY_ID` - custom tracking ID\n - `CODEGEN_TELEMETRY_API_SECRET` - custom API secret\n2. **Project-level config** (from `codegen.config.js`)\n3. **Global config file** (`~/.the-codegen-project/config.json`)\n\nExpected endpoint format (GA4 Measurement Protocol compatible):\n\n```\nPOST /telemetry\nContent-Type: application/json\n\n{\n \"client_id\": \"anonymous-uuid\",\n \"events\": [{\n \"name\": \"command_executed\",\n \"params\": {\n \"command\": \"generate\",\n \"flags\": \"watch\",\n \"input_source\": \"local_relative\",\n \"input_type\": \"asyncapi\",\n \"generators\": \"payloads,parameters\",\n \"generator_count\": 2,\n \"duration\": 1234,\n \"success\": true,\n \"cli_version\": \"0.57.0\",\n \"node_version\": \"v18.0.0\",\n \"os\": \"darwin\",\n \"ci\": false,\n \"engagement_time_msec\": \"1234\"\n }\n }]\n}\n```\n\n## Configuration File\n\nTelemetry settings are stored in:\n\n```\n~/.the-codegen-project/config.json\n```\n\nExample configuration:\n\n```json\n{\n \"version\": \"1.0.0\",\n \"telemetry\": {\n \"enabled\": true,\n \"anonymousId\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"endpoint\": \"https://www.google-analytics.com/mp/collect\",\n \"trackingId\": \"G-XXXXXXXXXX\"\n },\n \"hasShownTelemetryNotice\": true,\n \"lastUpdated\": \"2024-12-11T10:30:00Z\"\n}\n```\n\n## Example Telemetry Events\n\n### Command Execution\n\n```javascript\n{\n event: 'command_executed',\n command: 'generate',\n flags: 'watch', // Comma-separated if multiple, 'none' if empty\n input_source: 'local_relative', // Not the actual path!\n input_type: 'asyncapi',\n generators: 'payloads,parameters,channels', // Comma-separated list\n generator_count: 3,\n duration: 1234,\n success: true,\n cli_version: '0.57.0',\n node_version: 'v18.0.0',\n os: 'darwin',\n ci: false,\n engagement_time_msec: '1234' // Same as duration for proper engagement tracking\n}\n```\n\n**Why track generator combinations?** This helps us understand:\n- Which generators are commonly used together\n- Popular generator patterns (e.g., \"payloads + parameters\")\n- If certain generators are always used in isolation\n- Common workflows and use cases\n\n### Generator Usage\n\n```javascript\n{\n event: 'generator_used',\n generator_type: 'payloads',\n input_type: 'asyncapi', // Can be: asyncapi, openapi, jsonschema\n input_source: 'remote_url', // Not the actual URL!\n language: 'typescript',\n options: '{\"includeValidation\":true,\"serializationType\":\"json\"}',\n duration: 500,\n success: true,\n cli_version: '0.57.0',\n node_version: 'v18.0.0',\n os: 'darwin',\n ci: false,\n engagement_time_msec: '500'\n}\n```\n\n**Why track individual generators?** This helps us understand:\n- Which generators are most popular\n- How users configure generators (validation, serialization, etc.)\n- Performance characteristics of each generator\n- Success/failure rates per generator type\n\n**Combined with `command_executed` event**, we get both:\n- **Macro view**: What generators are used together\n- **Micro view**: How each generator is configured\n\n### Init Command\n\n```javascript\n{\n event: 'init_executed',\n config_type: 'esm',\n input_type: 'asyncapi',\n generators: 'payloads,parameters,channels', // Comma-separated list\n language: 'typescript',\n completed: true,\n cli_version: '0.57.0',\n node_version: 'v18.0.0',\n os: 'darwin',\n ci: false,\n engagement_time_msec: '100' // Minimum engagement time\n}\n```\n\n### Error Tracking\n\n```javascript\n{\n event: 'error_occurred',\n command: 'generate',\n error_type: 'configuration_error', // Category only, not actual error message\n cli_version: '0.57.0',\n node_version: 'v18.0.0'\n}\n```\n\n## CI/CD Environments\n\nTelemetry automatically detects CI environments and adjusts behavior:\n\n- **First-run notice is skipped** in CI environments\n- Telemetry still runs by default (to track CI usage patterns)\n- You can disable it with environment variables if needed\n\nDetected CI environments:\n- GitHub Actions\n- GitLab CI\n- CircleCI\n- Travis CI\n- Jenkins\n- Bitbucket Pipelines\n- AWS CodeBuild\n- TeamCity\n- Buildkite\n\n## Privacy & Compliance\n\n### GDPR Compliance\n\nOur telemetry implementation is GDPR compliant:\n\n- ✅ **Lawful Basis**: Legitimate interest (improving software)\n- ✅ **Transparency**: Clear notice on first run\n- ✅ **User Control**: Easy opt-out mechanism\n- ✅ **Data Minimization**: Only collect necessary data\n- ✅ **Purpose Limitation**: Use only for improvement\n- ✅ **Anonymization**: No PII collected\n- ✅ **Right to Object**: Users can disable anytime\n\n### Data Retention\n\nWe store data for 14 months, if you use your own telemetry, then its up to you.\n\n### Anonymous ID\n\nEach installation generates a random UUID (v4) as an anonymous identifier. This ID:\n- Is NOT tied to your identity\n- Cannot be used to identify you personally\n- Is only used to understand usage patterns\n- Can be reset by deleting the config file\n\n## How Telemetry Helps\n\nThe data we collect helps us:\n\n1. **Prioritize features**: Focus on the most-used generators and commands\n2. **Improve reliability**: Identify and fix common error scenarios\n3. **Optimize performance**: Understand typical execution times\n4. **Support platforms**: Know which Node.js versions and OS platforms to support\n5. **Guide documentation**: Understand which features cause confusion\n6. **Understand workflows**: Learn whether users prefer remote URLs, relative paths, or absolute paths\n\n## Technical Details\n\n### Implementation\n\n- **Non-blocking**: Telemetry runs asynchronously and never blocks CLI execution\n- **Fail-safe**: Network errors or timeouts don't affect CLI functionality\n- **Fast timeout**: Telemetry requests timeout after 1 second\n- **Error handling**: All errors are handled gracefully and silently\n\n### Default Analytics Provider\n\nWe use Google Analytics 4 Measurement Protocol by default:\n- Free service with powerful analytics\n- Automatic IP anonymization\n- GDPR compliant\n- No additional infrastructure needed\n\n## Website Analytics\n\nIn addition to CLI telemetry, our documentation website (https://the-codegen-project.org) also uses **Google Analytics 4** to understand how users interact with our documentation.\n\n### What the Website Tracks\n\n- **Page views**: Which documentation pages are viewed\n- **Navigation**: How users navigate through the documentation\n- **Search queries**: What users search for in the docs\n- **Outbound links**: Which external links users click\n- **Time on page**: How long users spend reading documentation\n- **Referral sources**: How users found our documentation\n\n**Note:** The website uses a different Google Analytics property than the CLI telemetry. They are completely separate tracking systems.\n\n### What the Website Does NOT Track\n\n- ❌ Personal information\n- ❌ Form inputs or data\n- ❌ Clipboard contents\n- ❌ Code snippets you copy\n- ❌ IP addresses (anonymized by GA4)\n\n### Website Privacy Controls\n\n**Standard Browser Controls:**\n- Use browser \"Do Not Track\" settings\n- Install privacy extensions (uBlock Origin, Privacy Badger, etc.)\n- Use browser incognito/private mode\n- Disable JavaScript (documentation still accessible)\n\n**Website-Specific Settings:**\n- Our website respects the `DO_NOT_TRACK` browser header\n- No cookies are set for tracking purposes\n- Google Analytics IP anonymization is enabled\n- No third-party tracking scripts beyond GA4\n\n## FAQ\n\n### Q: Will telemetry slow down my CLI?\n\n**A**: No. Telemetry runs asynchronously and doesn't block command execution. Network requests timeout after 1 second and fail silently.\n\n### Q: Can telemetry errors break my CLI?\n\n**A**: No. All telemetry functions are designed to never throw errors. Failures are handled internally and don't affect CLI functionality.\n\n### Q: Does this work behind a corporate proxy?\n\n**A**: Yes. Telemetry respects standard `HTTP_PROXY` and `HTTPS_PROXY` environment variables. If it fails, it fails silently without affecting the CLI.\n\n### Q: Can I see what's being sent?\n\n**A**: Yes! Use debug mode:\n\n```bash\nCODEGEN_TELEMETRY_DEBUG=1 codegen generate\n```\n\n### Q: Why opt-out instead of opt-in?\n\n**A**: Opt-out telemetry provides more representative data about how the tool is actually used, which leads to better improvements for all users. However, we respect your choice to opt-out at any time.\n\n### Q: Is my company's internal tracking supported?\n\n**A**: Yes! Set `CODEGEN_TELEMETRY_ENDPOINT` to your internal analytics service. See the \"Custom Tracking Endpoint\" section above.\n\n### Q: Where is the data sent?\n\n**A**: By default, to Google Analytics 4 (anonymized). You can configure a custom endpoint for organizational tracking.\n\n### Q: Can you track me across projects?\n\n**A**: We use an anonymous UUID that is the same across all your projects (any where you interact with the-codegen-project), but it's not tied to any personal information. You can reset it by deleting `~/.the-codegen-project/config.json`.\n\n### Q: Are CLI telemetry and website analytics linked?\n\n**A**: No. The CLI uses an anonymous UUID that is never shared with the website. Website analytics use standard Google Analytics browser tracking. There is no way to correlate CLI usage with website visits - they are completely independent systems.\n\n## Contact\n\nIf you have questions or concerns about telemetry:\n\n- GitHub Issues: [the-codegen-project/cli](https://github.com/the-codegen-project/cli/issues)", }, - "usage": { + usage: { title: "CLI Usage", content: "# CLI Usage\n\n\n```sh-session\n$ npm install -g @the-codegen-project/cli\n$ codegen COMMAND\nrunning command...\n$ codegen (--version)\n@the-codegen-project/cli/0.62.1 linux-x64 node-v18.20.8\n$ codegen --help [COMMAND]\nUSAGE\n $ codegen COMMAND\n...\n```\n\n\n## Table of contents\n\n\n* [CLI Usage](#cli-usage)\n\n\n## Commands\n\n\n* [`codegen autocomplete [SHELL]`](#codegen-autocomplete-shell)\n* [`codegen generate [FILE]`](#codegen-generate-file)\n* [`codegen help [COMMAND]`](#codegen-help-command)\n* [`codegen init`](#codegen-init)\n* [`codegen telemetry ACTION`](#codegen-telemetry-action)\n* [`codegen version`](#codegen-version)\n\n## `codegen autocomplete [SHELL]`\n\nDisplay autocomplete installation instructions.\n\n```\nUSAGE\n $ codegen autocomplete [SHELL] [-r]\n\nARGUMENTS\n SHELL (zsh|bash|powershell) Shell type\n\nFLAGS\n -r, --refresh-cache Refresh cache (ignores displaying instructions)\n\nDESCRIPTION\n Display autocomplete installation instructions.\n\nEXAMPLES\n $ codegen autocomplete\n\n $ codegen autocomplete bash\n\n $ codegen autocomplete zsh\n\n $ codegen autocomplete powershell\n\n $ codegen autocomplete --refresh-cache\n```\n\n_See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v3.0.18/src/commands/autocomplete/index.ts)_\n\n## `codegen generate [FILE]`\n\nGenerate code based on your configuration, use `init` to get started.\n\n```\nUSAGE\n $ codegen generate [FILE] [--help] [-w] [-p ]\n\nARGUMENTS\n FILE Path or URL to the configuration file, defaults to root of where the command is run\n\nFLAGS\n -p, --watchPath= Optional path to watch for changes when --watch flag is used. If not provided, watches the\n input file from configuration\n -w, --watch Watch for file changes and regenerate code automatically\n --help Show CLI help.\n\nDESCRIPTION\n Generate code based on your configuration, use `init` to get started.\n```\n\n_See code: [src/commands/generate.ts](https://github.com/the-codegen-project/cli/blob/v0.62.1/src/commands/generate.ts)_\n\n## `codegen help [COMMAND]`\n\nDisplay help for codegen.\n\n```\nUSAGE\n $ codegen help [COMMAND...] [-n]\n\nARGUMENTS\n COMMAND... Command to show help for.\n\nFLAGS\n -n, --nested-commands Include all nested commands in the output.\n\nDESCRIPTION\n Display help for codegen.\n```\n\n_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.0.22/src/commands/help.ts)_\n\n## `codegen init`\n\nInitialize The Codegen Project in your project\n\n```\nUSAGE\n $ codegen init [--help] [--input-file ] [--config-name ] [--input-type asyncapi|openapi]\n [--output-directory ] [--config-type esm|json|yaml|ts] [--languages typescript] [--no-tty]\n [--include-payloads] [--include-headers] [--include-client] [--include-parameters] [--include-channels]\n [--gitignore-generated]\n\nFLAGS\n --config-name= [default: codegen] The name to use for the configuration file (dont include file\n extension)\n --config-type=