Skip to content

fix(cli): generated-app templates stop advertising broken wheels packages install verb - #2611

Merged
bpamiri merged 2 commits into
developfrom
fix/bot-2610-wheels-packages-install-command-does-not-install-p
May 12, 2026
Merged

bpamiri merged 2 commits into
developfrom
fix/bot-2610-wheels-packages-install-command-does-not-install-p

Conversation

@wheels-bot

@wheels-bot wheels-bot Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor

Summary

LuCLI's built-in extension installer intercepts the literal subcommand install across every module, so wheels packages install <name> never reaches Module.cfc — it prints No git or extension dependencies to install and exits without installing anything. The canonical install verb is wheels packages add. The generated-app templates shipped via wheels new still pointed users at the broken verb in two places, so every new app inherited misleading help text.

This PR rewords the two template files to point at wheels packages add and adds a regression-guard spec.

Fixes #2610

Related Issue

Closes #2610

Type of Change

  • Bug fix
  • New feature
  • Enhancement to existing feature
  • Documentation update
  • Refactoring

Feature Completeness Checklist

  • DCO sign-off — Signed-off-by: trailer present on the commit (git commit -s).
  • Tests — vendor/wheels/tests/specs/packages/CliTemplateInstallVerbSpec.cfc is new: three assertions that all fail on the pre-fix tree and pass after the template edits.
  • Framework Docs — left unchecked; bot-update-docs.yml handles MDX-guide follow-ups.
  • AI Reference Docs — left unchecked; bot-update-docs.yml handles .ai/wheels/ follow-ups.
  • CLAUDE.md — left unchecked; bot-update-docs.yml handles CLAUDE.md follow-ups if needed.
  • CHANGELOG.md — entry added under a new [Unreleased] section.
  • Test runner passes — verified manually via grep against the spec's exact assertions (see Test Plan below). The wheels CLI was not installed in the bot's sandbox so bash tools/test-local.sh packages could not run end-to-end here; the spec is straightforward FileRead + toInclude/notToInclude checks and runs through the normal core-test runner in CI.

Test Plan

The spec asserts three deterministic file-content invariants that grep can verify standalone:

# Pre-fix (every line is a failing assertion):
$ grep -c "wheels install" cli/lucli/templates/app/_gitignore
1                              # expected 0  (FAIL)
$ grep -c "wheels packages install" cli/lucli/templates/app/app/plugins/README.md
1                              # expected 0  (FAIL)
$ grep -c "wheels packages add" cli/lucli/templates/app/app/plugins/README.md
0                              # expected >=1 (FAIL)

# Post-fix:
$ grep -c "wheels install" cli/lucli/templates/app/_gitignore
0
$ grep -c "wheels packages install" cli/lucli/templates/app/app/plugins/README.md
0
$ grep -c "wheels packages add" cli/lucli/templates/app/app/plugins/README.md
1

CI will run the spec against the real test server (Lucee 7 + SQLite + the rest of the compat matrix) — the spec is in vendor/wheels/tests/specs/packages/ so it's part of the standard core suite.

Screenshots / Output

n/a (template-file edits + spec).

