|
| 1 | +# Agent Guidelines — zenstack-docs-plugin |
| 2 | + |
| 3 | +## Project overview |
| 4 | + |
| 5 | +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`. |
| 6 | + |
| 7 | +Entry point: `src/index.ts` exports a `CliPlugin`. The orchestrator is `src/generator.ts`. Each entity type has a dedicated renderer in `src/renderers/`. |
| 8 | + |
| 9 | +## Git and commits |
| 10 | + |
| 11 | +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. |
| 12 | + |
| 13 | +### Commit message format |
| 14 | + |
| 15 | +``` |
| 16 | +<type>[optional scope]: <description> |
| 17 | +``` |
| 18 | + |
| 19 | +### Types and their effect |
| 20 | + |
| 21 | +| Type | Version bump | Changelog | |
| 22 | +|---|---|---| |
| 23 | +| `feat` | minor | visible | |
| 24 | +| `fix` | patch | visible | |
| 25 | +| `perf` | patch | visible | |
| 26 | +| `docs` | none | hidden | |
| 27 | +| `test` | none | hidden | |
| 28 | +| `refactor` | none | hidden | |
| 29 | +| `chore` | none | hidden | |
| 30 | +| `ci` | none | hidden | |
| 31 | + |
| 32 | +### Breaking changes |
| 33 | + |
| 34 | +Append `!` after the type: `feat!: rename diagramFormat option`. This bumps major (or minor while pre-1.0). |
| 35 | + |
| 36 | +### Branch naming |
| 37 | + |
| 38 | +- Features: `feature/<short-description>` |
| 39 | +- Fixes: `fix/<short-description>` |
| 40 | +- Docs: `docs/<short-description>` |
| 41 | +- Chores: `chore/<short-description>` |
| 42 | + |
| 43 | +### Rules |
| 44 | + |
| 45 | +- Never force-push to `main`. |
| 46 | +- Never amend commits that have been pushed. |
| 47 | +- Always create a branch and PR for changes — do not commit directly to `main`. |
| 48 | +- PR titles should follow the same conventional commit format (GitHub uses the PR title as the merge commit message). |
| 49 | + |
| 50 | +## Code style |
| 51 | + |
| 52 | +### TypeScript |
| 53 | + |
| 54 | +- Strict mode with `noUncheckedIndexedAccess` — every indexed access needs a null check or `!` assertion. |
| 55 | +- No `any` — write type guards instead of type assertions. |
| 56 | +- Use `function` declarations, not arrow-function expressions (the `func-style` lint rule is disabled for this reason). |
| 57 | +- Filenames are kebab-case. |
| 58 | +- Use `import type` for type-only imports. |
| 59 | +- ESM only (`"type": "module"` in package.json). |
| 60 | + |
| 61 | +### Lint |
| 62 | + |
| 63 | +Uses `eslint-config-canonical` with project-specific overrides in `eslint.config.js`. Run `pnpm run lint` before committing. Key overrides: |
| 64 | + |
| 65 | +- `!= null` checks are allowed (idiomatic null/undefined coalescing). |
| 66 | +- `console` usage is allowed (CLI plugin). |
| 67 | +- Non-null assertions (`!`) are allowed after guarded regex matches and array lookups. |
| 68 | +- `perfectionist/sort-modules` is enforced — exported functions must come before non-exported ones, and functions should be in alphabetical order. |
| 69 | + |
| 70 | +### Formatting |
| 71 | + |
| 72 | +Prettier is integrated via `eslint-config-canonical`. Do not add a separate prettier config — it runs through ESLint. |
| 73 | + |
| 74 | +## Testing |
| 75 | + |
| 76 | +- Framework: vitest |
| 77 | +- Run: `pnpm test` |
| 78 | +- Tests call the public `generate()` function through helpers in `test/utils.ts`, then assert on the generated Markdown output. |
| 79 | +- Use Red-Green TDD: write a failing test first, then implement. |
| 80 | +- Update snapshots with `pnpm test -- --update`. |
| 81 | + |
| 82 | +### Test helpers |
| 83 | + |
| 84 | +| Function | Purpose | |
| 85 | +|---|---| |
| 86 | +| `generateFromSchema(schema, options?)` | Parse inline ZModel, generate docs to temp dir | |
| 87 | +| `readDoc(tmpDir, ...segments)` | Read a generated doc file | |
| 88 | +| `findFieldLine(doc, fieldName)` | Find a field's table row | |
| 89 | +| `findBrokenLinks(outputDir)` | Verify all relative links resolve | |
| 90 | + |
| 91 | +## Build and verify |
| 92 | + |
| 93 | +```bash |
| 94 | +pnpm run typecheck # tsc --noEmit |
| 95 | +pnpm run lint # eslint |
| 96 | +pnpm test # vitest run |
| 97 | +pnpm run build # tsc --noEmit && tsup-node |
| 98 | +``` |
| 99 | + |
| 100 | +Always run typecheck, lint, and test before pushing. CI runs all three on Node 20 and 22. |
| 101 | + |
| 102 | +## Architecture notes |
| 103 | + |
| 104 | +### Renderers |
| 105 | + |
| 106 | +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. |
| 107 | + |
| 108 | +### Extractors |
| 109 | + |
| 110 | +`src/extractors.ts` contains pure functions for pulling data from the ZModel AST. Keep extraction separate from rendering. |
| 111 | + |
| 112 | +### Diagram pipeline |
| 113 | + |
| 114 | +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`. |
| 115 | + |
| 116 | +### Adding a new plugin option |
| 117 | + |
| 118 | +1. Add the option to `PluginOptions` in `src/types.ts` |
| 119 | +2. Parse it in `resolvePluginOptions()` in `src/generator.ts` |
| 120 | +3. If it controls rendering, add it to `RenderOptions` and `resolveRenderOptions()` in `src/extractors.ts` |
| 121 | +4. Update `README.md` configuration table |
| 122 | +5. Add tests |
| 123 | + |
| 124 | +### Adding a new section to a page |
| 125 | + |
| 126 | +1. Write a failing test |
| 127 | +2. Add rendering logic to the renderer in `src/renderers/` |
| 128 | +3. If needed, add extraction logic in `src/extractors.ts` |
| 129 | +4. If toggleable, add a boolean to `RenderOptions` |
| 130 | + |
| 131 | +## Dependencies |
| 132 | + |
| 133 | +- `@zenstackhq/language` and `@zenstackhq/sdk` are **peer dependencies** — the consuming project provides them. |
| 134 | +- `beautiful-mermaid` is the only runtime dependency (SVG rendering). |
| 135 | +- Use `pnpm` as the package manager. |
0 commit comments