Skip to content

fix(cli): resolve option inheritance bug in launch help options#2396

Open
abn wants to merge 2 commits into
lemonade-sdk:mainfrom
abn:fix/launch-help-options
Open

fix(cli): resolve option inheritance bug in launch help options#2396
abn wants to merge 2 commits into
lemonade-sdk:mainfrom
abn:fix/launch-help-options

Conversation

@abn

@abn abn commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Replace index-based option hiding with a version-agnostic name filter that hides all options on the launch subcommand except help flags. This prevents CLI11 version discrepancies (2.4.2 vs 2.6.2) from causing option index shifts that corrupted option groups and help outputs.

Motivation for me was because cli tests were failing when I was using system libs, so every time the tests would fail on local.

Below are the before-and-after snapshots of the CLI help output behavior.

🛑 Before (Index-shifting / Option Leakage Bug)

Due to option index shifting under different CLI11 versions, options defined on the launch subcommand (like --model, --directory, etc.) leaked into the root help output. This bloated the root command output and caused CI/CD consistency test assertions to fail:

$ lemonade launch --help
Launch an agent with a model

Usage: lemonade launch [OPTIONS] [SUBCOMMAND]

OPTIONS:
  -h, --help                  Display help information
      --help-all              Display help information for all subcommands
  -m, --model MODEL           Model name to load
      --directory DIR         Remote recipe directory used only if you choose recipe import at prompt
      --recipe-file FILE      Remote recipe JSON filename used only if you choose recipe import at prompt
      --agent-args ARGS       Custom arguments to pass directly to the launched agent process

Agents:
  claude                      Launch claude with a model
  codex                       Launch codex with a model
  opencode                    Launch opencode with a model
  pi                          Launch pi with a model

✅ After (Version-Agnostic Name Filtering Fix)

With the new version-agnostic name filtering, all option leakage on the parent subcommand is completely avoided.

1. Root launch Help Output (Options properly hidden)

$ lemonade launch --help
Launch an agent with a model

Usage: lemonade launch [OPTIONS] [SUBCOMMAND]

OPTIONS:
  -h, --help                  Display help information
      --help-all              Display help information for all subcommands

Agents:
  claude                      Launch claude with a model
  codex                       Launch codex with a model
  opencode                    Launch opencode with a model
  pi                          Launch pi with a model

2. Agent Subcommand Help Output (Options correctly preserved on subcommands)

When checking help for a specific agent subcommand, the options are fully visible and accessible:

$ lemonade launch claude --help
Launch claude with a model

Usage: lemonade launch claude [OPTIONS]

OPTIONS:
  -h, --help                  Display help information
      --help-all              Display help information for all subcommands
  -m, --model MODEL           Model name to load
      --directory DIR         Remote recipe directory used only if you choose recipe import at prompt
      --recipe-file FILE      Remote recipe JSON filename used only if you choose recipe import at prompt
      --agent-args ARGS       Custom arguments to pass directly to the launched agent process

Replace index-based option hiding with a version-agnostic name
filter that hides all options on the launch subcommand except help
flags. This prevents CLI11 version discrepancies (2.4.2 vs 2.6.2)
from causing option index shifts that corrupted option groups and
help outputs.
@jeremyfowers

Copy link
Copy Markdown
Member

Please add before-and-after screenshots to the PR description so that we can understand what the PR does.

@jeremyfowers jeremyfowers requested a review from sawansri June 23, 2026 20:28
@abn

abn commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

@jeremyfowers done 😄

@github-actions github-actions Bot added area::cli lemonade CLI client (src/cpp/cli) bug Something isn't working labels Jun 23, 2026
@sawansri

sawansri commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

I can't reproduce this off of main, are you running a tagged release?

image

@abn

abn commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

