regime/README.md
2026-05-07 14:03:54 +02:00

184 lines
7.1 KiB
Markdown

# REGIME
> Tooling and unified configuration for managing a bunch of repositories and packages.
## Stack & Standards
- Bun
- TypeScript 7
- Oxlint & Oxfmt
- Commitlint
- Conventional Commit
- Semantic Release
- Forgejo Actions
- [Gum](https://github.com/charmbracelet/gum)
## `regime` CLI
```
regime <check|sync|promote|templates> [path] [--yes] [--full]
```
If `[path]` is omitted, the current working directory is used. Regime discovers all `regime.config.json` files recursively under the target path (skipping `node_modules` and `.git`).
### Commands
#### `regime check [path] [--full]`
Compares managed files against their templates and reports differences. For each `regime.config.json` found:
- **overwrite** files: reports `missing` or `differs`
- **merge json / merge jsonc** files: reports field-level diffs -- missing fields, wrong values, and what the expected value should be
By default only problems are shown. Pass `--full` to also print fields/files that are already in sync.
#### `regime sync [path]`
Writes template-managed files into each project. For each `regime.config.json` found:
- **overwrite** files: created or replaced with the template content (with variable interpolation)
- **merge json / merge jsonc** files: deep-merged so that template-required fields are present while preserving any extra fields the project has added
Files and directories are created if they don't exist. Files already in sync are skipped silently.
#### `regime promote [path] [--yes]`
Interactively promotes a local file change back into a template. Only applies to **overwrite**-strategy files that differ from their template.
1. Presents a filterable list of changed files (via `gum filter`)
2. If the template chain has multiple templates, asks which template to write to (via `gum choose`)
3. De-interpolates variable values back into `<<varname>>` placeholders
4. Shows a diff of the proposed change
5. Asks for confirmation (skip with `--yes`)
6. Writes the updated file into the template directory
Requires [gum](https://github.com/charmbracelet/gum) to be installed.
#### `regime templates [--full]`
Lists all available templates as a tree showing inheritance relationships. Pass `--full` to also list the files each template provides.
## Templates
### Opting In
A project places a `regime.config.json` in its root (or in each workspace package):
```json
{
"templates": ["profile/library", "workflow/mirror", "adapts-to/bun"],
"vars": {
"repo": "my-project"
}
}
```
- `templates` -- a string or array of template names (paths relative to `templates/`)
- `vars` -- key-value pairs for `<<key>>` interpolation in template file contents and filenames
### Structure
Each template is a directory under `templates/` containing:
- `.regime-template.json` -- metadata (inheritance and file strategies)
- Any other files -- the template content synced into target repos
A `.regime-template.json` looks like:
```json
{
"inherits": ["shared/package"],
"patterns": {
"package.json": "merge json",
"tsconfig.*.json": "merge json"
}
}
```
- `inherits` -- parent templates resolved first (depth-first; parents before children)
- `patterns` -- maps file paths or globs to a file strategy
### File Strategies
| Strategy | Behavior |
|----------|----------|
| `overwrite` (default) | Template file replaces the target file entirely. |
| `merge json` | Deep-merged into existing JSON. Template values win for shared keys; target-only keys are preserved; arrays are unioned (template items first, then unique target items). |
| `merge jsonc` | Like `merge json` but parses/writes JSONC (JSON with comments and trailing commas). |
When multiple templates in a chain provide the same file:
- **overwrite**: the last template in the chain wins
- **merge json / merge jsonc**: all template versions are merged in chain order, then merged into the target
### Variable Interpolation
Template files can contain `<<varname>>` placeholders in both their **content** and **filenames** (including directory components). These are replaced with values from the project's `vars` during `check` and `sync`.
For example, a template file named `<<repo>>.code-workspace` with `vars: { "repo": "route" }` produces `route.code-workspace` in the target.
The `promote` command reverses this (de-interpolation), replacing concrete values back into `<<varname>>` placeholders before writing to the template. Undeclared variables emit a warning and remain as-is.
### Indentation
When updating existing JSON/JSONC files, regime detects and preserves the file's existing indentation style. New files default to 2-space indent (JSON) or tab indent (JSONC).
### Template Categories
```
templates/
shared/ foundational building blocks
include/ files included by inheritance only (not used directly)
profile/ complete project profiles (composed from shared + include)
adapts-to/ runtime/platform adapters
tool/ dev tooling (commitlint, husky, oxc)
workflow/ Forgejo CI workflows
```
### Available Templates
| Template | Inherits | Description |
|----------|----------|-------------|
| `shared/repo` | `include/license` | Pulls in LICENSE. |
| `shared/package` | -- | Base `package.json` (license, author, repository with `<<repo>>`). Merges `package.json`, `tsconfig.json`, `tsconfig.*.json`. |
| `shared/library` | `shared/package` | Full TypeScript library setup (tsconfig variants for src, test, config). |
| `include/license` | -- | MIT license file. |
| `profile/library` | `shared/repo`, `shared/library` | Standalone library repo with license + full TS setup. |
| `profile/monorepo/root` | `shared/repo`, `shared/package` | Monorepo root with workspaces catalog and workspace-wide scripts. |
| `profile/monorepo/library` | `shared/library` | Workspace package inside a monorepo (no license or repo-level files). |
| `profile/workspace` | -- | VS Code `.code-workspace` file (merges JSONC). Uses `<<repo>>` in filename. |
| `adapts-to/bun` | -- | Adds `@types/bun`, bun type references, `tsconfig.bun.json`. |
| `adapts-to/cloudflare` | -- | Adds `@cloudflare/workers-types`, cloudflare type references, `tsconfig.cloudflare.json`. |
| `tool/commitlint` | -- | Commitlint config, deps, and husky hook. |
| `tool/husky` | -- | Husky dep and prepare script. |
| `tool/oxc` | -- | Oxlint + oxfmt configs, deps, and lint script. |
| `workflow/checks` | -- | Forgejo CI workflow for lint/check/test. |
| `workflow/mirror` | -- | Forgejo workflow for mirroring to GitHub. |
| `workflow/publish-npm` | -- | Forgejo release workflow with semantic-release config. |
### Usage Examples
Standalone library:
```json
{
"templates": ["profile/library", "profile/workspace", "tool/oxc", "tool/commitlint", "tool/husky", "workflow/mirror", "workflow/publish-npm", "adapts-to/bun"],
"vars": { "repo": "route" }
}
```
Monorepo root:
```json
{
"templates": ["profile/monorepo/root", "profile/workspace", "tool/oxc", "tool/commitlint", "tool/husky", "workflow/mirror", "workflow/publish-npm"],
"vars": { "repo": "toolkit" }
}
```
Monorepo workspace package:
```json
{
"templates": ["profile/monorepo/library"],
"vars": { "repo": "toolkit" }
}
```