diff --git a/README.md b/README.md index 6fc2e4c..ac673bd 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,9 @@ proposed improvements to the durable recipe that guides the next run. > **Early release.** The current Go source supports ticket analysis, approved execution, > verification and separately approved draft PRs, also available in the downloadable -> `v0.3.1` release. Merge, deployment and issue closure -> remain manual. GitHub is the only tracker in a release; GitLab, Jira and outside -> reviewers are available in the source on `main` and not yet in a release. +> `v0.4.0` release. Merge, deployment and issue closure +> remain manual. v0.4.0 also ships the plugin runtime with bundled GitLab (forge), Jira +> (tracker) and `forgecomments` (reviewer) plugins; see [plugins](lab/plugins/README.md). ## How it works @@ -66,14 +66,14 @@ No Node, Go or source checkout is required to install it. **[Installation guide →](docs/install.md)** — prerequisites, PATH, upgrades and rollback.
-One-line installer · pinned to v0.3.1 +One-line installer · pinned to v0.4.0 ```sh -sh -c 'set -eu; script=$(mktemp "${TMPDIR:-/tmp}/forgecell-bootstrap.XXXXXXXX") || { echo "Forgecell: cannot create bootstrap temporary file." >&2; exit 1; }; trap '"'"'rm -f "$script"'"'"' 0; trap '"'"'exit 1'"'"' HUP INT TERM; curl -fsSL --proto "=https" --proto-redir "=https" --connect-timeout 15 --max-time 30 https://github.com/DanielNetzer/forgecell/releases/download/v0.3.1/install.sh -o "$script" || { echo "Forgecell: bootstrap download failed." >&2; exit 1; }; [ -s "$script" ] || { echo "Forgecell: bootstrap download was empty." >&2; exit 1; }; sh "$script"' +sh -c 'set -eu; script=$(mktemp "${TMPDIR:-/tmp}/forgecell-bootstrap.XXXXXXXX") || { echo "Forgecell: cannot create bootstrap temporary file." >&2; exit 1; }; trap '"'"'rm -f "$script"'"'"' 0; trap '"'"'exit 1'"'"' HUP INT TERM; curl -fsSL --proto "=https" --proto-redir "=https" --connect-timeout 15 --max-time 30 https://github.com/DanielNetzer/forgecell/releases/download/v0.4.0/install.sh -o "$script" || { echo "Forgecell: bootstrap download failed." >&2; exit 1; }; [ -s "$script" ] || { echo "Forgecell: bootstrap download was empty." >&2; exit 1; }; sh "$script"' ``` The installer verifies the executable checksum and version before activation and -preserves local Lab data. This command pins the published public-core v0.3.1 release. +preserves local Lab data. This command pins the published public-core v0.4.0 release. Checksums share the binaries’ GitHub HTTPS endpoint; they are not independent signatures.
@@ -110,7 +110,7 @@ sample repository with a deterministic stub harness. It needs only Git and Go on no API key, no GitHub token, no network and no repository of your own, and it publishes nothing. -The `v0.3.1` release defaults to a distinct private Lab for each checkout +The `v0.4.0` release defaults to a distinct private Lab for each checkout under `~/.forgecell/labs/`; `forgecell doctor --json` reports the exact location. Existing preview.1 checkout Labs remain intact: use the same `--lab .forgecell` path for every command to keep using one. Labs and saved bindings are not automatically diff --git a/docs/install.md b/docs/install.md index 6a22b45..eefe020 100644 --- a/docs/install.md +++ b/docs/install.md @@ -1,9 +1,9 @@ # Install Forgecell CLI -Public CLI `v0.3.1` release; core source licensed under the [MIT License](../LICENSE). No repository access, Node or Go is needed to install. +Public CLI `v0.4.0` release; core source licensed under the [MIT License](../LICENSE). No repository access, Node or Go is needed to install. ```sh -sh -c 'set -eu; script=$(mktemp "${TMPDIR:-/tmp}/forgecell-bootstrap.XXXXXXXX") || { echo "Forgecell: cannot create bootstrap temporary file." >&2; exit 1; }; trap '"'"'rm -f "$script"'"'"' 0; trap '"'"'exit 1'"'"' HUP INT TERM; curl -fsSL --proto "=https" --proto-redir "=https" --connect-timeout 15 --max-time 30 https://github.com/DanielNetzer/forgecell/releases/download/v0.3.1/install.sh -o "$script" || { echo "Forgecell: bootstrap download failed." >&2; exit 1; }; [ -s "$script" ] || { echo "Forgecell: bootstrap download was empty." >&2; exit 1; }; sh "$script"' +sh -c 'set -eu; script=$(mktemp "${TMPDIR:-/tmp}/forgecell-bootstrap.XXXXXXXX") || { echo "Forgecell: cannot create bootstrap temporary file." >&2; exit 1; }; trap '"'"'rm -f "$script"'"'"' 0; trap '"'"'exit 1'"'"' HUP INT TERM; curl -fsSL --proto "=https" --proto-redir "=https" --connect-timeout 15 --max-time 30 https://github.com/DanielNetzer/forgecell/releases/download/v0.4.0/install.sh -o "$script" || { echo "Forgecell: bootstrap download failed." >&2; exit 1; }; [ -s "$script" ] || { echo "Forgecell: bootstrap download was empty." >&2; exit 1; }; sh "$script"' ``` The command downloads the bootstrap over HTTPS before executing it. A failed download @@ -23,8 +23,8 @@ The four words you will see everywhere: You need Git, the GitHub CLI signed in (`gh auth login`), and one coding agent signed in with its own CLI: Claude Code, Codex or Cursor. Forgecell never asks for those -credentials. GitLab and Jira are available in the source on `main` and not yet in a -release. +credentials. GitLab and Jira ship in the v0.4.0 release as bundled +[plugins](../lab/plugins/README.md). 1. **Install.** Run the command above. Make sure `~/.local/bin` is on your PATH; the installer does not edit shell profiles. @@ -90,8 +90,8 @@ finished ledgers still uses `forgecell learn` and `forgecell suggestion`. ### Outside reviewers and fix rounds -Outside reviewers (review bots and other reviewer plugins) are available in the source on -`main`, not yet in a release. Declare them in the Formula under `reviewers:`, each with +Outside reviewers (review bots and other reviewer plugins) ship in the v0.4.0 release. +Declare them in the Formula under `reviewers:`, each with its plugin and the `autoFix` level that decides which findings a fix round takes on its own, and pin the plugin under `plugins:` (see the [review bot comments plugin](../lab/plugins/forgecomments/README.md) for an example): @@ -171,7 +171,7 @@ a Molecule's delivery and exits nonzero unless they passed. and authentication checks; it does not prove model access or repository policy readiness. `forgecell --help` lists every command and flag. -The `v0.3.1` release uses a distinct directory under `~/.forgecell/labs/` +The `v0.4.0` release uses a distinct directory under `~/.forgecell/labs/` for each checkout by default; `forgecell doctor --json` reports the exact location. Existing preview.1 checkout Labs in the ignored `.forgecell` directory are left intact. Use the same `--lab .forgecell` path for every command to continue using one; @@ -181,7 +181,7 @@ path such as the example above keeps records outside the checkout. ## Versions, upgrade and rollback -The command above pins `v0.3.1`. v0.3.1 is the first release that drives the whole loop from `forgecell ui`. Repeating it safely reinstalls that version. For another GitHub release, use its matching versioned installer; `FORGECELL_VERSION` overrides require the generic `FORGECELL_RELEASE_BASE` layout. Review release notes before upgrading. +The command above pins `v0.4.0`. v0.4.0 adds plugins: other trackers, forges and reviewers through pinned MCP plugins, and the `plugin new`/`pin`/`test` contributor kit. Repeating it safely reinstalls that version. For another GitHub release, use its matching versioned installer; `FORGECELL_VERSION` overrides require the generic `FORGECELL_RELEASE_BASE` layout. Review release notes before upgrading. `forgecell rollback` restores the previous verified installation when one exists. Installation preserves Formulas and ledgers, stores versioned executables under `~/.forgecell/releases`, and refuses conflicting unmanaged launchers. @@ -255,7 +255,7 @@ Native maintainers use [the distribution design](design/native-cli-distribution. ## Published public-core release and legacy provenance -The pinned installer uses `DanielNetzer/forgecell` and the `v0.3.1` tag. +The pinned installer uses `DanielNetzer/forgecell` and the `v0.4.0` tag. The earlier published [v0.2.0-preview.2 prerelease](https://github.com/DanielNetzer/forgecell/releases/tag/v0.2.0-preview.2) was built from public-core source `801a9846fc9066dde985bb678348cac2bc89a249`. Installation requires no GitHub token, Git, gh, Go or Node. diff --git a/lab/internal/ui/molecule_findings_ui_test.go b/lab/internal/ui/molecule_findings_ui_test.go index d48dd87..bd3f5e2 100644 --- a/lab/internal/ui/molecule_findings_ui_test.go +++ b/lab/internal/ui/molecule_findings_ui_test.go @@ -263,7 +263,7 @@ func moleculeFindingsDocText(raw string) string { return strings.ToLower(strings.Join(strings.Fields(strings.Join(lines, " ")), " ")) } -var moleculeFindingsGoneDocPhrases = []string{"outside reviewers are not supported yet", "outside reviewers are post-v1", "gitlab and jira are not supported yet", "(post-v1, #259)"} +var moleculeFindingsGoneDocPhrases = []string{"outside reviewers are not supported yet", "outside reviewers are post-v1", "gitlab and jira are not supported yet", "(post-v1, #259)", "not yet in a release"} // The docs no longer say outside reviewers are unsupported: install.md has // the subsection, the plugin README links it, and the design doc records the @@ -293,8 +293,11 @@ func TestMoleculeFindingsDocs(t *testing.T) { } } install := docs["docs/install.md"] - if !strings.Contains(moleculeFindingsDocText(install), "gitlab and jira are available in the source on `main` and not yet in a release") { - t.Error("docs/install.md does not say GitLab and Jira are on main and not yet released") + if !strings.Contains(moleculeFindingsDocText(install), "gitlab and jira ship in the v0.4.0 release") { + t.Error("docs/install.md does not say GitLab and Jira ship in v0.4.0") + } + if !strings.Contains(moleculeFindingsDocText(install), "outside reviewers (review bots and other reviewer plugins) ship in the v0.4.0 release") { + t.Error("docs/install.md does not say outside reviewers ship in v0.4.0") } for _, want := range []string{"### Outside reviewers and fix rounds", "reviewers:", "--collect", "--propose", "--dismiss", "--push", "Findings", "at most 3 fix rounds", "GitHub Labs can't serve"} { if !strings.Contains(install, want) { @@ -304,8 +307,8 @@ func TestMoleculeFindingsDocs(t *testing.T) { if !strings.Contains(docs["lab/plugins/forgecomments/README.md"], "docs/install.md#outside-reviewers-and-fix-rounds") { t.Error("the forgecomments README does not link the install subsection") } - if !strings.Contains(moleculeFindingsDocText(docs["README.md"]), "outside reviewers are available in the source on `main` and not yet in a release") { - t.Error("README.md does not say outside reviewers are on main and not yet released") + if !strings.Contains(moleculeFindingsDocText(docs["README.md"]), "v0.4.0 also ships the plugin runtime with bundled gitlab (forge), jira (tracker) and `forgecomments` (reviewer) plugins") { + t.Error("README.md does not say v0.4.0 ships the GitLab, Jira and forgecomments plugins") } if !strings.Contains(read("docs/design/2026-10-30-plugins-design.md"), "\nSlices 1-6 implemented on main (2026-11-03); the contributor guide is `lab/plugins/README.md`.\n") { t.Error("the plugins design doc lacks the slice status line") diff --git a/lab/plugins/README.md b/lab/plugins/README.md index 44e46a3..1490fcf 100644 --- a/lab/plugins/README.md +++ b/lab/plugins/README.md @@ -5,7 +5,7 @@ server on stdio that serves one of three contracts. You pin it by digest, and a enables it. Forgecell starts it, calls its tools and stops it. A plugin never drives Forgecell. -Plugins are available in the source on `main`, not yet in a release. +Plugins ship in the v0.4.0 release. | Kind | Contract | What it does | |---|---|---| diff --git a/scripts/test-native-installer.py b/scripts/test-native-installer.py index b308429..427d64d 100755 --- a/scripts/test-native-installer.py +++ b/scripts/test-native-installer.py @@ -37,7 +37,7 @@ assert binary.with_name(binary.name + '.sha256').read_text().strip() == hashlib.sha256(binary.read_bytes()).hexdigest() assert (release_root / 'install.sh').read_bytes() == (release_root / versions[-1] / 'install.sh').read_bytes() print('PASS: all four packages, license, notices and rendered version/tag pins') -public_url = 'https://github.com/DanielNetzer/forgecell/releases/download/v0.3.1/install.sh' +public_url = 'https://github.com/DanielNetzer/forgecell/releases/download/v0.4.0/install.sh' def documented_command(path): commands = [block.strip() for block in re.findall(r'```sh\n(.*?)\n```', path.read_text(), re.S) if public_url in block] assert len(commands) == 1, f'{path}: expected one public install command'