Compare commits

...

4 Commits

Author SHA1 Message Date
HAL9000 534fbba5db fix(cli): correct parse_args override type to satisfy TyperGroup contract
CI / lint (pull_request) Successful in 46s
CI / typecheck (pull_request) Successful in 1m1s
CI / security (pull_request) Successful in 1m13s
CI / helm (pull_request) Successful in 25s
CI / push-validation (pull_request) Successful in 23s
CI / build (pull_request) Successful in 44s
CI / quality (pull_request) Successful in 49s
CI / unit_tests (pull_request) Failing after 5m9s
CI / coverage (pull_request) Has been skipped
CI / docker (pull_request) Has been skipped
CI / integration_tests (pull_request) Failing after 9m7s
CI / status-check (pull_request) Failing after 3s
TyperGroup.parse_args is typed against typer._click.core.Context (the
vendored click), which is not assignable to click.Context or
typer.Context (typer.models.Context). Use Any for the ctx parameter to
satisfy the override constraint without depending on typer's private
_click module path.

ISSUES CLOSED: #6879
2026-06-02 06:47:28 -04:00
HAL9000 0e0aec0f16 fix(cli): handle standalone short options like -f that take values
When a global short option like -f (for --format) appears after a subcommand
as a standalone token (e.g., 'agents info -f json'), it was not being promoted
because the code only handled fused forms like '-fjson'.

