diff --git a/changelog.d/3184-wheels-cli-forgebox-deprecation-metadata.changed.md b/changelog.d/3184-wheels-cli-forgebox-deprecation-metadata.changed.md
new file mode 100644
index 0000000000..20e766759f
--- /dev/null
+++ b/changelog.d/3184-wheels-cli-forgebox-deprecation-metadata.changed.md
@@ -0,0 +1 @@
+- The published `wheels-cli` ForgeBox registry metadata (`box.json` short description/description/instructions/name and `README.md`) now leads with the deprecation notice and points to the supported standalone `wheels` CLI (`brew install wheels-dev/wheels/wheels`), so ForgeBox browsers see the deprecation before running `box install wheels-cli` (#3184)
diff --git a/tools/build/cli/README.md b/tools/build/cli/README.md
index c3b19a5fb1..c8e026ede8 100644
--- a/tools/build/cli/README.md
+++ b/tools/build/cli/README.md
@@ -1,52 +1,47 @@
-# Wheels CLI
-
-The official Command Line Interface for the wheels framework.
-
-## Installation
-
-Install the Wheels CLI module via CommandBox:
+# Wheels CLI Commands (DEPRECATED)
+
+> **DEPRECATED — do not use for new projects.** This legacy CommandBox
+> `wheels-cli` module does not support Wheels 4.0+ and is scheduled for removal
+> in v5.0 (issues [#2227](https://github.com/wheels-dev/wheels/issues/2227),
+> [#2634](https://github.com/wheels-dev/wheels/issues/2634)). Install the
+> supported Wheels CLI instead:
+>
+> ```bash
+> brew install wheels-dev/wheels/wheels
+> ```
+>
+> Other platforms (scoop / apt / yum) and full instructions:
+>
+
+This package is still published to ForgeBox **only** so existing automation
+that runs `box install wheels-cli` keeps working. It receives no new features,
+is not maintained for Wheels 4.0+, and will be removed in v5.0.
+
+## Supported CLI
+
+The supported command-line tool is the standalone `wheels` binary (built on the
+LuCLI runtime). Install it once and it manages every Wheels project:
```bash
-box install wheels-cli
+brew install wheels-dev/wheels/wheels
```
-## Features
-
-- **Code Generation** - Generate applications, controllers, models, views, and complete scaffolds
-- **Database Migrations** - Version control your database schema with migrations
-- **Testing** - Run tests with coverage reports and debugging capabilities
-- **Development Tools** - File watching, reloading, and environment management
-- **Deployment** - Docker integration and CI/CD configuration
-
-## Quick Start
-
-Create a new Wheels application:
-
-```bash
-wheels new myapp
-```
+Installation for scoop, apt, and yum is documented in the install guide:
+
-Generate a complete resource:
+Migrating off this legacy module is covered in the 3.x → 4.x upgrade guide:
+
-```bash
-wheels scaffold Product name:string price:decimal description:text
-```
+## Legacy installation (existing automation only)
-Run database migrations:
+If you have existing automation pinned to this module, it continues to install
+via CommandBox:
```bash
-wheels dbmigrate latest
+box install wheels-cli
```
-## Documentation
-
-Full documentation is available at:
-https://wheels.dev/3.1.0/guides/command-line-tools/commands/README
-
-## Requirements
-
-- CommandBox 5.0+
-- wheels 3.0+
+Do not adopt this for new projects — use the supported `wheels` binary above.
## License
diff --git a/tools/build/cli/box.json b/tools/build/cli/box.json
index d804a5794d..5fa4eb2aff 100644
--- a/tools/build/cli/box.json
+++ b/tools/build/cli/box.json
@@ -1,5 +1,5 @@
{
- "name":"Wheels CLI Commands",
+ "name":"Wheels CLI Commands (DEPRECATED)",
"version":"@build.version@",
"author":"Tom King, Peter Amiri",
"location":"forgeboxStorage",
@@ -7,18 +7,18 @@
"createPackageDirectory":true,
"packageDirectory":"wheels-cli",
"homepage":"https://wheels.dev/",
- "documentation":"https://wheels.dev/3.1.0/guides/command-line-tools/commands/README",
+ "documentation":"https://guides.wheels.dev/v4-0-0/command-line-tools/installation/",
"repository":{
"type":"GIT",
"URL":"https://github.com/wheels-dev/wheels"
},
"bugs":"https://github.com/wheels-dev/wheels/issues",
"slug":"wheels-cli",
- "shortDescription":"Wheels.dev CLI Commands",
- "description":"Command Line Interface for Wheels framework providing code generation, database migrations, testing, and development tools",
- "instructions":"Install via CommandBox by typing 'box install wheels-cli'",
+ "shortDescription":"DEPRECATED — legacy CommandBox CLI. Use the supported Wheels CLI: brew install wheels-dev/wheels/wheels",
+ "description":"DEPRECATED and unmaintained. This legacy CommandBox module does not support Wheels 4.0+ and is scheduled for removal in v5.0 (see issues 2227 and 2634). The supported CLI is the standalone `wheels` binary — install it with `brew install wheels-dev/wheels/wheels` (scoop / apt / yum also available); full instructions: https://guides.wheels.dev/v4-0-0/command-line-tools/installation/ . This package is still published to ForgeBox only so existing automation that runs `box install wheels-cli` keeps working — do not install it for new projects.",
+ "instructions":"DEPRECATED — do NOT install for new projects. The supported Wheels CLI is the standalone `wheels` binary: brew install wheels-dev/wheels/wheels . Install guide: https://guides.wheels.dev/v4-0-0/command-line-tools/installation/",
"changelog":"",
"type":"commandbox-modules",
- "keywords":"wheels.dev,wheels,cli,commands",
+ "keywords":"wheels.dev,wheels,cli,commands,deprecated",
"private":false
}
diff --git a/vendor/wheels/tests/specs/cli/ForgeBoxCliDeprecationMetadataSpec.cfc b/vendor/wheels/tests/specs/cli/ForgeBoxCliDeprecationMetadataSpec.cfc
new file mode 100644
index 0000000000..7c4155971a
--- /dev/null
+++ b/vendor/wheels/tests/specs/cli/ForgeBoxCliDeprecationMetadataSpec.cfc
@@ -0,0 +1,139 @@
+/**
+ * Regression / posture guard for issue #3184.
+ *
+ * The legacy CommandBox `wheels-cli` module (cli/src/) is published to
+ * ForgeBox on every stable release via tools/build/scripts/prepare-cli.sh.
+ * The registry-visible metadata shipped with that artifact —
+ * tools/build/cli/box.json (shortDescription / description / instructions /
+ * name) and tools/build/cli/README.md — read as the *supported* CLI ("The
+ * official Command Line Interface for the wheels framework", "Install via
+ * CommandBox by typing 'box install wheels-cli'"), even though the module is
+ * deprecated in favour of the LuCLI `wheels` binary and slated for removal in
+ * v5.0 (#2227, #2634). The in-CLI deprecation banners fire on only two
+ * sub-commands; a ForgeBox browser sees no deprecation signal before running
+ * `box install wheels-cli`.
+ *
+ * Cross-framework research (issue comment wheels-bot:research:3184) found the
+ * near-unanimous pattern: deprecate in place with a soft, non-breaking,
+ * registry-page-visible signal that names the successor — never unpublish.
+ * ForgeBox has no first-class soft-deprecate flag, so the only pre-install
+ * lever is the box.json description/instructions text + README (the issue's
+ * Option 1). This spec pins that posture so the registry metadata cannot
+ * drift back to implying parity with the supported binary.
+ *
+ * Structural assertion against the metadata source — invoking the release
+ * pipeline from a test would require a writable build context and release
+ * inputs. Reading the committed template files mirrors the guard pattern used
+ * by buildArtifactLicenseSpec.cfc, buildInfoSpec.cfc, and
+ * LegacyUpgradeDeprecationSpec.cfc.
+ *
+ * The pipeline version-freeze half of the issue (decouple the CLI version
+ * from @build.version@ in prepare-cli.sh) is a maintainer strategy call and
+ * is intentionally NOT asserted here — see the PR body.
+ */
+component extends="wheels.WheelsTest" {
+
+ function run() {
+
+ // Shared context for nested it() closures (Adobe CF closures cannot
+ // reliably read plain outer `var` locals — see CLAUDE.md). expandPath
+ // ("/wheels") resolves to vendor/wheels; the repo root is two levels up.
+ var ctx = {
+ repoRoot: expandPath("/wheels/../.."),
+ boxPath: expandPath("/wheels/../..") & "/tools/build/cli/box.json",
+ readmePath: expandPath("/wheels/../..") & "/tools/build/cli/README.md",
+ // Canonical successor pointers — must match the existing in-CLI
+ // banner in cli/src/commands/wheels/upgrade.cfc so README + box.json
+ // + banners all agree.
+ brewPointer: "brew install wheels-dev/wheels/wheels",
+ installGuide: "guides.wheels.dev/v4-0-0/command-line-tools/installation"
+ };
+
+ describe("tools/build/cli/box.json — ForgeBox registry metadata (issue ##3184)", () => {
+
+ it("the box.json template exists", () => {
+ expect(fileExists(ctx.boxPath)).toBeTrue("Missing file: " & ctx.boxPath);
+ });
+
+ it("leads the registry display name with the deprecation", () => {
+ var meta = deserializeJSON(fileRead(ctx.boxPath));
+ expect(findNoCase("DEPRECATED", meta.name) > 0).toBeTrue(
+ "box.json `name` should signal the module is deprecated so the ForgeBox listing title is unambiguous."
+ );
+ });
+
+ it("leads shortDescription with DEPRECATED and points at the supported CLI", () => {
+ var meta = deserializeJSON(fileRead(ctx.boxPath));
+ expect(reFindNoCase("^\s*DEPRECATED", meta.shortDescription) > 0).toBeTrue(
+ "box.json `shortDescription` is the primary pre-install summary on the ForgeBox page — it must lead with DEPRECATED."
+ );
+ expect(findNoCase(ctx.brewPointer, meta.shortDescription) > 0).toBeTrue(
+ "box.json `shortDescription` should name the supported CLI install (`" & ctx.brewPointer & "`)."
+ );
+ });
+
+ it("describes the deprecation, the v5.0 removal, and the successor", () => {
+ var meta = deserializeJSON(fileRead(ctx.boxPath));
+ expect(findNoCase("DEPRECATED", meta.description) > 0).toBeTrue(
+ "box.json `description` must lead with the deprecation, not read as the supported CLI."
+ );
+ expect(findNoCase("5.0", meta.description) > 0).toBeTrue(
+ "box.json `description` should state the module is scheduled for removal in v5.0."
+ );
+ expect(findNoCase(ctx.brewPointer, meta.description) > 0).toBeTrue(
+ "box.json `description` should point at the supported `wheels` binary (`" & ctx.brewPointer & "`)."
+ );
+ expect(findNoCase(ctx.installGuide, meta.description) > 0).toBeTrue(
+ "box.json `description` should link the canonical v4 CLI install guide."
+ );
+ // The pre-fix copy framed it as the supported CLI; that framing
+ // must be gone.
+ expect(findNoCase("providing code generation, database migrations, testing, and development tools", meta.description) == 0).toBeTrue(
+ "box.json `description` still reads as the supported CLI — replace the feature-parity blurb with the deprecation notice."
+ );
+ });
+
+ it("leads instructions with DEPRECATED rather than an install command", () => {
+ var meta = deserializeJSON(fileRead(ctx.boxPath));
+ expect(reFindNoCase("^\s*DEPRECATED", meta.instructions) > 0).toBeTrue(
+ "box.json `instructions` must lead with DEPRECATED, not `Install via CommandBox by typing 'box install wheels-cli'`."
+ );
+ });
+
+ });
+
+ describe("tools/build/cli/README.md — ForgeBox README (issue ##3184)", () => {
+
+ it("the README template exists", () => {
+ expect(fileExists(ctx.readmePath)).toBeTrue("Missing file: " & ctx.readmePath);
+ });
+
+ it("opens with a deprecation banner blockquote", () => {
+ var content = fileRead(ctx.readmePath);
+ expect(reFindNoCase("(?m)^>\s*\*\*DEPRECATED", content) > 0).toBeTrue(
+ "README.md should open with a markdown blockquote deprecation banner (`> **DEPRECATED ...**`) so ForgeBox renders it above the fold."
+ );
+ });
+
+ it("no longer advertises itself as the official CLI", () => {
+ var content = fileRead(ctx.readmePath);
+ expect(findNoCase("The official Command Line Interface for the wheels framework", content) == 0).toBeTrue(
+ "README.md still calls the legacy module the official CLI — remove that framing."
+ );
+ });
+
+ it("points readers at the supported Wheels CLI", () => {
+ var content = fileRead(ctx.readmePath);
+ expect(findNoCase(ctx.brewPointer, content) > 0).toBeTrue(
+ "README.md should point readers at the supported CLI install (`" & ctx.brewPointer & "`)."
+ );
+ expect(findNoCase(ctx.installGuide, content) > 0).toBeTrue(
+ "README.md should link the canonical v4 CLI install guide."
+ );
+ });
+
+ });
+
+ }
+
+}