Skip to content

cli: align with Typer's bundled agent skill - #15

Merged
richardmhope merged 3 commits into
mainfrom
claude/typer-agent-skill-review-sm7psy
Jul 28, 2026
Merged

cli: align with Typer's bundled agent skill#15
richardmhope merged 3 commits into
mainfrom
claude/typer-agent-skill-review-sm7psy

Conversation

@richardmhope

@richardmhope richardmhope commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Reviewed src/icebergsca/cli/main.py against the agent skill Typer ships at typer/.agents/skills/typer/SKILL.md (typer 0.27.0), and closed the gaps.

Already aligned

Explicit typer.Typer() app rather than typer.run; Annotated throughout, with no old-style = typer.Option(...) defaults or default=... ellipsis; no_args_is_help on the root app; list[str] for the repeatable --exclude; a boolean flag pair on sbom; an eager --version callback. None of the Click-era settings the skill calls out (expose_value, shell_complete, show_choices, errors, prompt_required, is_flag, flag_value, allow_from_autoenv) appear anywhere in src/, and nothing imports Click.

--scope and --ecosystem are now Typer enum lists

They took a single comma-separated str and hand-rolled the splitting and enum validation, so --help rendered <str> and advertised no choices — inconsistent with --format, which Typer converts natively, and with --exclude in the same command, already a list. The skill's "CLI options with multiple values" section is explicit that a multi-value option is a list.

They are now list[Scope] | None and list[EcosystemId] | None. Typer derives the metavar, validates each value, and rejects a bad one as a usage error on its own, so _parse_enum_option, _choices_metavar and the EnumT TypeVar are all gone — 42 lines out, 8 in.

--scope       <runtime|dev|test|build|optional>          Scope to include, overriding --include-dev. Repeatable.
--ecosystem   <pypi|npm|maven|go|cargo|nuget|rubygems>   Ecosystem to restrict to. Repeatable.

$ icebergsca scan . --scope prod
Invalid value for '--scope': 'prod' is not one of 'runtime', 'dev', 'test', 'build', 'optional'.   # exit 2

Breaking: --scope runtime,dev is now a usage error; use --scope runtime --scope dev. Taken on the basis that there are no deployments to keep compatible. Exit codes and the rest of the help output are unchanged.

Other fixes

  • The sbom docstring used RST double backticks, which the default Rich markup mode renders literally in --help. Now uses [bold], per the skill's Rich section.
  • rich_markup_mode is stated on the app rather than inferred, so help output does not change shape with what else is installed.
  • sbom's -v/-q had no help text, unlike the same flags on scan.
  • The cache sub-app lacked no_args_is_help, so a bare icebergsca cache errored with exit 2 while a bare icebergsca printed help.
  • Floored typer at 0.26, the release that vendored Click. Below that, an unrelated Click upgrade in the same environment governs this CLI's parsing and exit codes — and ExitCode.USAGE = 2 is justified in its own docstring by Click's reservation of that code. The lock already resolved to 0.27.

Docs

README.md, website/docs/cli.md, website/docs/ecosystems.md and the bundled .agents/skills/icebergsca/SKILL.md now show the repeated form, per the CLAUDE.md rule that a skill describing flags that no longer exist is worse than none.

Verification

ruff check, ruff format --check, mypy and pytest all pass — 386 tests, up from 384. Added test_scope_flag_is_repeatable and test_enum_choices_are_listed_in_help, the latter asserting the choices reach --help so a future switch back to a bare <str> metavar fails loudly.

Dogfooded icebergsca scan . --ecosystem pypi --scope runtime --scope build --format json — 50 dependencies, correct scope union.

claude added 3 commits July 28, 2026 22:45
Reviewed src/icebergsca/cli/main.py against the typer skill shipped at
typer/.agents/skills/typer/SKILL.md. The explicit Typer app, Annotated
declarations and absence of Click-era settings already matched; these are
the gaps.

- --scope and --ecosystem took a single comma-separated string, so their
  help showed <str> and listed no choices, unlike --format and unlike
  --exclude in the same command. They now take a repeatable list and
  advertise their members in the metavar. Comma-separated values still
  parse, so every documented invocation is unchanged.
- The sbom docstring used RST double backticks, which the default Rich
  markup mode renders literally. Uses Rich markup instead.
- rich_markup_mode is now stated rather than inferred, so help output does
  not change shape with what else is installed.
- sbom's -v/-q had no help text; the cache sub-app had no no_args_is_help,
  so a bare `icebergsca cache` errored where a bare `icebergsca` helps.
- Floor typer at 0.26, the release that vendored Click. Below it, an
  unrelated Click upgrade governs parsing and exit codes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CJSEXcpbfSLbYqHc2t2WY2
No deployments to keep compatible, so the comma-separated form goes and the
options become plain list[Scope] and list[EcosystemId]. Typer derives the
choices metavar, validates the values and rejects a bad one as a usage error
by itself, which is exactly what _parse_enum_option and _choices_metavar were
reimplementing — both are now gone, along with the EnumT TypeVar.

Help output and exit codes are unchanged. Docs and the bundled skill now show
the repeated form.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CJSEXcpbfSLbYqHc2t2WY2
test_enum_choices_are_listed_in_help passed locally and failed on all four
CI Pythons. Rich counts GitHub Actions as a terminal, so help output is bare
off CI and styled on it — and it styles each choice in a metavar separately,
putting escape codes between every value:

  <\x1b[1;33mpypi\x1b[0m|\x1b[1;33mnpm\x1b[0m|...

so the plain substring is never present there. Strips the codes first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CJSEXcpbfSLbYqHc2t2WY2
@richardmhope
richardmhope merged commit fe8b195 into main Jul 28, 2026
8 checks passed
@richardmhope
richardmhope deleted the claude/typer-agent-skill-review-sm7psy branch July 28, 2026 23:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants