184 lines
7.1 KiB
Markdown
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" }
|
|
}
|
|
```
|
|
|