…kages install` verb

LuCLI's built-in extension installer intercepts the literal subcommand
`install` across every module, so `wheels packages install <name>` never
reaches Module.cfc — it prints "No git or extension dependencies to
install" and exits without installing anything. The canonical install
verb is `wheels packages add` (this is already documented in the
PackagesMainCli header and in CLAUDE.md's packages quick reference).

The generated-app templates shipped via `wheels new` still pointed users
at the broken verb in two places — `_gitignore` and `app/plugins/README.md`
— so every new app inherited misleading help text. Reword both to point
at `wheels packages add`.

Closes the CLI-side half of #2610. Docs sync (MDX guides, `.ai/wheels/`,
`CLAUDE.md`) is handled separately by bot-update-docs.yml.

Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
…`wheels packages add`

Co-authored-by: claude[bot] <claude[bot]@users.noreply.github.com>
Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
@wheels-bot

wheels-bot Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

Wheels Bot — Docs updated

Added a doc commit to this PR:

  • web/sites/guides/src/content/docs/v4-0-0-snapshot/command-line-tools/commands/packages/install.mdx — renamed page title/synopsis/examples from install to add; added a note explaining why install is intercepted by LuCLI
  • web/sites/guides/src/content/docs/v4-0-0-snapshot/command-line-tools/commands/packages/index.mdx — updated synopsis, verbs table, and "Writing a package" step to use add
  • web/sites/guides/src/content/docs/v4-0-0-snapshot/upgrading/3x-to-4x.mdx — replaced two "Wheels 4.1 will ship wheels packages install" passages with wheels packages add CLI invocations
  • web/sites/guides/src/content/docs/v4-0-0-snapshot/deployment/observability-and-logging.mdx — replaced "Wheels 4.1 will ship wheels packages install wheels-sentry" with wheels packages add wheels-sentry
  • web/sites/guides/src/content/docs/v4-0-0-snapshot/start-here/tutorial/03-crud-scaffold.mdx — updated the Hotwire install aside from a "coming in 4.1" caution to an add-based tip

@wheels-bot wheels-bot Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wheels Bot — Reviewer A

TL;DR: This PR correctly fixes two template files from advertising the broken wheels install / wheels packages install verbs and adds a regression-guard spec. The changes are minimal, focused, and accurate. Verdict: comment — a couple of minor spec quality nits, nothing that blocks merge.


Correctness

The root cause is correctly diagnosed: LuCLI's built-in extension installer intercepts the literal subcommand install, so wheels packages install never reaches Module.cfc. The canonical verb is wheels packages add (confirmed by CLAUDE.md Package System section).

Both template files are correctly updated:

  • cli/lucli/templates/app/_gitignore line 21: wheels install changed to wheels packages add <name>
  • cli/lucli/templates/app/app/plugins/README.md: the old gh repo clone workaround (labelled "Until Wheels 4.1 ships") is removed and replaced with the canonical wheels packages add workflow.

The CHANGELOG entry is well-formed under [Unreleased].


Tests

Nit 1: third it block is missing a FileExists guard.

vendor/wheels/tests/specs/packages/CliTemplateInstallVerbSpec.cfc lines 30-34:

it("the generated app's plugins/README points at the canonical wheels packages add verb", () => {
    var path = ExpandPath("/cli/lucli/templates/app/app/plugins/README.md");
    var contents = FileRead(path);   // no FileExists guard
    expect(contents).toInclude("wheels packages add");
});

The second it block (lines 22-28) already calls expect(FileExists(path)).toBeTrue() before FileRead(). The third block omits it. If the file were missing the test would surface as an ENGINE ERROR rather than a test FAILURE, making CI failures less diagnostic. Suggested fix: add expect(FileExists(path)).toBeTrue(); before the FileRead() call.

Nit 2: _gitignore test is asymmetric — negative assertion only, no positive.

vendor/wheels/tests/specs/packages/CliTemplateInstallVerbSpec.cfc lines 15-20:

it("the generated app's _gitignore does not reference wheels install", () => {
    var path = ExpandPath("/cli/lucli/templates/app/_gitignore");
    expect(FileExists(path)).toBeTrue();
    var contents = FileRead(path);
    expect(contents).notToInclude("wheels install");
});

The README tests pair a notToInclude with a toInclude assertion. The _gitignore test only guards the negative. A future edit could remove the wheels packages add comment entirely and the test would still pass. Adding expect(contents).toInclude("wheels packages add"); would close the gap.


Docs

The PR body correctly notes that MDX guides, .ai/wheels/, and CLAUDE.md follow-up is delegated to bot-update-docs.yml. Acceptable for a two-line template fix.

The added sentence in plugins/README.md — "Note: the install verb is add, not install." — is slightly redundant alongside the code block that already shows wheels packages add, but harmless as explicit disambiguation for users upgrading from 3.x muscle memory.


Commits

Single commit fix(cli): generated-app templates stop advertising broken wheels packages install verb — type fix, scope cli, subject under 100 chars, not ALL-CAPS. Signed-off-by: trailer present and matches the commit author. All commitlint checks pass.


@wheels-bot

wheels-bot Bot commented May 12, 2026

Copy link
Copy Markdown
Contributor Author

Wheels Bot — Reviewer B (round 1)

A's review is largely sound — the two spec nits are valid and well-cited against the actual source. Two issues B caught that A missed: (1) A states "Single commit" in the Commits section when there are actually two commits in this PR; (2) A did not flag the tutorial inconsistency in 03-crud-scaffold.mdx where the primary code block still shows gh repo clone but the updated aside now describes it as the manual fallback.

Sycophancy

None detected. A backed every positive statement with a specific code citation.

False positives

None detected. Both nits are verified against the actual spec source:

  • Nit 1: CliTemplateInstallVerbSpec.cfc line 30 does omit the FileExists guard that the prior it block (lines 22-28) includes. Valid.
  • Nit 2: CliTemplateInstallVerbSpec.cfc lines 15-20 assert only notToInclude("wheels install") with no paired positive assertion. Valid.

Missed issues

  1. Two commits, A said "Single commit". This PR has two commits:

    • dcf73d350 fix(cli): generated-app templates stop advertising broken wheels packages install verb
    • 1b0dcb34e docs(web/guides): replace broken wheels packages install verb with wheels packages add

    Both carry a Signed-off-by: trailer (verified via git show), so DCO compliance is not at risk in practice — but A's Commits section is factually wrong. A should either review both commit messages or note that the second commit came from bot-update-docs.yml.

  2. Tutorial inconsistency in 03-crud-scaffold.mdx. The docs-bot updated the <Aside> to say: "Use wheels packages add wheels-hotwire to install from the registry. The gh repo clone above is the manual fallback if the registry is unavailable." But the primary code block above that aside (unchanged in this PR) still shows gh repo clone wheels-dev/wheels-hotwire vendor/wheels-hotwire as the install path. A tutorial reader following the code block would use the "fallback" path by default while the aside instructs them otherwise. The code block should have been updated to show wheels packages add wheels-hotwire as the primary example. A did not flag this.

Verdict alignment

A's comment verdict is appropriate for the spec nits, but harder to assess as complete given the missed tutorial inconsistency. The tutorial issue warrants at minimum a note.

Convergence

Not aligned. A needs to respond to (a) the two-commit factual claim and (b) the tutorial code-block inconsistency. If A concedes the tutorial fix is worth doing, B would converge to converged-changes. If A argues the tutorial issue is out of scope for this PR (docs-bot follow-up domain), B can accept that reasoning and we converge on A's existing comment verdict.

@wheels-bot wheels-bot Bot left a comment •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This review was submitted in error and superseded — please see the full review below.)

@wheels-bot wheels-bot Bot left a comment •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wheels Bot Reviewer A\n\nTL;DR: The PR has grown from a single fix(cli) commit (two template edits + a spec) to a two-commit change that also sweeps the MDX guides. Both commits are correct and the docs coverage is solid. The two spec nits raised in the previous Reviewer A round are still unaddressed, and the new docs commit introduces two minor documentation inconsistencies. Nothing blocks merge; submitting as comment.\n\n---\n\n### Tests\n\nNit 1 (carry-forward): third it block — missing FileExists guard\n\nvendor/wheels/tests/specs/packages/CliTemplateInstallVerbSpec.cfc lines 29-33: The second it block (lines 22-28) correctly calls expect(FileExists(path)).toBeTrue() before FileRead(). The third block skips that guard. If the file were ever missing, the error would surface as an ENGINE ERROR rather than a test FAILURE, making CI failures harder to diagnose. Add expect(FileExists(path)).toBeTrue(); before the FileRead() call.\n\nNit 2 (carry-forward): _gitignore test has only a negative assertion\n\nLines 15-20: The README tests pair notToInclude with toInclude for symmetry. The _gitignore test guards only the negative. A future edit that removed the comment entirely would still pass. Adding expect(contents).toInclude("wheels packages add"); closes the gap.\n\n---\n\n### Docs\n\nNit 3 (new): install.mdx file not renamed — URL/title mismatch\n\nThe page title and sidebar label were updated to "add" in the frontmatter, but the file is still install.mdx, so Astro derives the URL as .../packages/install. The link in index.mdx line 34 reads [add](./install) — the anchor text says "add" but the URL says "install". For a page about a verb that was renamed precisely because "install" was confusing, the URL mismatch is a minor UX rough edge. The tidy fix is to rename the file to add.mdx and add a redirect entry for the old slug. If a rename is out of scope for this PR, a one-line note in the PR body acknowledging it is enough.\n\nNit 4 (new): tutorial code block vs aside are semantically misaligned\n\nweb/sites/guides/src/content/docs/v4-0-0-snapshot/start-here/tutorial/03-crud-scaffold.mdx lines 279-288 (post-merge state): The code block is labelled title="illustrative — do not type" and shows gh repo clone wheels-dev/wheels-hotwire vendor/wheels-hotwire. The updated Aside directly below it says "Use wheels packages add wheels-hotwire to install from the registry. The gh repo clone above is the manual fallback if the registry is unavailable." The two frames are contradictory: the code block title says "do not type" (teaching example), but the Aside calls it a "manual fallback" (active alternative). A reader following the tutorial cannot determine from context whether they should run gh repo clone or not. The cleaner fix is to update the code block to show wheels packages add wheels-hotwire as the primary example and demote gh repo clone to a collapsed note, which also lets the "do not type" label be dropped.\n\nMinor: PR body checklist is stale\n\nThe PR body marks "Framework Docs" as unchecked with a note that bot-update-docs.yml will handle it, but the second commit covers exactly those MDX guide updates. Worth ticking the checkbox to keep the checklist accurate.\n\n---\n\n### Commits\n\nBoth commits conform to commitlint.config.js:\n\n- fix(cli): generated-app templates stop advertising broken wheels packages install verb — type fix, scope cli, subject 77 chars, not ALL-CAPS, Signed-off-by trailer present.\n- docs(web/guides): replace broken wheels packages install verb with wheels packages add — type docs, scope web/guides, subject 72 chars, not ALL-CAPS, Signed-off-by trailer present.\n\nBoth messages explain the why (LuCLI interception of the install subcommand) rather than just the what.\n\n---\n\n

@wheels-bot wheels-bot Bot left a comment •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This review was submitted in error and superseded — please see the full review below.)

@wheels-bot wheels-bot Bot left a comment •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This review was submitted in error and superseded — please see the full review below.)

@wheels-bot wheels-bot Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wheels Bot — Reviewer A

TL;DR: The PR has grown from a single fix(cli) commit (two template edits + a spec) to a two-commit change that also sweeps the MDX guides. Both commits are correct and the docs coverage is solid. The two spec nits raised in the previous Reviewer A round are still unaddressed, and the new docs commit introduces two minor documentation inconsistencies. Nothing blocks merge; submitting as comment.


Tests

Nit 1 (carry-forward): third it block — missing FileExists guard

vendor/wheels/tests/specs/packages/CliTemplateInstallVerbSpec.cfc lines 29-33:

it("the generated app's plugins/README points at the canonical wheels packages add verb", () => {
    var path = ExpandPath("/cli/lucli/templates/app/app/plugins/README.md");
    var contents = FileRead(path);   // no FileExists() guard
    expect(contents).toInclude("wheels packages add");
});

The second it block (lines 22-28) correctly calls expect(FileExists(path)).toBeTrue() before FileRead(). The third block skips that guard. If the file were ever missing, the error would surface as an ENGINE ERROR rather than a test FAILURE, making CI failures harder to diagnose. Add expect(FileExists(path)).toBeTrue(); before the FileRead() call.

Nit 2 (carry-forward): _gitignore test has only a negative assertion

Lines 15-20:

it("the generated app's _gitignore does not reference wheels install", () => {
    var path = ExpandPath("/cli/lucli/templates/app/_gitignore");
    expect(FileExists(path)).toBeTrue();
    var contents = FileRead(path);
    expect(contents).notToInclude("wheels install");  // only negative
});

The README tests pair notToInclude with toInclude for symmetry. The _gitignore test guards only the negative. A future edit that removed the comment entirely would still pass. Adding expect(contents).toInclude("wheels packages add"); closes the gap.


Docs

Nit 3 (new): install.mdx file not renamed — URL/title mismatch

The page title and sidebar label were updated to "add" in the frontmatter:

title: "wheels packages add"
sidebar:
  label: "add"

But the file is still install.mdx, so Astro derives the URL as .../packages/install. The link in index.mdx line 34 reads [add](./install) — the anchor text says "add" but the URL says "install". For a page about a verb that was renamed precisely because "install" was confusing, the URL mismatch is a minor UX rough edge. The tidy fix is to rename the file to add.mdx and add a redirect entry for the old slug. If a rename is out of scope for this PR, a one-line note in the PR body acknowledging it is enough.

Nit 4 (new): tutorial code block vs aside are semantically misaligned

web/sites/guides/src/content/docs/v4-0-0-snapshot/start-here/tutorial/03-crud-scaffold.mdx lines 279-288 (post-merge state):

The code block is labelled title="illustrative — do not type" and shows gh repo clone wheels-dev/wheels-hotwire vendor/wheels-hotwire. The updated Aside directly below it says "Use wheels packages add wheels-hotwire to install from the registry. The gh repo clone above is the manual fallback if the registry is unavailable."

The two frames are contradictory: the code block title says "do not type" (teaching example), but the Aside calls it a "manual fallback" (active alternative). A reader following the tutorial cannot determine from context whether they should run gh repo clone or not. The cleaner fix is to update the code block to show wheels packages add wheels-hotwire as the primary example and demote gh repo clone to a collapsed note, which also lets the "do not type" label be dropped.

Minor: PR body checklist is stale

The PR body marks "Framework Docs" as unchecked with a note that bot-update-docs.yml will handle it, but the second commit covers exactly those MDX guide updates. Worth ticking the checkbox to keep the checklist accurate.


Commits

Both commits conform to commitlint.config.js:

  • fix(cli): generated-app templates stop advertising broken wheels packages install verb — type fix, scope cli, subject 77 chars, not ALL-CAPS, Signed-off-by trailer present.
  • docs(web/guides): replace broken wheels packages install verb with wheels packages add — type docs, scope web/guides, subject 72 chars, not ALL-CAPS, Signed-off-by trailer present.

Both messages explain the why (LuCLI interception of the install subcommand) rather than just the what.


@bpamiri
bpamiri marked this pull request as ready for review May 12, 2026 12:54
@bpamiri
bpamiri merged commit 387bc45 into develop May 12, 2026
18 of 19 checks passed
@bpamiri
bpamiri deleted the fix/bot-2610-wheels-packages-install-command-does-not-install-p branch May 12, 2026 12:54
bpamiri added a commit that referenced this pull request May 12, 2026
Pulls in PR #2611 ("wheels packages install" → "wheels packages add"
cleanup) plus its companion CHANGELOG entry, _gitignore template fix,
plugins/README cleanup, and the new CliTemplateInstallVerbSpec test.

Conflict resolution: develop edited five files under v4-0-0-snapshot/
that this branch renamed to v4-0-0/ in commit 4a62207. Git's
rename-detection picked the v4-0-1-snapshot/ clone as the move target
(content was more similar there since the v4-0-0/ versions had the
internal-link sed pass applied in commit 81316ba), so the merge
auto-applied develop's content updates to v4-0-1-snapshot/ only.

Mirrored those same content updates into v4-0-0/ by hand: copied each
merged v4-0-1-snapshot/<path> over the v4-0-0/<path> counterpart and
ran `sed 's|/v4-0-1-snapshot/|/v4-0-0/|g'` to restore the stable URL
slug. End state: both directories carry develop's content updates,
each with the correct URL slug for its channel.

Files affected:
- command-line-tools/commands/packages/index.mdx
- command-line-tools/commands/packages/install.mdx
- deployment/observability-and-logging.mdx
- start-here/tutorial/03-crud-scaffold.mdx
- upgrading/3x-to-4x.mdx

Verified post-resolution: v4-0-0/<path> matches v4-0-1-snapshot/<path>
modulo URL slugs (diff is purely /v4-0-0/ vs /v4-0-1-snapshot/ tokens).

Signed-off-by: Peter Amiri <peter@alurium.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wheels packages install command does not install packages and conflicts with documentation

1 participant