rlsbl 0.110.2 → 0.111.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +29 -28
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  # rlsbl
8
8
 
9
- Release orchestration and project scaffolding for npm, PyPI, Go, and [15 more release targets](https://rlsbl.smmh.dev/targets).
9
+ Release orchestration and project scaffolding for npm, PyPI, Go, and [14 more release targets](https://rlsbl.smmh.dev/targets).
10
10
 
11
11
  ## Install
12
12
 
@@ -42,34 +42,34 @@ All commands auto-detect targets (versioning) from project files (`package.json`
42
42
  | `check` | Run project checks registered via the check framework and report results |
43
43
  | `status` | Display the current project version, branch, last release tag, unreleased commit count, and changelog coverage. Outputs plain text by default or structured JSON with the --json flag. |
44
44
  | `scaffold` | Generate or update CI/CD workflows, git hooks, changelog, and license files. Safe to run repeatedly -- three-way merges template changes with your customizations. Existing files with no stored merge base are healed from their last scaffold commit before merging. |
45
- | `check-name` | Query npm, PyPI, crates.io, or other registries to check whether one or more package names are available. Accepts multiple names as positional arguments and respects a configurable delay between checks. |
45
+ | `check-name` | Query npm, PyPI, or other registries to check whether one or more package names are available. Accepts multiple names as positional arguments and respects a configurable delay between checks. |
46
46
  | `claim-name` | Claim a name on a package registry by publishing a minimal placeholder package. Runs check-name first, then publishes if available. |
47
47
  | `discover` | Search GitHub for repositories tagged with the rlsbl topic and list them. Use --mine to filter results to only your own repositories. Requires the gh CLI to be authenticated. |
48
48
  | `watch` | Poll GitHub Actions CI workflow runs for a specific commit SHA and report pass or fail status. Defaults to HEAD if no SHA is provided. Useful after rlsbl release to monitor the publish pipeline. |
49
- | `pre-push-check` | Verify that CHANGELOG.md contains an entry matching the current project version. Designed to run as a git pre-push hook to prevent pushing releases without documented changes. |
49
+ | `pre-push-check` | Removed. This command no longer performs any check: it always exits 1 with instructions. The pre-push hook now runs `rlsbl check --tag prepush` instead, so a repo whose hook still calls pre-push-check needs `rlsbl scaffold` to regenerate it. |
50
50
  | `prs` | List all open pull requests for the current repository using the GitHub CLI. Shows PR number, title, author, and branch for a quick overview of pending work. |
51
- | `push` | Push the current branch to origin with preflight checks: branch guard (refuses release branches), changelog coverage validation with actionable remediation hints, and behind-remote detection. Use `rlsbl release run` for release branches. |
52
51
  | `unreleased` | List commits between the latest release tag and HEAD, and check whether each has a corresponding changelog entry. Outputs a coverage report in plain text or JSON to help prepare the next release. |
53
- | `targets` | List all release targets detected in the current project directory, showing which ecosystems (npm, PyPI, Go, Cargo, etc.) are active based on manifest files found. |
52
+ | `targets` | List all release targets detected in the current project directory, showing which ecosystems (npm, PyPI, Go, etc.) are active based on manifest files found. |
54
53
  | `deploy` | Run the configured deployment pipeline for the project. Supports named deploy targets and dry-run preview of what would be deployed. Branch restrictions are always enforced. |
55
54
  | `commit` | Commit one or more files with an Autogenerated trailer, marking the commit as machine-generated so it is automatically exempted from changelog coverage checks. |
56
- | **release** | Release orchestration commands. Provides 9 subcommands covering the full release lifecycle: run, resume, init, retry, edit, undo, deprecate, yank, and scrub. |
57
- | `release run` | Bump version, validate the JSONL changelog, run tests and lint, commit, tag, push, and create a GitHub Release. Reads the bump type (patch, minor, major, or infra) and target selection from .rlsbl/releases/unreleased.toml, which can be scaffolded with rlsbl release init. Supports dry-run preview, non-interactive mode with --yes, and --allow-dirty to skip the clean working tree check. |
55
+ | **release** | Release orchestration commands covering the full release lifecycle. Provides 10 subcommands: run, resume, init, retry, edit, undo, deprecate, yank, scrub, reconcile. |
56
+ | `release run` | Bump version, validate the JSONL changelog, run tests and lint, commit, tag, push, and create a GitHub Release. Reads the bump type (patch, minor, major, or infra) and target selection from .rlsbl/releases/unreleased.toml, which can be scaffolded with rlsbl release init. Supports dry-run preview, --approve-consequential to skip the confirmation prompt in non-interactive contexts, and --allow-dirty to skip the clean working tree check. |
58
57
  | `release resume` | Resume a previously failed release from where it left off. Reads the in-progress state file (.rlsbl/releases/in-progress.json, or .rlsbl-monorepo/releasables/<name>/releases/in-progress.json for releasable releases), validates that the current branch matches the saved state, and re-enters the release flow, skipping already-completed steps. |
59
58
  | `release init` | Scaffold a .rlsbl/releases/unreleased.toml file by auto-detecting project targets. The generated file contains a default bump type (patch), an include list of all detected targets, and per-target configuration sections for Flutter targets. |
60
59
  | `release retry` | Dispatch CI/CD workflows for a completed release via gh workflow run. Reads the dispatch list and ref from .rlsbl/releases/retry.toml, which is auto-scaffolded with sensible defaults if missing. Verifies the GitHub Release exists before dispatching. Each workflow in the dispatch list is triggered against the configured ref (defaults to the release tag). |
61
60
  | `release edit` | Sync the GitHub Release notes for a given version with the corresponding CHANGELOG.md entry. Defaults to the current version if none is specified. Use --dry-run to preview changes without updating GitHub. |
62
61
  | `release undo` | Revert a release. Without --version, reverts the latest release (deletes GitHub Release, removes git tag, reverts version bump commit). With --version, reverts a non-latest release if it is provably unpublished (probes registries for evidence, deletes GitHub Release + tag only, un-finalizes changelog). |
63
62
  | `release deprecate` | Mark a past release as deprecated. Sets the GitHub Release pre-release flag and prepends a deprecation notice to the release notes. Use --reason to explain why and --use to suggest a replacement version. |
64
- | `release yank` | Remove a published version from package registries. Probes each configured target's registry to determine publication status, then executes registry-specific removal: npm deprecate, cargo yank, Go retract, or PyPI manual checklist. Also marks the GitHub Release as pre-release with a yank notice. |
63
+ | `release yank` | Remove a published version from package registries. Probes each configured target's registry to determine publication status, then executes registry-specific removal: npm deprecate, Go retract, or PyPI manual checklist. Also marks the GitHub Release as pre-release with a yank notice. |
65
64
  | `release scrub` | Scrub sensitive content from git history and update release metadata to match the rewritten commits. Supports 3 modes: match (--pattern), file (--file), or recipe (--recipe). After rewriting, remaps commit hashes in JSONL changelog files, regenerates CHANGELOG.md, force-pushes, and recreates GitHub Releases on the new tags. |
65
+ | `release reconcile` | Reconcile release metadata with a rewritten history: re-push the tags a rewrite moved and recreate the GitHub Releases attached to them. Reads safegit's rewrite journal (.git/safegit/rewrite-maps.jsonl) to determine what moved, so it works after ANY out-of-band rewrite, not just one driven by rlsbl release scrub. Fail-closed: a tag whose divergence from the remote the journal does not explain is a hard error, never a force-push. |
66
66
  | **changelog** | Structured changelog management using JSONL entries with 3 entry types (feature, fix, breaking). Add and generate CHANGELOG.md from per-commit changelog entries stored in unreleased.jsonl for precise, auditable release notes. |
67
67
  | `changelog add` | Append a structured changelog entry to the project's unreleased.jsonl file. Each entry includes a human-readable description, an entry type (feature, fix, or breaking), and optional commit hashes linking it to specific changes. The file is auto-committed by default. Use --no-user-facing to mark internal changes that should not appear in the published changelog. |
68
68
  | `changelog generate` | Compile all validated JSONL changelog entries into a formatted CHANGELOG.md file. Groups entries by type (features, fixes, breaking changes) under the appropriate version heading, preserving existing changelog content for previous releases. Use --dry-run to preview the generated Markdown output without writing to disk, which is useful for reviewing before committing. |
69
69
  | `changelog amend` | Append a changelog entry to a released version's JSONL file. Temporarily unlocks the read-only file, appends the entry, re-locks it, regenerates CHANGELOG.md, and syncs GitHub Release notes. Use --no-validate-hashes to skip hash validation for old or amended commits. |
70
70
  | `changelog edit` | Modify an existing changelog entry in unreleased or released JSONL files. Finds the entry by commit hash or entry ID, applies field changes (type, description, user-facing status), and rewrites the file atomically. For released files, temporarily unlocks the read-only file, regenerates CHANGELOG.md, and syncs GitHub Release notes. |
71
71
  | `changelog remap` | Remap stale commit hashes in JSONL changelog files using a mapping of old SHAs to new SHAs. Reads the mapping from a file (--map-file), the safegit rewrite journal (--from-journal), or stdin (--stdin). At least one source is required. Auto-commits with Autogenerated trailer. |
72
- | **monorepo** | Manage monorepo workspaces with multiple independently-versioned projects. Initialize workspaces, add or remove projects, sync CI workflows, check name availability, and analyze dependency graphs. Provides 16 monorepo subcommands plus a release subgroup, and supports all 18 release targets in a single workspace.toml. |
72
+ | **monorepo** | Manage monorepo workspaces with multiple independently-versioned projects. Initialize workspaces, add or remove projects, sync CI workflows, check name availability, and analyze dependency graphs. Supports all 18 release targets in a single workspace.toml. Provides 19 monorepo subcommands: init, add, remove, list, sync, status, check-names, outdated, snapshot, snapshot-check, mirror, graph, impact, extract, absorb, extract-releasable, cleanup, migrate-releasable, rename-releasable. Plus 1 subgroup: release. |
73
73
  | `monorepo init` | Create a new monorepo workspace by generating the .rlsbl-monorepo directory and an empty workspace.toml configuration file at the current directory. This must be run at the repository root before adding individual projects with the add subcommand. Each workspace tracks multiple independently-versioned projects that share a single git repository. |
74
74
  | `monorepo add` | Register a project directory in the monorepo workspace.toml configuration. The path argument specifies the project's location relative to the repo root. Supports 6 optional settings: display name, target registry, glob patterns for change detection, subtree remote URL, inter-project dependencies, and a library flag to mark shared code packages. |
75
75
  | `monorepo remove` | Unregister a project from the monorepo workspace.toml by its path. This removes the project entry from the workspace configuration file but does not delete any files, directories, or git history on disk. The project's code remains intact and can be re-added later with the add subcommand if needed. |
@@ -78,7 +78,8 @@ All commands auto-detect targets (versioning) from project files (`package.json`
78
78
  | `monorepo status` | Show the current version, last release tag, and number of unreleased commits for every project in the monorepo workspace. Provides a quick overview of which projects have pending changes and are ready for their next release. Projects with zero unreleased commits are shown as up-to-date. |
79
79
  | `monorepo check-names` | Check package name availability on a target registry for all projects in the monorepo workspace. Queries the registry API for each project name and reports whether it is available or already taken. Supports optional prefix and suffix arguments to test naming conventions like scoped packages, with a configurable delay between registry queries to avoid rate limiting. |
80
80
  | `monorepo outdated` | Scan all projects in the monorepo workspace for intra-workspace dependencies that reference older versions than what is currently available in the workspace. Lists each outdated dependency with the referenced version and the latest available version, helping identify which downstream projects need a version bump after upstream releases. |
81
- | `monorepo snapshot` | Generate a committed JSON artifact at .rlsbl-monorepo/snapshot.json summarizing all packages, versions, dependencies, and graph structure. Use --check to verify the snapshot is up-to-date without regenerating it (exits 1 if stale). |
81
+ | `monorepo snapshot` | Regenerate the committed JSON artifact at .rlsbl-monorepo/snapshot.json summarizing all packages, versions, dependencies, and graph structure, and commit it. Verifying without regenerating is a separate command, `rlsbl monorepo snapshot-check`. Under --dry-run the artifact is computed but neither written nor committed, and the preview names both steps. |
82
+ | `monorepo snapshot-check` | Verify that .rlsbl-monorepo/snapshot.json matches the workspace it describes, without regenerating it. Exits 1 when the artifact is stale or missing. This is the read-only half of the former `monorepo snapshot --check` flag; `rlsbl monorepo snapshot` is the half that writes. |
82
83
  | `monorepo mirror` | Reconcile a monorepo project's subtree mirror toward its desired state. The mirror is a tool-owned, derived artifact: it observes the remote, then converges it to exactly one scaffold commit atop the current deterministic subtree split, force-pushing (with lease) as the routine write. A tripwire refuses to touch a mirror carrying foreign (hand-authored) commits. Use --dry-run to print a plan (converged, behind, scaffold-missing, contract-violated, or virgin) without writing. |
83
84
  | `monorepo graph` | Export the monorepo dependency graph in JSON, DOT (Graphviz), or indented text tree format. Supports filtering by a root package (transitive deps) or reverse package (transitive rdeps), with optional depth limiting. Use --output to write to a file instead of stdout. |
84
85
  | `monorepo impact` | Analyze the impact of changes to a package, file, or git diff range on the monorepo dependency graph. Shows direct and transitive dependents, test scope, and release candidates. Supports package names, file paths, and --since for git-based change detection. |
@@ -89,11 +90,11 @@ All commands auto-detect targets (versioning) from project files (`package.json`
89
90
  | `monorepo migrate-releasable` | Migrate a releasable from per-package release state to the releasable model. Detects current state, consolidates per-package changelogs and versions into the releasable directory, creates a releasable-format migration tag, and removes orphaned per-package .rlsbl/changes/ and .rlsbl/releases/ directories. Requires the workspace to be in explicit mode (with [[releasables]] in workspace.toml). |
90
91
  | `monorepo rename-releasable` | Rename a releasable group. Rewrites the [[releasables]] name and every member's releasable field in workspace.toml (preserving comments), moves the releasable's state directory, drops the stale changelog validation cache, re-runs monorepo sync to regenerate publish gate prefixes, and commits everything as one commit. When the tag_format contains {name}, a boundary alias tag for the current version is created at the old tag's commit and pushed; historical releases stay under the old prefix. Idempotent: a crash between the commit and the tag push is healed by re-running. |
91
92
  | **dev** | Developer utilities for locally working with rlsbl projects, including editable installs that mirror the project's release target (pypi -> uv tool install -e, npm -> npm link, go -> go install). |
92
- | `dev install` | Install the project locally for development using the detected target's editable install command. --global (default) installs system-wide across 8 supported targets (pypi, npm, go, cargo, zig, swift, deno, hex), while --venv installs into the project's local environment instead. In monorepo mode, pair with --all, --include, or --exclude. Use --uninstall to reverse a previous install. |
93
+ | `dev install` | Install the project locally for development by running each detected target's own install command. --global (default) is supported by 7 targets: pypi (uv tool install -e), npm (npm link), go (go install), deno (deno install), and -- since they have no system-wide install concept -- zig (zig build install), swift (swift build), and hex (mix deps.get). --venv installs into the project's local environment instead and is supported by pypi, npm, deno, and hex; other targets are skipped with a reason. --uninstall reverses a previous install where the target supports it (pypi, npm, deno). In monorepo mode, pair with --all, --include, or --exclude. |
93
94
  | `dev sync` | Overlay local editable checkouts of sibling projects onto this project's locked environment. Reads dev-sources.toml.local-only for overlay entries, runs uv sync --inexact excluding overlaid packages, then uv pip install -e per entry. Requires UV_NO_SYNC=1 in the environment to prevent bare uv run from reverting overlays. |
94
95
  | `dev status` | Report the state of local dev-sync overlays: for each package recorded in the dev-overlays sentinel, show its declared editable checkout path and version alongside the venv's actual install (editable at the expected path, WIPED back to a registry wheel, or missing entirely). Exits 1 if any overlay drifted so scripts and pre-run guards can detect a silent wipe by a bare uv sync or uv run; exits 0 when all overlays are intact or none are declared. |
95
96
 
96
- Global flags: `--help`, `--version`, `--dry-run`, `--yes`, `--quiet`.
97
+ Global flags: `--help`, `--version`, `--dry-run`, `--approve-consequential`, `--quiet`, `--verbose`.
97
98
 
98
99
  ## Release flow
99
100
 
@@ -119,7 +120,13 @@ When you run `rlsbl release run`:
119
120
  18. Runs `.rlsbl/hooks/post-release.sh` if present (non-fatal)
120
121
  19. Prints `Watch CI: rlsbl watch <sha>`
121
122
 
122
- Use `--dry-run` to preview without changes. Use `--yes` for non-interactive mode (CI, AI agents).
123
+ Use `--dry-run` to preview without changes: mutating operations are recorded and printed as a
124
+ would-do log rather than performed. A small set of commands declares itself `consequential`
125
+ (`release run`/`resume`/`retry`/`undo`/`deprecate`/`yank`/`scrub`/`reconcile`, `claim-name`,
126
+ `deploy`, `monorepo release run`/`mirror`/`absorb`/`extract`/`extract-releasable`) and asks
127
+ for confirmation before running; pass `--approve-consequential` in non-interactive contexts
128
+ (CI, AI agents), where the prompt is a hard error instead. Every other command runs without
129
+ asking.
123
130
 
124
131
  Create the release file with `rlsbl release init`, which auto-detects project targets and scaffolds the TOML file.
125
132
 
@@ -132,7 +139,7 @@ Pre-release versions (e.g. `1.0.0-beta.1`) are supported.
132
139
  ```
133
140
  rlsbl scaffold # create or update CI/CD for all detected registries
134
141
  rlsbl scaffold --force # overwrite managed files (user-owned files still preserved)
135
- rlsbl scaffold --no-commit # skip auto-commit of scaffolded files
142
+ rlsbl scaffold --no-auto-commit # skip auto-commit of scaffolded files
136
143
  ```
137
144
 
138
145
  Created files are committed automatically by default.
@@ -167,7 +174,7 @@ See [docs/ci-customization.md](docs/ci-customization.md) for an example.
167
174
 
168
175
  ## Check system
169
176
 
170
- rlsbl includes 65 checks across 9 tags.
177
+ rlsbl includes 69 checks across 9 tags.
171
178
 
172
179
  | Tag | Checks | Description |
173
180
  |-----|--------|-------------|
@@ -188,8 +195,8 @@ rlsbl check --name lock # run a single check
188
195
  ## Undo
189
196
 
190
197
  ```
191
- rlsbl release undo # interactive: confirms before each destructive step
192
- rlsbl release undo --yes # non-interactive: auto-confirms, auto-pushes
198
+ rlsbl release undo # interactive: confirms once, then auto-pushes
199
+ rlsbl release undo --approve-consequential # non-interactive: skips the confirmation
193
200
  ```
194
201
 
195
202
  Reverts the last release:
@@ -197,7 +204,7 @@ Reverts the last release:
197
204
  1. Deletes the GitHub Release
198
205
  2. Deletes the git tag (remote + local)
199
206
  3. Reverts the version bump commit (if HEAD matches the tag)
200
- 4. Pushes the revert commit (with confirmation, or automatic with `--yes`)
207
+ 4. Pushes the revert commit (the single confirmation covers the whole rollback)
201
208
 
202
209
  On partial failure, prints a structured summary table with remediation commands for each failed step.
203
210
 
@@ -207,19 +214,14 @@ The `.git/hooks/pre-push` hook captures push refs from git and runs `rlsbl check
207
214
 
208
215
  1. **Changelog coverage** -- every pushed commit must have a JSONL entry
209
216
  2. **Gitignore guard** -- rlsbl-managed files must not be gitignored
210
- 3. **Manual push warning** -- warns when pushing to a release branch outside `rlsbl release`
217
+ 3. **Manual push guard** -- hard error when pushing to a release branch outside `rlsbl release`
211
218
  4. **Test suite** -- runs project tests (single-project) or affected project tests (monorepo)
212
219
 
213
- Old hooks that call `rlsbl pre-push-check` still work but show a deprecation warning. Run `rlsbl scaffold` to update to the current hook format.
220
+ The hook is namespace-aware: it enforces on `refs/heads/*` and exits 0 for `refs/tags/*` (release tags, pushed by rlsbl itself) and `refs/backups/*` (tool-owned backup slots). Release-internal pushes run `git push --no-verify` and never invoke the hook, so there is no environment-variable bypass to leak.
214
221
 
215
- To reinstall manually:
222
+ Old hooks that call `rlsbl pre-push-check` no longer work: the command was removed and now exits non-zero with an error, which blocks the push. Run `rlsbl scaffold` to install the current hook.
216
223
 
217
- ```
218
- echo '#!/usr/bin/env bash' > .git/hooks/pre-push
219
- echo 'export RLSBL_PUSH_STDIN="$(cat)"' >> .git/hooks/pre-push
220
- echo 'exec rlsbl check --tag prepush' >> .git/hooks/pre-push
221
- chmod +x .git/hooks/pre-push
222
- ```
224
+ To reinstall, run `rlsbl scaffold` -- it writes the current hook (and upgrades any previously shipped version in place).
223
225
 
224
226
  ## Ecosystem tagging
225
227
 
@@ -250,7 +252,6 @@ Supports architectural layer rules via `[layers]` in `workspace.toml` for enforc
250
252
 
251
253
  | Variable | Default | Description |
252
254
  |----------|---------|-------------|
253
- | `RLSBL_PUSH_TIMEOUT` | `120` | Timeout in seconds for `git push` operations |
254
255
  | `RLSBL_VERSION` | -- | Set when running pre-release and post-release hooks; contains the version being released |
255
256
  | `RLSBL_DIST_DIR` | -- | Set when running `custom_assets` build commands; points to the distribution directory for output files |
256
257
  | `GITHUB_TOKEN` | -- | Used by `gh` CLI for GitHub API calls; `discover` works unauthenticated for public repos |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rlsbl",
3
- "version": "0.110.2",
3
+ "version": "0.111.0",
4
4
  "description": "Release orchestration and project scaffolding across package ecosystems",
5
5
  "license": "MIT",
6
6
  "bin": {