Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
groups:
zenstack:
patterns:
- "@zenstackhq/*"
dev-dependencies:
dependency-type: development
exclude-patterns:
- "@zenstackhq/*"
open-pull-requests-limit: 10

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
135 changes: 135 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Agent Guidelines — zenstack-docs-plugin

## Project overview

ZenStack CLI plugin that generates Markdown documentation from ZModel schemas. Pure function: AST in, Markdown files out. No template engines, no runtime dependencies beyond `@zenstackhq/language` and `@zenstackhq/sdk`.

Entry point: `src/index.ts` exports a `CliPlugin`. The orchestrator is `src/generator.ts`. Each entity type has a dedicated renderer in `src/renderers/`.

## Git and commits

This project uses [Conventional Commits](https://www.conventionalcommits.org/) with [Release Please](https://github.com/googleapis/release-please) for automated versioning. Commit message format matters — it determines version bumps and changelog entries.

### Commit message format

```
<type>[optional scope]: <description>
```

### Types and their effect

| Type | Version bump | Changelog |
|---|---|---|
| `feat` | minor | visible |
| `fix` | patch | visible |
| `perf` | patch | visible |
| `docs` | none | hidden |
| `test` | none | hidden |
| `refactor` | none | hidden |
| `chore` | none | hidden |
| `ci` | none | hidden |

### Breaking changes

Append `!` after the type: `feat!: rename diagramFormat option`. This bumps major (or minor while pre-1.0).

### Branch naming

- Features: `feature/<short-description>`
- Fixes: `fix/<short-description>`
- Docs: `docs/<short-description>`
- Chores: `chore/<short-description>`

### Rules

- Never force-push to `main`.
- Never amend commits that have been pushed.
- Always create a branch and PR for changes — do not commit directly to `main`.
- PR titles should follow the same conventional commit format (GitHub uses the PR title as the merge commit message).

## Code style

### TypeScript

- Strict mode with `noUncheckedIndexedAccess` — every indexed access needs a null check or `!` assertion.
- No `any` — write type guards instead of type assertions.
- Use `function` declarations, not arrow-function expressions (the `func-style` lint rule is disabled for this reason).
- Filenames are kebab-case.
- Use `import type` for type-only imports.
- ESM only (`"type": "module"` in package.json).

### Lint

Uses `eslint-config-canonical` with project-specific overrides in `eslint.config.js`. Run `pnpm run lint` before committing. Key overrides:

- `!= null` checks are allowed (idiomatic null/undefined coalescing).
- `console` usage is allowed (CLI plugin).
- Non-null assertions (`!`) are allowed after guarded regex matches and array lookups.
- `perfectionist/sort-modules` is enforced — exported functions must come before non-exported ones, and functions should be in alphabetical order.

### Formatting

Prettier is integrated via `eslint-config-canonical`. Do not add a separate prettier config — it runs through ESLint.

## Testing

- Framework: vitest
- Run: `pnpm test`
- Tests call the public `generate()` function through helpers in `test/utils.ts`, then assert on the generated Markdown output.
- Use Red-Green TDD: write a failing test first, then implement.
- Update snapshots with `pnpm test -- --update`.

### Test helpers

| Function | Purpose |
|---|---|
| `generateFromSchema(schema, options?)` | Parse inline ZModel, generate docs to temp dir |
| `readDoc(tmpDir, ...segments)` | Read a generated doc file |
| `findFieldLine(doc, fieldName)` | Find a field's table row |
| `findBrokenLinks(outputDir)` | Verify all relative links resolve |

## Build and verify

```bash
pnpm run typecheck # tsc --noEmit
pnpm run lint # eslint
pnpm test # vitest run
pnpm run build # tsc --noEmit && tsup-node
```

Always run typecheck, lint, and test before pushing. CI runs all three on Node 20 and 22.

## Architecture notes

### Renderers

Every renderer follows the same pattern: accept AST node(s) and options, build a `string[]` where each element is one line, join with `'\n'`, return the full page. Conditional sections are omitted by not pushing lines.

### Extractors

`src/extractors.ts` contains pure functions for pulling data from the ZModel AST. Keep extraction separate from rendering.

### Diagram pipeline

Mermaid blocks in rendered markdown are post-processed by `src/renderers/diagram-processor.ts`. It supports three modes via `diagramFormat` (`mermaid`, `svg`, `both`) and two embed modes via `diagramEmbed` (`file`, `inline`). SVG rendering uses `beautiful-mermaid`.

### Adding a new plugin option

1. Add the option to `PluginOptions` in `src/types.ts`
2. Parse it in `resolvePluginOptions()` in `src/generator.ts`
3. If it controls rendering, add it to `RenderOptions` and `resolveRenderOptions()` in `src/extractors.ts`
4. Update `README.md` configuration table
5. Add tests

### Adding a new section to a page

1. Write a failing test
2. Add rendering logic to the renderer in `src/renderers/`
3. If needed, add extraction logic in `src/extractors.ts`
4. If toggleable, add a boolean to `RenderOptions`

## Dependencies

- `@zenstackhq/language` and `@zenstackhq/sdk` are **peer dependencies** — the consuming project provides them.
- `beautiful-mermaid` is the only runtime dependency (SVG rendering).
- Use `pnpm` as the package manager.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

A [ZenStack](https://zenstack.dev) community plugin that automatically generates rich, browsable Markdown documentation from your ZModel schema — every time you run `zenstack generate`.

> ℹ️ This project is not affiliated with or endorsed by the ZenStack team.

## Why

Your ZModel schema is already the single source of truth for your data layer: models, relationships, enums, access policies, validation rules, computed fields, procedures. But that knowledge is locked inside `.zmodel` files that non-engineers can't easily read, and manually-maintained wiki pages inevitably drift.
Expand Down