Contributing

May 2, 2026 · View on GitHub

Thanks for your interest in Content Machine! Here's how to get started.

Your First Contribution

New here? Look for issues labeled good first issue. These are scoped, well-described, and a great way to learn the codebase.

Not sure where to start? Some areas that always welcome help:

  • Improving user docs in docs/user/
  • Adding example scripts to docs/user/examples/
  • Writing tests for uncovered code paths
  • Bug fixes (check open issues)

Setup

git clone https://github.com/45ck/content-machine.git
cd content-machine

nvm install && nvm use   # or ensure Node.js >= 20.6
npm install
cp .env.example .env     # add API keys as needed

npm run cm -- --help     # verify it works

Development Workflow

  1. Create a branch: git checkout -b my-feature
  2. Make your changes
  3. Run checks: npm run quality (typecheck, lint, format, tests)
  4. Commit and open a PR

Running Checks Individually

npm run typecheck      # TypeScript
npm run lint:fix       # ESLint (auto-fix)
npm run format         # Prettier
npm test               # Vitest (watch mode)
npm run test:run       # Vitest (single run)
npm run test:coverage  # With coverage report
npm run docs:check     # User/demo docs, links, and showcase status
npm run dup:check      # Duplication check when refactoring

Writing Tests

We use Vitest with test fakes in src/test/stubs/:

import { FakeLLMProvider } from '@/test/stubs/fake-llm.js';

const fakeLLM = new FakeLLMProvider();
fakeLLM.queueJsonResponse({ script: '...' });

We recommend writing tests alongside your changes. For bug fixes, a regression test is appreciated.

Pull Requests

Before submitting:

  • npm run quality passes
  • No hardcoded secrets
  • New code has test coverage
  • Docs updated if behavior changed

Keep PRs focused — one feature or fix per PR. We'll review within a few days.

Code Style

  • TypeScript with strict mode
  • camelCase for variables/functions, PascalCase for types, kebab-case for files
  • Structured logging via Pino (createLogger('module-name'))
  • Errors use types from src/core/errors.ts

Documentation

  • User docs live in docs/user/ — keep these approachable
  • Developer docs live in docs/dev/ — dated filenames use YYYYMMDD suffix convention
  • Reference docs in docs/reference/ are auto-generated — edit the YAML registries instead:
    • registry/repo-facts.yamlnpm run repo-facts:gen
    • registry/ubiquitous-language.yamlnpm run glossary:gen

Getting Help

  • Questions: open an issue with [question] in the title
  • Bugs: include the command you ran, expected vs actual behavior, and --verbose output
  • Security: see SECURITY.md — do not use public issues for security reports

License

By contributing, you agree that your contributions will be licensed under the MIT License.