This fix adds a check for standalone short options in _GLOBAL_VALUE_SHORT_OPTIONS
that consume the following argument, allowing 'agents info -f json' to work
correctly in addition to 'agents info -fjson'.
2026-06-02 06:47:28 -04:00
HAL9000 cb77abb6c7 chore: add contributor entry for CLI global format flag fix (#6879) 2026-06-02 06:47:28 -04:00
HAL9000 06d13687c4 fix(cli): allow global format flag after subcommands
Closes #6879\n\nISSUES CLOSED: #6879
2026-06-02 06:47:28 -04:00
4 changed files with 114 additions and 0 deletions
+5
View File
@@ -1097,6 +1097,11 @@ iteration` and data corruption under concurrent plan execution. All public
The `export` command gains `--output-format` and the `import` command gains `--format`
to select the output envelope format independently of the export/import file format.
- **CLI global format flag parsing** (#6879): Promotes global CLI options before
Typer parsing so `agents <command> --format json` and `-f` shorthand work from
the documented position. Adds regression coverage for version, info, and
diagnostics commands.
- **Robot Framework TDD Listener Guards** (#5436): Added three guard conditions to the
`tdd_expected_fail_listener` `end_test()` function to prevent blindly inverting ALL test
failures to passes, which was masking infrastructure errors and causing flaky CI behavior.
+1
View File
@@ -28,6 +28,7 @@ Below are some of the specific details of various contributions.
* HAL 9000 has contributed the plan tree JSON/YAML command envelope fix (#9163): wrapped `agents plan tree --format json/yaml` output in the spec-required command envelope structure, added summary statistics, decision_ids mapping, child_plans list, and accurate timing measurement.
* HAL 9000 contributed Structural Component Output Validation (PR #11161 / issue #8164): implemented `validate_plan_tree`, `validate_decision_dict`, `validate_structured_output`, and `validate_structured_component_output` validators that replace exact-character matching with structural schema checking for plan tree nodes, decision CLI dictionaries, and structured session output envelopes.
* HAMZA KHYARI has contributed the ACMS execute-phase context assembler project-level hot_max_tokens fix (PR #11036 / issue #11035): added `_resolve_effective_budget()` method that reads each linked project's `settings.hot_max_tokens` and uses the maximum override value as the pipeline budget instead of the hardcoded global 16K default.
* HAL 9000 has contributed the CLI global format flag fix (#6879): promoted global options before subcommand parsing to allow `agents <command> --format ...` syntax as documented.
* This project was made possible thanks to considerable donation of time, money, and resources by CleverThis, Inc.
* HAL 9000 has contributed automated bug fixes, CLI output formatting improvements, and ongoing maintenance as part of the CleverAgents automation system.
* HAL 9000 has contributed the pr-review-pool-supervisor tracking prefix documentation fix (#7891): aligned all documentation references from the outdated `AUTO-REV-POOL` prefix to the correct `AUTO-REV-SUP` prefix used in production.
+19
View File
@@ -44,6 +44,25 @@ Feature: Global --format flag propagation to subcommands
Then the global format command should succeed
And the global format output should be valid JSON
# -----------------------------------------------------------------------
# Regression: global --format accepted after the subcommand name
# -----------------------------------------------------------------------
Scenario: Global --format flag works after the info subcommand name
When I invoke the CLI with global args "info --format json"
Then the global format command should succeed
And the global format output should be valid JSON
Scenario: Global --format flag works after the version subcommand name
When I invoke the CLI with global args "version --format json"
Then the global format command should succeed
And the global format output should be valid JSON
Scenario: Global --format flag works after the diagnostics subcommand name
When I invoke the CLI with global args "diagnostics --format json"
Then the global format command should succeed
And the global format output should be valid JSON
# -----------------------------------------------------------------------
# Subtask 3: version, info, diagnostics read format from global ctx.obj
# -----------------------------------------------------------------------
+89
View File
@@ -9,6 +9,7 @@ from pathlib import Path
from typing import TYPE_CHECKING, Annotated, Any
import typer
from typer.core import TyperGroup
from cleveragents import __version__
from cleveragents.cli.formatting import OutputFormat
@@ -21,6 +22,90 @@ _console: "Console | None" = None
_err_console: "Console | None" = None
_subcommands_registered = False
_GLOBAL_VALUE_OPTIONS = frozenset({"--format"})
_GLOBAL_VALUE_SHORT_OPTIONS = frozenset({"-f"})
_GLOBAL_VALUE_EQ_PREFIXES = ("--format=",)
_GLOBAL_FLAG_OPTIONS = frozenset({"--show-secrets", "--version", "-V"})
def _split_short_value_option(option: str) -> tuple[str, str] | None:
for short in _GLOBAL_VALUE_SHORT_OPTIONS:
if option.startswith(short) and len(option) > len(short):
return short, option[len(short) :]
return None
def _promote_global_options(args: list[str]) -> list[str]:
"""Move global root options before subcommands for Typer parsing."""
if not args:
return args
promoted: list[str] = []
remaining: list[str] = []
i = 0
length = len(args)
while i < length:
arg = args[i]
if arg == "--":
remaining.extend(args[i:])
break
if arg in _GLOBAL_FLAG_OPTIONS:
promoted.append(arg)
i += 1
continue
if arg in _GLOBAL_VALUE_OPTIONS:
if i + 1 < length:
promoted.extend([arg, args[i + 1]])
i += 2
else:
remaining.append(arg)
i += 1
continue
eq_prefix = next(
(prefix for prefix in _GLOBAL_VALUE_EQ_PREFIXES if arg.startswith(prefix)),
None,
)
if eq_prefix is not None and len(arg) > len(eq_prefix):
promoted.extend([eq_prefix.rstrip("="), arg[len(eq_prefix) :]])
i += 1
continue
split_short = _split_short_value_option(arg)
if split_short is not None:
short_opt, value = split_short
promoted.extend([short_opt, value])
i += 1
continue
if arg in _GLOBAL_VALUE_SHORT_OPTIONS:
if i + 1 < length:
promoted.extend([arg, args[i + 1]])
i += 2
else:
remaining.append(arg)
i += 1
continue
remaining.append(arg)
i += 1
return promoted + remaining
class CleverAgentsTyperGroup(TyperGroup):
"""Typer group that promotes global options before subcommand parsing."""
def parse_args(self, ctx: Any, args: list[str]) -> list[str]:
promoted_args = _promote_global_options(list(args))
return super().parse_args(ctx, promoted_args)
__all__ = [
"_print_basic_help",
"app",
@@ -69,6 +154,7 @@ app: Any = typer.Typer(
pretty_exceptions_enable=True,
pretty_exceptions_show_locals=False,
rich_markup_mode="rich",
cls=CleverAgentsTyperGroup,
)
@@ -740,6 +826,9 @@ def main(args: list[str] | None = None) -> int:
if not args:
args = ["--help"]
# Global CLI options are promoted by CleverAgentsTyperGroup.parse_args,
# so we avoid reprocessing here to prevent double handling.
# Fast paths for lightweight flags to avoid heavy imports when using the
# real Typer app. If the app is monkeypatched (e.g., tests), fall back to
# normal execution so patched call paths are exercised.