Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

126
.claude/templates/README.md Normal file
View 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.