The issue is triggered by a CLI11 version discrepancy.

  • By default, building off main uses CLI11 v2.4.2 (via CMake's FetchContent fallback), which does not exhibit this bug.
  • However, if the build system has a newer version of CLI11 installed globally (e.g., CLI11 v2.6.2 on Fedora/Arch/macOS), CMake autodetects and builds against it. The option inheritance behavior and internal option index ordering changed in CLI11 2.5+, shifting the indices used by hide_new_options and causing the bug.

To reproduce the bug on main without needing to install a system-wide package, force CMake to download and build against a newer version of CLI11:

1. Force CLI11 v2.6.2 in CMakeLists.txt

Temporarily update the pinned CLI11 version tag in CMakeLists.txt (around line 216) to pull v2.6.2:

     FetchContent_Declare(CLI11
         GIT_REPOSITORY https://github.com/CLIUtils/CLI11.git
-        GIT_TAG v${MIN_CLI11_VERSION}
+        GIT_TAG v2.6.2
     )

2. Rebuild and Check Help Output

Run a clean configure and build, then inspect the launch help command:

# Clear CMake cache and rebuild
rm -rf build/
cmake -B build --preset default
cmake --build --preset default

# Run launch help
./build/lemonade launch --help

Observed Behavior (Bug): Options like --model, --directory, --recipe-file, and --agent-args will leak into the root launch help output instead of being hidden.


Here is a self contained reproducer (you can replace podman with docker if required). This will take a minute because well no cache. 😄

podman run --rm -i --entrypoint bash docker.io/ubuntu:22.04 <<'EOF'
set -xe

apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y \
    git \
    cmake \
    ninja-build \
    g++ \
    libcurl4-openssl-dev \
    libssl-dev \
    zlib1g-dev \
    libcap-dev \
    pkg-config

git clone https://github.com/lemonade-sdk/lemonade.git /workspace
cd /workspace

# Force FetchContent to pull CLI11 v2.6.2 (disabling system autodetection)
sed -i 's/find_path(CLI11_INCLUDE_DIRS "CLI\/CLI.hpp")/set(CLI11_INCLUDE_DIRS "")/' CMakeLists.txt
sed -i 's/GIT_TAG v${MIN_CLI11_VERSION}/GIT_TAG v2.6.2/' CMakeLists.txt

# Configure and compile only the CLI client target
cmake -B build -GNinja -DBUILD_WEB_APP=OFF .
cmake --build build --target lemonade

# 5. Run the help command to demonstrate the option leakage bug
echo "=== DEMONSTRATING THE BUG (Leaked Options) ==="
./build/lemonade launch --help
EOF

@sawansri

Copy link
Copy Markdown
Collaborator

The issue is triggered by a CLI11 version discrepancy.

* By default, building off `main` uses **CLI11 v2.4.2** (via CMake's `FetchContent` fallback), which does not exhibit this bug.

* However, if the build system has a newer version of CLI11 installed globally (e.g., **CLI11 v2.6.2** on Fedora/Arch/macOS), CMake autodetects and builds against it. The option inheritance behavior and internal option index ordering changed in CLI11 2.5+, shifting the indices used by `hide_new_options` and causing the bug.

To reproduce the bug on main without needing to install a system-wide package, force CMake to download and build against a newer version of CLI11:

1. Force CLI11 v2.6.2 in CMakeLists.txt

Temporarily update the pinned CLI11 version tag in CMakeLists.txt (around line 216) to pull v2.6.2:

     FetchContent_Declare(CLI11
         GIT_REPOSITORY https://github.com/CLIUtils/CLI11.git
-        GIT_TAG v${MIN_CLI11_VERSION}
+        GIT_TAG v2.6.2
     )

2. Rebuild and Check Help Output

Run a clean configure and build, then inspect the launch help command:

# Clear CMake cache and rebuild
rm -rf build/
cmake -B build --preset default
cmake --build --preset default

# Run launch help
./build/lemonade launch --help

Observed Behavior (Bug): Options like --model, --directory, --recipe-file, and --agent-args will leak into the root launch help output instead of being hidden.

Here is a self contained reproducer (you can replace podman with docker if required). This will take a minute because well no cache. 😄

podman run --rm -i --entrypoint bash docker.io/ubuntu:22.04 <<'EOF'
set -xe

apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y \
    git \
    cmake \
    ninja-build \
    g++ \
    libcurl4-openssl-dev \
    libssl-dev \
    zlib1g-dev \
    libcap-dev \
    pkg-config

git clone https://github.com/lemonade-sdk/lemonade.git /workspace
cd /workspace

# Force FetchContent to pull CLI11 v2.6.2 (disabling system autodetection)
sed -i 's/find_path(CLI11_INCLUDE_DIRS "CLI\/CLI.hpp")/set(CLI11_INCLUDE_DIRS "")/' CMakeLists.txt
sed -i 's/GIT_TAG v${MIN_CLI11_VERSION}/GIT_TAG v2.6.2/' CMakeLists.txt

# Configure and compile only the CLI client target
cmake -B build -GNinja -DBUILD_WEB_APP=OFF .
cmake --build build --target lemonade

# 5. Run the help command to demonstrate the option leakage bug
echo "=== DEMONSTRATING THE BUG (Leaked Options) ==="
./build/lemonade launch --help
EOF

Ah ok, I can reproduce the bug now, thanks for the script.

@sawansri sawansri left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the fix!

Image

Fix tested with:

docker run --rm -i --entrypoint bash docker.io/ubuntu:22.04 <<'EOF'
  set -xe

  apt-get update
  DEBIAN_FRONTEND=noninteractive apt-get install -y \
      git \
      cmake \
      ninja-build \
      g++ \
      libcurl4-openssl-dev \
      libssl-dev \
      zlib1g-dev \
      libcap-dev \
      pkg-config

  git clone https://github.com/abn/lemonade.git /workspace
  cd /workspace
  git checkout fix/launch-help-options
  # Force FetchContent to pull CLI11 v2.6.2 (disabling system autodetection)
  sed -i 's/find_path(CLI11_INCLUDE_DIRS "CLI\/CLI.hpp")/set(CLI11_INCLUDE_DIRS "")/' CMakeLists.txt
  sed -i 's/GIT_TAG v${MIN_CLI11_VERSION}/GIT_TAG v2.6.2/' CMakeLists.txt
  
  # Configure and compile only the CLI client targe
  cmake -B build -GNinja -DBUILD_WEB_APP=OFF .
  cmake --build build --target lemonade
  # 5. Run the help command to demonstrate the option leakage bug
  ./build/lemonade launch --help
EOF

@sawansri sawansri enabled auto-merge June 23, 2026 23:03
@sawansri sawansri added this pull request to the merge queue Jun 24, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 24, 2026
@fl0rianr fl0rianr added this pull request to the merge queue Jun 24, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area::cli lemonade CLI client (src/cpp/cli) bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants