# Contributing

> How to report bugs and share ideas, and how team members work on Livemark.

> [!WARNING]
> **We don't accept pull requests from outside contributors.** Pull requests opened by anyone outside the team are closed without review. If you've found a bug or have an idea, open an issue or start a discussion instead, as described below.

Livemark is an open-source project developed by the [Datist](https://datist.io) team. Everyone is welcome to help shape it with bug reports, ideas and questions; code changes come from team members.

## Contributors

### Report a bug

Open an issue on [GitHub Issues](https://github.com/datisthq/livemark/issues). A good report includes:

- the Livemark version and how you use it
- the smallest input that reproduces the problem
- the output you got and the output you expected

### Share an idea or ask a question

Use [GitHub Discussions](https://github.com/datisthq/livemark/discussions) for anything that isn't a bug:

- [Ideas](https://github.com/datisthq/livemark/discussions/new?category=ideas): features and improvements you'd like to see
- [Q&A](https://github.com/datisthq/livemark/discussions/new?category=q-a): questions about using Livemark
- [Show and tell](https://github.com/datisthq/livemark/discussions/new?category=show-and-tell): projects built with Livemark

Ideas the team picks up turn into issues.

## Members

The rest of this guide is for Datist team members working on Livemark.

### Quick start

You'll need [Node.js](https://nodejs.org/) 24+ and [pnpm](https://pnpm.io/) 11+. Then:

```bash
git clone https://github.com/datisthq/livemark.git
cd livemark
pnpm install
pnpm start
```

`pnpm start` boots the dev server against this repo's own `livemark/docs/` so you can iterate on Livemark while seeing the result in your browser. Edits to `livemark/source/`, `markdown/source/` or `livemark/docs/` reload automatically.

### Repository layout

```
├── livemark/               # the `livemark` package: CLI, site and escapable UI
│   ├── source/             # its code (compiles into build/)
│   │   ├── actions/        # build-time orchestration (config, articles, changelog)
│   │   ├── commands/       # `livemark <cmd>` CLI entrypoints
│   │   ├── components/     # site React components (overridable via .livemark/)
│   │   ├── elements/       # shadcn-style primitives (overridable)
│   │   ├── helpers/        # internal utilities (private)
│   │   ├── hooks/          # public React hooks
│   │   ├── plugins/        # the site's Vite plugins
│   │   ├── routes/         # TanStack Start routes
│   │   ├── models/         # Zod schemas
│   │   ├── content/        # derivations over the loaded articles
│   │   └── vite.config.ts  # the Vite config consumers run against
│   ├── shims/              # `livemark/components/*` etc. for files that live in markdown/
│   ├── skills/             # agent skills shipped to people who install Livemark
│   ├── docs/               # livemark.dev's content (not published)
│   └── blog/               # livemark.dev's blog posts (not published)
├── markdown/               # the internal `@livemark/markdown` package
│   └── source/             # the Markdown pipeline, and the components, elements and
│                           # styles articles render with (overridable too)
├── vite/                   # the public `@livemark/vite` package
│   └── source/             # the Vite plugin and what apps import beside it
├── .scripts/               # repo tooling and repo-wide guards
└── livemark.config.ts      # livemark.dev's livemark config
```

Each package ships `source/` and `build/`: Node loads `build/*.js`, while Vite bundles raw TS from `source/*` so the literal `.ts` import extensions resolve. A site is assembled from `markdown/source`, then `livemark/source` over it, then the project's `.livemark/` escapes; no path exists in both packages.

### Local commands

| Command            | What it does                                |
| ------------------ | ------------------------------------------- |
| `pnpm start`       | Run the dev server against this repo's docs |
| `pnpm build:docs`  | Production build of the docs site           |
| `pnpm build`       | Compile each package's `source/` → `build/` |
| `pnpm check:types` | Type-check (no emit)                        |
| `pnpm check:lint`  | Format check + lint via vite-plus           |
| `pnpm check`       | Lint + type                                 |
| `pnpm format`      | Auto-fix formatting                         |
| `pnpm test:unit`   | Run unit tests (Vitest)                     |
| `pnpm test`        | Lint + type + unit                          |

A change is ready to push when `pnpm test` is green and `pnpm build:docs` succeeds.

### Code conventions

- **TypeScript**: strict mode is on. Don't use `any`, the `as` cast, or non-null `!` without a clear reason — flag it in the PR.
- **Imports**: use full ESM paths with the `.ts(x)` extension (`from "./foo.ts"`). Tsgo rewrites them to `.js` on emit via `rewriteRelativeImportExtensions`.
- **Comments**: docstrings on exports. A `//` comment must name the mistake it prevents, stays under about three lines, and comments never outnumber code — rationale and history belong in git.
- **File layout**: high-level public items at the top, private helpers at the bottom.
- **Tests**: place unit tests in `<module>.unit.ts` next to the code. No "Arrange/Act/Assert" comments — the structure should be obvious.
- **Formatting**: vite-plus via `pnpm format`. 2-space indent, no semicolons, double quotes, 90 columns.

### Proposing a change

1. **Open an issue first** for anything bigger than a typo or a small bug. It's much easier to align on direction before code.
2. **Branch from `main`** with a short descriptive name (e.g. `fix-mobile-toc`, `feat-yaml-frontmatter`).
3. **Write a focused commit history**. Livemark uses [Conventional Commits](https://www.conventionalcommits.org/) — the prefix drives release-please:
   - `fix:` — bug fix in a published package (`livemark/` or `markdown/`) → patch release
   - `feat:` — new feature in a published package → minor release
   - `chore:`, `docs:`, `refactor:`, `test:` — no release; use these for CI, tooling, dependencies, the docs site and anything else an installer never sees
   - never mark a commit breaking (`!` or a `BREAKING CHANGE:` footer) without a maintainer agreeing to a major release
4. **Run `pnpm test` and `pnpm build:docs`** before pushing.
5. **Open a PR** against `main`. Describe the _why_ (link the issue), include screenshots for any UI change, and call out anything reviewers should pay extra attention to.

### Releases

Releases are driven by [release-please](https://github.com/googleapis/release-please). A `feat` or `fix` landing on `main` opens a Release PR with the computed version and changelog; merging that PR tags, publishes and creates the GitHub release. Maintainers never bump versions by hand — `.release/manifest.json` is maintained by release-please.
