Skip to content

Releases: aiperceivable/apcore-cli-python

Release 0.7.0

26 Apr 04:07

Choose a tag to compare

Changed

  • Dependency bump: requires apcore >= 0.18.0 (was >= 0.17.1). Aligns with upstream apcore 0.18.0 and apcore-toolkit 0.4.2 breaking changes.
  • MAX_MODULE_ID_LENGTH 128 → 192: validate_module_id() and all references updated to the new 192-character limit introduced in apcore 0.18.0 (apcore.registry.registry.MAX_MODULE_ID_LENGTH).
  • describe-pipeline renders StrategyInfo: executor.describe_pipeline(strategy) now returns a StrategyInfo dataclass (name, step_count, step_names, description). strategy.py updated to use StrategyInfo fields; header line is Pipeline: {info.name} ({info.step_count} steps). Falls back gracefully to the legacy _resolve_strategy_name path when describe_pipeline is unavailable.
  • CI — spec-repo checkout: .github/workflows/ci.yml now checks out aiperceivable/apcore-cli into .apcore-cli-spec/ and exposes it to pytest via APCORE_CLI_SPEC_REPO. Mirrors the pattern established in apcore-python / apcore-cli-typescript.

Added

  • create_cli(app=...) parameter: create_cli() accepts an optional app: APCore unified client (introduced in apcore 0.18.0). app is mutually exclusive with registry/executor (raises ValueError). When app is provided, registry and executor are extracted from app.registry and app.executor. Filesystem discovery is skipped if app.registry already contains registered modules; otherwise normal discovery proceeds into app.registry.
  • Cross-language conformance test harness (tests/conformance/) consuming the shared apcli-visibility fixtures from the aiperceivable/apcore-cli spec repo (conformance/fixtures/apcli-visibility/). Behavioral assertions (apcli group visibility, registered subcommand set for include/exclude modes, always-registered exec) run today across all five canonical scenarios (standalone-default, embedded-default, cli-override, env-override, yaml-include). Byte-matching against expected_help.txt is marked xfail until Click's HelpFormatter is replaced with a canonical clap v4 / GNU-style emitter, tracked for parity with apcore-cli-typescript/src/canonical-help.ts.
  • APCORE_CLI_SPEC_REPO env var — overrides the spec-repo lookup path for conformance fixtures. Defaults to a sibling checkout (../apcore-cli/). Tests are skipped (not failed) when the spec repo is absent.
  • FE-12: Module Exposure Filtering — Declarative control over which discovered modules are exposed as CLI commands.
  • ExposureFilter class in exposure.py with is_exposed(module_id) and filter_modules(ids) methods.
  • Three modes: all (default), include (whitelist), exclude (blacklist) with glob-pattern matching.
  • ExposureFilter.from_config(dict) classmethod for loading from apcore.yaml expose section.
  • create_cli(expose=...) parameter accepting dict or ExposureFilter instance.
  • list --exposure {exposed,hidden,all} filter flag in discovery commands.
  • GroupedModuleGroup._build_group_map() integration: calls ExposureFilter.is_exposed() to filter command registration.
  • ConfigResolver gains expose.* config keys.
  • 4-tier config precedence: CliConfig.expose > --expose-mode CLI flag > env var > apcore.yaml.
  • Hidden modules remain invocable via exec <module_id>.
  • New file: exposure.py.

Release 0.6.0

06 Apr 12:59

Choose a tag to compare

Changed

  • Dependency bump: requires apcore >= 0.17.1 (was >= 0.15.1). Adds Execution Pipeline Strategy, Config Bus enhancements, Pipeline v2 declarative step metadata, minimal strategy preset.
  • Schema parser: Required schema properties now correctly enforced at CLI option level (was silently optional).
  • Approval gate: Fixed inverted logic in annotation type guard; check_approval() now accepts timeout parameter.

Added

  • FE-11: Usability Enhancements — 11 new capabilities:
  • --dry-run preflight mode via Executor.validate(). Standalone validate command.
  • System management commands: health, usage, enable, disable, reload, config get/config set. Graceful no-op when system modules unavailable.
  • Enhanced error output: structured JSON with ai_guidance, suggestion, retryable, user_fixable, details. TTY hides machine-only fields.
  • --trace pipeline visualization via call_with_trace().
  • CliApprovalHandler class implementing apcore ApprovalHandler protocol, wired to Executor.set_approval_handler(). --approval-timeout, --approval-token flags.
  • --stream JSONL output via Executor.stream().
  • Enhanced list command: --search, --status, --annotation, --sort, --reverse, --deprecated, --deps.
  • --strategy selection: standard, internal, testing, performance, minimal. describe-pipeline command.
  • Output format extensions: --format csv|yaml|jsonl, --fields dot-path field selection.
  • Multi-level grouping: cli.group_depth config key.
  • Custom command extension: create_cli(extra_commands=[...]) with collision detection.
  • New error code: CONFIG_ENV_MAP_CONFLICT.
  • New config keys: cli.approval_timeout (60), cli.strategy ("standard"), cli.group_depth (1).
  • New environment variables: APCORE_CLI_APPROVAL_TIMEOUT, APCORE_CLI_STRATEGY, APCORE_CLI_GROUP_DEPTH.
  • New files: system_cmd.py, strategy.py.

Release 0.5.0

01 Apr 03:40

Choose a tag to compare

Release version 0.5.0

See CHANGELOG.md for details.

Release 0.4.1

30 Mar 08:15

Choose a tag to compare

Fixed

  • prevent click parameter mismatch by setting expose_value=False for the --man option

Release 0.4.0

29 Mar 04:20

Choose a tag to compare

Added

  • Verbose help mode — Built-in apcore options (--input, --yes, --large-input, --format, --sandbox) are now hidden from --help output by default. Pass --help --verbose to display the full option list including built-in options.
  • Universal man page generationbuild_program_man_page() generates a complete roff man page covering all registered commands. configure_man_help() adds --help --man support to any Click CLI, enabling downstream projects to get man pages for free.
  • Documentation URL supportset_docs_url() sets a base URL for online docs. Per-command help shows Docs: {url}/commands/{name}, man page SEE ALSO includes Full documentation at {url}. No default — disabled when not set.

Changed

  • build_module_command() respects the global verbose help flag to control built-in option visibility.
  • --sandbox is now always hidden from help (not yet implemented). Only four built-in options (--input, --yes, --large-input, --format) toggle with --verbose.
  • Improved built-in option descriptions for clarity.

Release 0.3.1

27 Mar 10:22

Choose a tag to compare

Added

  • DisplayResolver integration__main__.py integrates DisplayResolver from apcore-toolkit (optional) when --binding option is provided; gracefully skipped when not installed.
  • init to BUILTIN_COMMANDSinit subcommand is now registered in the builtin commands set.
  • APCORE_AUTH_API_KEY to man page — environment variable documented in generated roff man page.
  • Grouped shell completion with _APCORE_GRP — bash/zsh/fish completion scripts now support two-level group/command completion via the _APCORE_GRP environment variable (shell.py).
  • Path traversal validation for --dir in init command — rejects paths containing .. segments to prevent directory escape (init_cmd.py).

Fixed

  • RegistryWriter API call — constructor now called without parameters; fixes TypeError introduced by upstream API change.

Changed

  • apcore dependency bumped to >=0.14.0.

Release 0.3.0

24 Mar 03:42

Choose a tag to compare

Added

  • Display overlay routing (§5.13) — LazyModuleGroup now reads metadata["display"]["cli"] for alias and description when building the command list and routing get_command(). Commands are exposed under their CLI alias instead of raw module_id.
  • _alias_map: built from metadata["display"]["cli"]["alias"] (with module_id fallback), enabling apcore-cli alias-name invocation.
  • _descriptor_cache: populated during alias map build to avoid double registry.get_definition() calls in get_command().
  • _alias_map_built flag only set on successful build, allowing retry after transient registry errors.
  • Display overlay in JSON outputformat_module_list(..., "json") now reads metadata["display"]["cli"] for id, description, and tags, consistent with the table output branch.

Changed

  • _ERROR_CODE_MAP.get(error_code, 1): guarded with isinstance(error_code, str) to prevent None-key lookup.
  • Runtime companion: apcore-toolkit >= 0.4.0 enables DisplayResolver and ConventionScanner (graceful fallback when not installed).

Tests

  • TestDisplayOverlayAliasRouting (6 tests): list_commands uses CLI alias, get_command by alias, cache hit path, module_id fallback, build_module_command alias and description.
  • test_format_list_json_uses_display_overlay: JSON output uses display overlay alias/description/tags.
  • test_format_list_json_falls_back_to_scanner_when_no_overlay: JSON output falls back to scanner values.

Added (Grouped Commands — FE-09)

  • GroupedModuleGroup(LazyModuleGroup) — organizes modules into nested click.Group subcommands based on namespace prefixes. Auto-groups by first . segment, with display.cli.group override from binding.yaml.
  • _resolve_group() — 3-tier group resolution: explicit display.cli.group > first . segment of CLI alias > top-level.
  • _build_group_map() — lazy, idempotent group map builder with builtin collision detection and shell-safe group name validation.
  • format_help() — collapsed root help with Commands, Modules, and Groups sections (with command counts).
  • _LazyGroup(click.Group) — nested group that lazily builds subcommands from module descriptors.
  • list --flat flag — opt-in flat display mode for list command; default is now grouped display.
  • format_grouped_module_list() — Rich table output grouped by namespace.
  • Updated shell completions — bash/zsh/fish completion scripts handle two-level group/command structure.

Changed (Grouped Commands)

  • create_cli() now uses GroupedModuleGroup instead of LazyModuleGroup.

Tests (Grouped Commands)

  • 48 new tests: TestResolveGroup (8+), TestBuildGroupMap (5+), TestGroupedModuleGroupRouting (7), TestLazyGroupInner (4), TestGroupedHelpDisplay (5), TestCreateCliGrouped (1), TestGroupedE2E (5), TestGroupedDiscovery (7+), TestGroupedCompletion (6).

Added (Convention Module Discovery — §5.14)

  • apcore-cli init module <id> — scaffolding command with --style (decorator, convention, binding) and --description options. Generates module templates in the appropriate directory.
  • --commands-dir CLI option — path to a convention commands directory. When set, ConventionScanner from apcore-toolkit scans for plain functions and registers them as modules.

Tests (Convention Module Discovery)

  • 6 new tests in tests/test_init_cmd.py covering all three styles and options.

Release 0.2.2

22 Mar 13:14

Choose a tag to compare

Changed

  • Rebrand: aipartnerup → aiperceivable

Release 0.2.1

19 Mar 09:31

Choose a tag to compare

Changed

  • Help text truncation limit increased from 200 to 1000 characters (configurable via cli.help_text_max_length config key)
  • _extract_help: added max_length: int = 1000 parameter (schema_parser.py)
  • schema_to_click_options: added max_help_length: int = 1000 parameter (schema_parser.py)
  • build_module_command: added help_text_max_length: int = 1000 parameter, threaded through to schema parser (cli.py)
  • LazyModuleGroup: constructor accepts help_text_max_length: int = 1000, passes to build_module_command (cli.py)
  • create_cli: resolves cli.help_text_max_length from ConfigResolver and passes to LazyModuleGroup (__main__.py)
  • format_exec_result: nested dict/list values in table mode now rendered with json.dumps instead of str() (output.py)

Added

  • cli.help_text_max_length config key (default: 1000) in ConfigResolver.DEFAULTS (config.py)
  • APCORE_CLI_HELP_TEXT_MAX_LENGTH environment variable support for configuring help text max length
  • test_help_truncation_default: tests default 1000-char truncation
  • test_help_no_truncation_within_limit: tests no truncation at 999 chars
  • test_help_truncation_custom_max: tests custom max_length parameter
  • 263 tests (up from 261)

