Initial Commit
This commit is contained in:
126
.claude/templates/README.md
Normal file
126
.claude/templates/README.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# README-generation templates
|
||||
|
||||
This directory holds `@suaveplan/templates` engine templates for auto-generating
|
||||
`README.md` files at three levels of the `packages/` tree.
|
||||
|
||||
| Template | Target path | Purpose |
|
||||
|----------|-------------|---------|
|
||||
| `package-readme.template.md` | `packages/<category>/<plugin>/<pkg>/README.md` | Stand-alone npm-package readme |
|
||||
| `plugin-readme.template.md` | `packages/<category>/<plugin>/README.md` | Index of packages inside one plugin |
|
||||
| `category-readme.template.md` | `packages/<category>/README.md` | Index of all packages in a category |
|
||||
|
||||
## How to render
|
||||
|
||||
Load the template file as a string, build a context object, and pass both to
|
||||
`TemplateEngine` with the **loop-aware preset**:
|
||||
|
||||
```ts
|
||||
import {
|
||||
TemplateEngine,
|
||||
fullPresetWithLoops,
|
||||
} from "@suaveplan/templates";
|
||||
import type { ParseState } from "@suaveplan/templates";
|
||||
|
||||
const engine = new TemplateEngine();
|
||||
engine.usePreset(
|
||||
fullPresetWithLoops(
|
||||
(tpl, ctx, state) =>
|
||||
(engine as unknown as { parseInternal: Function }).parseInternal(
|
||||
tpl,
|
||||
ctx,
|
||||
state
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const template = await Bun.file(
|
||||
".claude/templates/package-readme.template.md"
|
||||
).text();
|
||||
|
||||
const context = {
|
||||
packageName: "@suaveplan/api-plugin-vault",
|
||||
shortDescription: "Per-user vault HTTP plugin for `@suaveplan/api`.",
|
||||
summary: "Per-user vault HTTP plugin...",
|
||||
installCommand: "bun add @suaveplan/api-plugin-vault",
|
||||
quickStartCode: `import { createVaultPlugin } from "@suaveplan/api-plugin-vault";`,
|
||||
quickStartDescription: "After `registry.start()`, the vault plugin...",
|
||||
features: [
|
||||
"Persists `site` records under SurrealDB...",
|
||||
"Enforces per-organization and per-site caps...",
|
||||
],
|
||||
modules: [
|
||||
{ name: "error-codes/error-codes", path: "./src/error-codes/error-codes.md", description: "9 stable `VAULT_PLUGIN_*` codes." },
|
||||
{ name: "plugin/plugin", path: "./src/plugin/plugin.md", description: "`createVaultPlugin` factory." },
|
||||
],
|
||||
otelInstruments: [
|
||||
{ type: "Counter", name: "webhook_plugin.deliveries_total", labels: "{event,status,endpoint_id}" },
|
||||
],
|
||||
otelStatusValues: "`delivered`, `exhausted`, `not_found`",
|
||||
license: "MIT",
|
||||
};
|
||||
|
||||
const readme = engine.parse(template, context);
|
||||
```
|
||||
|
||||
## Context shapes
|
||||
|
||||
### `package-readme.template.md`
|
||||
|
||||
| Key | Type | Required | Notes |
|
||||
|-----|------|----------|-------|
|
||||
| `packageName` | `string` | ✅ | Full scoped name, e.g. `@suaveplan/templates` |
|
||||
| `shortDescription` | `string` | ✅ | ≤120 characters; appended to H1 |
|
||||
| `summary` | `string` | ✅ | Multi-line paragraph(s) |
|
||||
| `installCommand` | `string` | ✅ | Shell command, e.g. `bun add @suaveplan/templates` |
|
||||
| `quickStartCode` | `string` | ✅ | Code inside the `ts` fence (no backticks) |
|
||||
| `quickStartDescription` | `string` | ❌ | Paragraph after the quick-start block |
|
||||
| `features` | `string[]` | ❌ | Renders the "What it does" section |
|
||||
| `modules` | `{name,path,description}[]` | ✅ | Module index bullets |
|
||||
| `otelInstruments` | `{type,name,labels?}[]` | ❌ | Renders the "OpenTelemetry" section |
|
||||
| `otelStatusValues` | `string` | ❌ | Sentence fragment after the instrument list |
|
||||
| `license` | `string` | ✅ | e.g. `MIT` |
|
||||
|
||||
### `plugin-readme.template.md`
|
||||
|
||||
| Key | Type | Required |
|
||||
|-----|------|----------|
|
||||
| `pluginName` | `string` | ✅ |
|
||||
| `pluginDescription` | `string` | ✅ |
|
||||
| `packages` | `{name,path,description}[]` | ✅ |
|
||||
|
||||
### `category-readme.template.md`
|
||||
|
||||
| Key | Type | Required |
|
||||
|-----|------|----------|
|
||||
| `categoryName` | `string` | ✅ |
|
||||
| `categoryDescription` | `string` | ✅ |
|
||||
| `packages` | `{name,path,description}[]` | ✅ |
|
||||
|
||||
## Brace-escaping caveat
|
||||
|
||||
The `@suaveplan/templates` engine scans the **entire** template (including text
|
||||
inside code blocks) for `{identifier}` tokens. If a context string contains a
|
||||
literal brace pair that looks like a variable — e.g. `GET /sites/{id}/public` —
|
||||
the engine will try to resolve it and, when the identifier is absent from
|
||||
context, replace it with an empty string.
|
||||
|
||||
When building context objects, avoid bare `{foo}` patterns. Safe work-arounds:
|
||||
|
||||
1. **Add a space** — `{ id }` does not match any plugin regex.
|
||||
2. **Back-tick wrapping** — `` `{id}` `` is still scanned, but if the value is
|
||||
not in context the engine replaces it with `""`. Only use this when the
|
||||
loss of the braces is acceptable.
|
||||
3. **Post-process** — after rendering, run a regex replace that restores any
|
||||
sentinels you placed in the context strings (e.g. `«LBRACE»` → `{`).
|
||||
|
||||
Because the package-level readme is aimed at npm consumers with no knowledge of
|
||||
the monorepo, the generated text should already avoid monorepo-specific tags
|
||||
(`genesis`, migration phases, universal tiers, etc.). The AI generating the
|
||||
context object is responsible for stripping that content before rendering.
|
||||
|
||||
## Conditional nesting
|
||||
|
||||
The `@suaveplan/templates` conditional plugin (`{if:…}…{/if}`) does not support
|
||||
nesting. The package template keeps all conditionals at the top level so they
|
||||
never wrap each other. Loop bodies may contain inner conditionals safely because
|
||||
the loop plugin resolves them recursively before the outer conditional runs.
|
||||
Reference in New Issue
Block a user