Release 0.2.0

16 Mar 09:25

Choose a tag to compare

Added

  • APCORE_CLI_LOGGING_LEVEL env var — CLI-specific log level that takes priority over APCORE_LOGGING_LEVEL; 3-tier precedence: --log-level flag > APCORE_CLI_LOGGING_LEVEL > APCORE_LOGGING_LEVEL > WARNING (__main__.py)
  • test_cli_logging_level_takes_priority_over_global — verifies APCORE_CLI_LOGGING_LEVEL=DEBUG wins over APCORE_LOGGING_LEVEL=ERROR
  • test_cli_logging_level_fallback_to_global — verifies fallback when CLI-specific var is unset
  • test_builtin_name_collision_exits_2 — schema property named format (or other reserved names) causes build_module_command to exit 2
  • test_exec_result_table_format--format table renders Rich Key/Value table to stdout
  • test_bash_completion_quotes_prog_name_in_directive — verifies shlex.quote() applied to complete -F directive, not just embedded subshell
  • test_zsh_completion_quotes_prog_name_in_directives — verifies compdef line uses quoted prog_name
  • test_fish_completion_quotes_prog_name_in_directives — verifies complete -c lines use quoted prog_name
  • 17 new tests (244 → 261 total)

Changed

  • --log-level accepted choices: WARNWARNING (__main__.py)
  • schema_to_click_options: schema-derived options now always have required=False; required fields marked [required] in help text instead of Click enforcement — allows --input - STDIN to supply required values without Click rejecting first (schema_parser.py)
  • format_exec_result: now routes through resolve_format() and renders Rich table when --format table is specified; previously ignored its format parameter (output.py)
  • _generate_bash_completion, _generate_zsh_completion, _generate_fish_completion: shlex.quote() applied to ALL prog_name positions in generated scripts (complete directives, compdef, complete -c), not only embedded subshell commands (shell.py)
  • check_approval: removed unused ctx: click.Context parameter (approval.py)
  • set_audit_logger: broadened type annotation from AuditLogger to AuditLogger | None (cli.py)
  • collect_input: simplified redundant condition if not raw or raw_size == 0:if not raw: (cli.py)
  • Example Input models: all 7 modules updated with Field(description=...) on every field so CLI --help shows descriptive text for each flag

Fixed

  • --input - STDIN blocked by Click required enforcement: schema_to_click_options was generating required=True Click options; Click validated before the callback ran, rejecting STDIN-only invocations. Resolved by always using required=False and delegating required validation to jsonschema.validate() after input collection. Fixes all 6 TestRealStdinPiping failures.
  • --log-level had no effect: logging.basicConfig() is a no-op after the first call; subsequent create_cli() calls in tests retained the prior handler's level. Fixed by calling logging.getLogger().setLevel() explicitly after basicConfig().
  • test_log_level_flag_takes_effect false pass: --help is an eager flag that exits before the group callback, so --log-level DEBUG --help never applied the log level. Test updated to use completion bash subcommand instead.
  • Shell completion directives not shell-safe: prog names with spaces or special characters were unquoted in complete -F, compdef, and complete -c lines. Fixed by assigning quoted = shlex.quote(prog_name) and using it in all directive positions.
  • Audit set_audit_logger(None) type error: type annotation rejected None; broadened to AuditLogger | None.
  • Test logger level leakage: tests modifying root logger level affected subsequent tests; fixed with try/finally that restores the original level.

Security

  • AuditLogger._hash_input: now uses secrets.token_bytes(16) per-invocation salt before hashing, preventing cross-invocation input correlation via SHA-256 rainbow tables
  • build_module_command: added reserved-name collision guard — exits 2 if a schema property (input, yes, large_input, format, sandbox) conflicts with a built-in CLI option name
  • _prompt_with_timeout (SIGALRM path): wrapped in try/finally to guarantee signal handler restoration regardless of exit path