py-wlcli 0.8.1__tar.gz → 0.8.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/PKG-INFO +1 -1
- py_wlcli-0.8.2/VERSION +1 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/capabilities.py +2 -1
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/cc/checks.py +160 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/cc/mutate.py +31 -8
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/env/cli.py +17 -4
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/env_status.py +93 -13
- py_wlcli-0.8.1/VERSION +0 -1
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/.gitignore +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/LICENSE +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/README.md +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/pyproject.toml +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/__main__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/cc/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/cc/cli.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/cli_click.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/base.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/build.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/build_utils.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/builders/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/builders/cleanup.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/builders/coordinator.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/builders/environment.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/builders/rust_builder.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/builders/stubs.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/dist.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/test.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/build.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/clean.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/clean_utils.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/core.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/dead_code/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/dead_code/dead_code_command.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/dead_code/detector.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/dead_code/fixer.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/dead_code/reporter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/dead_code/utils.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/lfs.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/python.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/rust.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/utils/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/clean/venv.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/cleanup.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/click_base.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/config/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/config/config.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/debug/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/debug/debug.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/debug/debug_cache.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/debug/debug_subagent.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/debug/output_formatter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/debug/source_hasher.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/format/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/format/format_cache_adapter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/format/format_command.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/format/format_coordinator.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/format/format_executor.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/format/format_outcome.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/format/format_path_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/format/format_progress.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/format/format_reporter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/format/python_formatter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/format/rust_formatter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/gate/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/gate/gate_command.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/gate/preflight.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/git/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/git/config.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/git/git_facts.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/git/git_flow.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/git/hook.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/git/policy.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/git/push_update.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/common/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/common/check_git_bash.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/common/error_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/common/exceptions.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/cargo_sync.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/config_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/directory_utils.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/git/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/git/branch_creator.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/git/git_flow_interface.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/git/git_flow_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/git/git_lfs_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/git/git_utility.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/git/gitignore_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/git_initializer.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/i18n_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/log_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/project_structure/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/project_structure/config_generator.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/project_structure/directory_creator.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/project_structure/hook_source.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/project_structure/hooks_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/project_structure/readme_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/project_structure/rust_files_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/project_structure/setup_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/project_structure/sop_generator.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/project_structure/template_copier.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/project_structure/template_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/pyproject_generator.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/rust_initializer.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/symlink_cleaner.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/symlink_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/components/venv_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/initenv.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/services/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/services/environment_initializer.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/services/git_lfs_initializer.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/initenv/services/project_structure_initializer.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lfs/README.md +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lfs/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lfs/cli.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lfs/config.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lfs/hook.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lfs/initializer.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lfs/manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lfs/policy.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lfs/watcher.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lint/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lint/lint_command.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lint/lint_executor.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lint/lint_reporter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lint/lint_run.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/lint/mypy_config.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/registry.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/common/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/common/capabilities.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/common/config.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/common/version_cache.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/handlers/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/handlers/base_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/handlers/install_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/handlers/status_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/handlers/uninstall_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/handlers/update_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/handlers/version_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/self_command.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/services/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/services/installation_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/services/local_installer.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/services/pypi_updater.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/self/services/windows_update.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/base_dependency_analyzer.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/batch_processor.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/cache_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/coverage_analyzer.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/coverage_cache_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/progress_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/python_env_detector.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/report_generator.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/single_test_executor.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/speed_checker.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/test_command_builder.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/test_commands.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/test_reporter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/test_result_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/test_runner.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/test_utils.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/utils/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/utils/coverage_parser.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/utils/env_info.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/utils/junit_parser.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/utils/markdown_utils.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/testcommands/utils/project_root.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/update/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/update/services/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/update/services/backup_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/update/services/component_manager.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/update/services/conflict_resolver.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/update/services/vendors_updater.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/update/services/version_tracker.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/update/update_command.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/update/utils/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/version/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/version/version_command.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/workflow.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/env/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/envelope.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/exceptions.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/lib/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/lib/rust_utils.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/mcp/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/mcp/capabilities.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/mcp/cli.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/mcp/gitlab.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/mcp/k8s.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/mcp/protocol.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/platform.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/quality/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/cache.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/cache_ledger.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/cache_store.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/config/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/config/config_loader.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/config/core.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/config/defaults.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/config/env_exporter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/config/env_parser.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/config/validation.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/error_handler.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/file_copier.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/file_operations.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/language_utils.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/lazy_import.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/log_levels.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/log_rotators.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/logging.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/output_context.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/performance/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/performance/decorators.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/performance/exporter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/performance/models.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/performance/monitor.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/performance_monitor.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/platform_adapter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/pre_commit.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/pre_commit_config.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/root.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/root_fallback.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/run_evidence.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/structured_logger.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/structured_logging/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/structured_logging/config.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/structured_logging/core.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/structured_logging/env.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/structured_logging/filtering.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/structured_logging/filters.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/structured_logging/formatters.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/structured_logging/handlers.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/structured_logging/logger.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/subprocess.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/subprocess_utils.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/test_utils/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/test_utils/test_filter.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/uv_run.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/uv_tool.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/uv_tree.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/uv_workspace.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/version/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/version/pypi_version_checker.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/version/version_comparator.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/version/version_detectors.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/version/version_service.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/version/version_updater.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/wl_dir_updater.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/workspace_detector/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/workspace_detector/core.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/workspace_detector/detection_strategies.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/workspace_detector/exceptions.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/workspace_detector/types.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/utils/workspace_detector/venv_resolver.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/config/.codespellrc +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/config/dependencies.toml +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/config/mypy.ini +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/config/pyproject_defaults.toml +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/config/template_config.toml +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/config/tool_configs.toml +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/git/.gitignore +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/git/.pre-commit-config.yaml +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/applypatch-msg.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/commit-msg.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/fsmonitor-watchman.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/post-update.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/pre-applypatch.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/pre-commit +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/pre-commit.legacy +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/pre-commit.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/pre-merge-commit.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/pre-push.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/pre-rebase.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/pre-receive.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/prepare-commit-msg.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/push-to-checkout.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/sendemail-validate.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/applypatch-msg.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/check_lockfile.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/check_lockfile.sh +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/commit-msg.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/fsmonitor-watchman.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/post-update.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/pre-applypatch.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/pre-commit +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/pre-commit.legacy +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/pre-commit.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/pre-commit.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/pre-merge-commit.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/pre-push +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/pre-push.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/pre-rebase.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/pre-receive.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/unix/prepare-commit-msg.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/update.sample +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/hooks/win/work.bat +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/project/.gitignore +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/project/.python-version +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/project/LICENSE +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/project/README.md +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/project/pyproject.toml +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/project/pyproject_no_workspace.toml +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/project/pyproject_workspace.toml +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/readme/README.md +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/rust/Cargo.toml +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/rust/lib/__init__.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/rust/lib/rust_utils.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/rust/src/lib.rs +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/rust/src/main.rs +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/rust/tests/test_rust_fallback.py +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/sop_doc/git-dev-sop.md +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/sop_doc/industrial-standard-sop.md +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/sop_doc/python-sop.md +0 -0
- {py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/vendors/sop_doc/rust-readme.md +0 -0
py_wlcli-0.8.2/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.8.2
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""The shared capability registry for the ``wl`` CLI (issues #270, #221).
|
|
1
|
+
"""The shared capability registry for the ``wl`` CLI (issues #270, #221, #231).
|
|
2
2
|
|
|
3
3
|
Capabilities are the stable, dotted names a consumer (wlcc) probes instead of
|
|
4
4
|
grepping ``--help`` for an implementation flag (wlcc ADR-0010, decision 6):
|
|
@@ -43,6 +43,7 @@ CAPABILITY_SINCE: dict[str, str] = {
|
|
|
43
43
|
"cc.statusline": "0.8.0",
|
|
44
44
|
"cc.upgrade": "0.8.0",
|
|
45
45
|
"env.check": "0.8.0",
|
|
46
|
+
"env.check.require": "0.8.2",
|
|
46
47
|
"env.repair": "0.8.0",
|
|
47
48
|
"mcp.gitlab": "0.8.0",
|
|
48
49
|
"mcp.k8s": "0.8.0",
|
|
@@ -107,6 +107,15 @@ MCP_SERVE_ARGS: dict[str, str] = {
|
|
|
107
107
|
"k8s-diagnose": "k8s",
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
#: Environment the registered argv needs, per server (#229). ``gitlab`` owns
|
|
111
|
+
#: its default host inside ``server.py``; ``k8s-diagnose`` cannot discover the
|
|
112
|
+
#: SSH target, so the registration must carry it. This is the single source
|
|
113
|
+
#: for both the ``claude mcp add -e`` argv and the registration check.
|
|
114
|
+
MCP_SERVE_ENV: dict[str, tuple[tuple[str, str], ...]] = {
|
|
115
|
+
"gitlab": (),
|
|
116
|
+
"k8s-diagnose": (("K8S_SSH_HOST", "ubuntu-server"),),
|
|
117
|
+
}
|
|
118
|
+
|
|
110
119
|
#: Capability the ``wl`` on ``PATH`` must advertise before a registration argv
|
|
111
120
|
#: counts as verifiable (#228). Consumers (wlcc) use the same bit to decide
|
|
112
121
|
#: that registration goes through ``wl mcp serve``.
|
|
@@ -608,6 +617,124 @@ def _wl_reason(fields: dict[str, Any]) -> str:
|
|
|
608
617
|
return f"the wl CLI on PATH is not usable ({state or 'unknown state'})"
|
|
609
618
|
|
|
610
619
|
|
|
620
|
+
def mcp_config_path() -> Path:
|
|
621
|
+
"""Return Claude Code's user-scope config file (``claude mcp add -s user``).
|
|
622
|
+
|
|
623
|
+
``CLAUDE_CONFIG_DIR`` moves the file *inside* that directory, while the
|
|
624
|
+
default location is ``~/.claude.json`` -- a sibling of ``~/.claude``, not
|
|
625
|
+
``~/.claude/.claude.json``. ``HostContext.config_root`` therefore cannot
|
|
626
|
+
supply this path on its own. Verified against the CLI on 2026-11-05.
|
|
627
|
+
"""
|
|
628
|
+
raw = os.environ.get("CLAUDE_CONFIG_DIR")
|
|
629
|
+
if raw:
|
|
630
|
+
# The real CLI resolves this relative to the cwd and does **not**
|
|
631
|
+
# expand ``~`` (measured 2026-11-05), so neither may we.
|
|
632
|
+
return Path(os.path.abspath(raw)) / ".claude.json"
|
|
633
|
+
return Path(os.path.expanduser("~/.claude.json"))
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
def _registration_status(name: str, entry: Any, wl: str) -> str:
|
|
637
|
+
"""Classify one stored registration as ``ok``, ``missing`` or ``stale``.
|
|
638
|
+
|
|
639
|
+
The stamp alone is not evidence: a payload swap that keeps the version
|
|
640
|
+
leaves the old argv pointing at a deleted plugin file (#229), so the
|
|
641
|
+
stored command, args and required environment are compared verbatim.
|
|
642
|
+
"""
|
|
643
|
+
if not isinstance(entry, dict):
|
|
644
|
+
return "missing"
|
|
645
|
+
if entry.get("type", "stdio") != "stdio":
|
|
646
|
+
return "stale"
|
|
647
|
+
if entry.get("command") != wl:
|
|
648
|
+
return "stale"
|
|
649
|
+
if entry.get("args") != ["mcp", "serve", MCP_SERVE_ARGS[name]]:
|
|
650
|
+
return "stale"
|
|
651
|
+
env = entry.get("env")
|
|
652
|
+
if env is None:
|
|
653
|
+
env = {}
|
|
654
|
+
if not isinstance(env, dict):
|
|
655
|
+
return "stale"
|
|
656
|
+
for key, _default in MCP_SERVE_ENV[name]:
|
|
657
|
+
# Only presence matters: a user's custom host (e.g. a real K8S_SSH_HOST)
|
|
658
|
+
# is a working registration and must not be rewritten to the default.
|
|
659
|
+
if not env.get(key):
|
|
660
|
+
return "stale"
|
|
661
|
+
return "ok"
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
def _cwd() -> str:
|
|
665
|
+
"""The working directory Claude Code keys the local scope by."""
|
|
666
|
+
return os.path.abspath(os.getcwd())
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
def _shadowing_servers(config: dict[str, Any]) -> dict[str, str]:
|
|
670
|
+
"""Return server name -> scope for entries that shadow the user scope.
|
|
671
|
+
|
|
672
|
+
Claude Code resolves ``mcpServers`` for the working directory: the local
|
|
673
|
+
scope in ``projects[<cwd>].mcpServers`` and the project ``<cwd>/.mcp.json``
|
|
674
|
+
both take precedence over the user-scope map (#229 review). A shadowing
|
|
675
|
+
entry is reported, never rewritten -- it belongs to the project, not wlcc.
|
|
676
|
+
"""
|
|
677
|
+
shadowed: dict[str, str] = {}
|
|
678
|
+
cwd = _cwd()
|
|
679
|
+
projects = config.get("projects")
|
|
680
|
+
if isinstance(projects, dict):
|
|
681
|
+
local = projects.get(cwd)
|
|
682
|
+
if isinstance(local, dict):
|
|
683
|
+
servers = local.get("mcpServers")
|
|
684
|
+
if isinstance(servers, dict):
|
|
685
|
+
for name in MCP_SERVERS:
|
|
686
|
+
if name in servers:
|
|
687
|
+
shadowed[name] = "local"
|
|
688
|
+
project_data, _ = _read_json_object(Path(cwd) / ".mcp.json")
|
|
689
|
+
if project_data is not None:
|
|
690
|
+
servers = project_data.get("mcpServers")
|
|
691
|
+
if isinstance(servers, dict):
|
|
692
|
+
for name in MCP_SERVERS:
|
|
693
|
+
shadowed.setdefault(name, "project")
|
|
694
|
+
return shadowed
|
|
695
|
+
|
|
696
|
+
|
|
697
|
+
def probe_mcp_registrations(wl: str) -> dict[str, Any]:
|
|
698
|
+
"""Report the user-scope registrations for the servers wlcc owns.
|
|
699
|
+
|
|
700
|
+
A missing config file reads as "no registrations" rather than an error --
|
|
701
|
+
``claude mcp add`` creates it, so the first repair must be allowed to
|
|
702
|
+
write. An unreadable file is reported through ``error`` and never
|
|
703
|
+
rewritten. ``stale`` lists the server names whose stored argv does not
|
|
704
|
+
match ``<wl> mcp serve <sub>``; ``shadowed`` names the same-name entries
|
|
705
|
+
in the local/project scopes that override the user registration.
|
|
706
|
+
"""
|
|
707
|
+
path = mcp_config_path()
|
|
708
|
+
data, error = _read_json_object(path)
|
|
709
|
+
report: dict[str, Any] = {
|
|
710
|
+
"config": str(path),
|
|
711
|
+
"servers": {},
|
|
712
|
+
"stale": [],
|
|
713
|
+
"shadowed": {},
|
|
714
|
+
"error": error,
|
|
715
|
+
}
|
|
716
|
+
if data is None:
|
|
717
|
+
return report
|
|
718
|
+
servers = data.get("mcpServers")
|
|
719
|
+
if servers is None:
|
|
720
|
+
servers = {}
|
|
721
|
+
elif not isinstance(servers, dict):
|
|
722
|
+
report["error"] = f"{path}: 'mcpServers' is not an object"
|
|
723
|
+
return report
|
|
724
|
+
for name in MCP_SERVERS:
|
|
725
|
+
entry = servers.get(name)
|
|
726
|
+
status = _registration_status(name, entry, wl)
|
|
727
|
+
report["servers"][name] = {
|
|
728
|
+
"status": status,
|
|
729
|
+
"command": entry.get("command") if isinstance(entry, dict) else None,
|
|
730
|
+
"args": entry.get("args") if isinstance(entry, dict) else None,
|
|
731
|
+
}
|
|
732
|
+
if status != "ok":
|
|
733
|
+
report["stale"].append(name)
|
|
734
|
+
report["shadowed"] = _shadowing_servers(data)
|
|
735
|
+
return report
|
|
736
|
+
|
|
737
|
+
|
|
611
738
|
def probe_mcp(host: HostContext) -> dict[str, Any]:
|
|
612
739
|
"""§3: the registration target, version stamp and interpreter visibility.
|
|
613
740
|
|
|
@@ -616,6 +743,11 @@ def probe_mcp(host: HostContext) -> dict[str, Any]:
|
|
|
616
743
|
instead of looking for a plugin-root ``mcp-tools/server.py``. The
|
|
617
744
|
interpreter probe stays a report field but can no longer gate the section
|
|
618
745
|
-- ``python`` is not part of the registered command any more.
|
|
746
|
+
|
|
747
|
+
Since #229 the version stamp is not the only evidence: the stored
|
|
748
|
+
user-scope registration is read back and compared verbatim, because a
|
|
749
|
+
payload swap that keeps the version number used to leave a dead
|
|
750
|
+
``mcp-tools/server.py`` argv behind while this section still said ``ok``.
|
|
619
751
|
"""
|
|
620
752
|
cache = _wlcc_cache(host)
|
|
621
753
|
fields: dict[str, Any] = {
|
|
@@ -625,6 +757,8 @@ def probe_mcp(host: HostContext) -> dict[str, Any]:
|
|
|
625
757
|
"plugin_root": None,
|
|
626
758
|
"rejected": False,
|
|
627
759
|
"servers": list(MCP_SERVERS),
|
|
760
|
+
"mcp_config": str(mcp_config_path()),
|
|
761
|
+
"registrations": {},
|
|
628
762
|
"wl": _probe_wl_serve(),
|
|
629
763
|
"python": _probe_python(),
|
|
630
764
|
}
|
|
@@ -655,6 +789,13 @@ def probe_mcp(host: HostContext) -> dict[str, Any]:
|
|
|
655
789
|
if not wl_state.startswith("ok:"):
|
|
656
790
|
return _result("unverifiable", _wl_reason(fields["wl"]), **fields)
|
|
657
791
|
|
|
792
|
+
registration = probe_mcp_registrations(str(fields["wl"].get("path") or ""))
|
|
793
|
+
fields["mcp_config"] = registration["config"]
|
|
794
|
+
fields["registrations"] = registration["servers"]
|
|
795
|
+
fields["shadowed"] = registration["shadowed"]
|
|
796
|
+
if registration["error"]:
|
|
797
|
+
return _result("unverifiable", registration["error"], **fields)
|
|
798
|
+
|
|
658
799
|
if registered != version:
|
|
659
800
|
return _result(
|
|
660
801
|
"dangling",
|
|
@@ -662,6 +803,25 @@ def probe_mcp(host: HostContext) -> dict[str, Any]:
|
|
|
662
803
|
"wl cc repair will re-register",
|
|
663
804
|
**fields,
|
|
664
805
|
)
|
|
806
|
+
|
|
807
|
+
if registration["shadowed"]:
|
|
808
|
+
scopes = ", ".join(
|
|
809
|
+
f"{name} ({scope})" for name, scope in registration["shadowed"].items()
|
|
810
|
+
)
|
|
811
|
+
return _result(
|
|
812
|
+
"dangling",
|
|
813
|
+
f"MCP registration shadowed by a higher scope: {scopes}; "
|
|
814
|
+
"remove the shadowing project entry manually",
|
|
815
|
+
**fields,
|
|
816
|
+
)
|
|
817
|
+
if registration["stale"]:
|
|
818
|
+
return _result(
|
|
819
|
+
"dangling",
|
|
820
|
+
"stale MCP registration for "
|
|
821
|
+
+ ", ".join(registration["stale"])
|
|
822
|
+
+ "; wl cc repair will re-register",
|
|
823
|
+
**fields,
|
|
824
|
+
)
|
|
665
825
|
return _result("ok", None, **fields)
|
|
666
826
|
|
|
667
827
|
|
|
@@ -87,11 +87,17 @@ GSTACK_REPO = "https://github.com/garrytan/gstack.git"
|
|
|
87
87
|
#: wlcc marketplace source when it is not registered yet (``/wl-upgrade`` §2).
|
|
88
88
|
WLCC_MARKETPLACE_REPO = "https://gitlab.gewinnrobo.com/Humuyuan/wlcc.git"
|
|
89
89
|
|
|
90
|
-
#: Per-server extra argv for ``claude mcp add`` (check.sh §3)
|
|
91
|
-
#:
|
|
90
|
+
#: Per-server extra argv for ``claude mcp add`` (check.sh §3), derived from
|
|
91
|
+
#: the same ``checks.MCP_SERVE_ENV`` table the registration check reads, so
|
|
92
|
+
#: the written argv and the verified argv cannot drift (#229). The GitLab
|
|
93
|
+
#: host is deliberately *not* passed: ``server.py`` owns that default (#242).
|
|
92
94
|
MCP_SERVER_EXTRA: dict[str, tuple[str, ...]] = {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
name: tuple(
|
|
96
|
+
part
|
|
97
|
+
for key, value in checks.MCP_SERVE_ENV[name]
|
|
98
|
+
for part in ("-e", f"{key}={value}")
|
|
99
|
+
)
|
|
100
|
+
for name in checks.MCP_SERVERS
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
#: How many timestamped ``settings.json`` backups are kept (hooks-drift).
|
|
@@ -494,9 +500,12 @@ def ensure_mcp() -> dict[str, Any]:
|
|
|
494
500
|
Since #228 the registered argv is ``<wl> mcp serve <sub>`` -- the plugin
|
|
495
501
|
tree's ``mcp-tools/server.py`` is neither required nor kept as a fallback.
|
|
496
502
|
A rejected plugin root or a missing/unusable ``wl`` is reported as
|
|
497
|
-
``unverifiable`` and never registered.
|
|
498
|
-
|
|
499
|
-
|
|
503
|
+
``unverifiable`` and never registered. Since #229 the idempotency latch is
|
|
504
|
+
the *pair* of the version stamp and the stored registration: a matching
|
|
505
|
+
stamp with a stale argv (same version, swapped payload) is repaired rather
|
|
506
|
+
than reported ``ok``. The stamp is written only after *both* ``claude mcp
|
|
507
|
+
add`` calls returned 0; one failure leaves the old stamp in place and the
|
|
508
|
+
next run retries.
|
|
500
509
|
"""
|
|
501
510
|
before = checks.probe_mcp(checks.load_host_context())
|
|
502
511
|
fields = _section_fields(before)
|
|
@@ -506,6 +515,17 @@ def ensure_mcp() -> dict[str, Any]:
|
|
|
506
515
|
if before["status"] == "ok":
|
|
507
516
|
return _result("ok", None, changed, **fields)
|
|
508
517
|
|
|
518
|
+
shadowed = before.get("shadowed")
|
|
519
|
+
if isinstance(shadowed, dict) and shadowed:
|
|
520
|
+
scopes = ", ".join(f"{name} ({scope})" for name, scope in shadowed.items())
|
|
521
|
+
return _result(
|
|
522
|
+
"dangling",
|
|
523
|
+
f"MCP registration shadowed by a higher scope: {scopes}; "
|
|
524
|
+
"remove the shadowing project entry manually",
|
|
525
|
+
changed,
|
|
526
|
+
**fields,
|
|
527
|
+
)
|
|
528
|
+
|
|
509
529
|
plugin_root = before.get("plugin_root")
|
|
510
530
|
if not isinstance(plugin_root, str) or not plugin_root:
|
|
511
531
|
return _result(
|
|
@@ -534,7 +554,10 @@ def ensure_mcp() -> dict[str, Any]:
|
|
|
534
554
|
for name in checks.MCP_SERVERS:
|
|
535
555
|
subcommand = checks.MCP_SERVE_ARGS[name]
|
|
536
556
|
try:
|
|
537
|
-
|
|
557
|
+
# ``-s user`` is required: without it the CLI refuses to remove
|
|
558
|
+
# when the same name also exists in the local/project scope, and
|
|
559
|
+
# the following ``add -s user`` then fails as a duplicate.
|
|
560
|
+
_run([claude, "mcp", "remove", name, "-s", "user"])
|
|
538
561
|
proc = _run(
|
|
539
562
|
[
|
|
540
563
|
claude,
|
|
@@ -74,18 +74,31 @@ def _summary_lines(
|
|
|
74
74
|
is_flag=True,
|
|
75
75
|
help="Emit one five-state JSON envelope on stdout.",
|
|
76
76
|
)
|
|
77
|
-
|
|
77
|
+
@click.option(
|
|
78
|
+
"--require",
|
|
79
|
+
"require",
|
|
80
|
+
multiple=True,
|
|
81
|
+
metavar="CAPABILITY",
|
|
82
|
+
help=(
|
|
83
|
+
"Assert a capability is available (repeatable). The consumer contract "
|
|
84
|
+
"is the capability name, not a version string; a missing or unknown "
|
|
85
|
+
"name exits 1 with status 'error'."
|
|
86
|
+
),
|
|
87
|
+
)
|
|
88
|
+
def check(as_json: bool, require: tuple[str, ...]) -> None:
|
|
78
89
|
"""Report the running wl: version, executable, platform and capabilities.
|
|
79
90
|
|
|
80
91
|
Read-only. In ``--json`` mode stdout is exactly one envelope line and
|
|
81
92
|
diagnostics go to stderr; the probe itself runs in a temporary CWD and the
|
|
82
93
|
dispatcher skips the startup ``.wl`` self-sync (#220), so the caller's
|
|
83
|
-
directory is never written to.
|
|
94
|
+
directory is never written to. ``--require`` turns the report into an
|
|
95
|
+
assertion: consumers gate on capability names, never on a version string
|
|
96
|
+
(#231).
|
|
84
97
|
"""
|
|
85
98
|
if as_json:
|
|
86
|
-
raise SystemExit(emit_check())
|
|
99
|
+
raise SystemExit(emit_check(require))
|
|
87
100
|
|
|
88
|
-
status, reason, fields = build_payload()
|
|
101
|
+
status, reason, fields = build_payload(require=require)
|
|
89
102
|
for line in _summary_lines(status, reason, fields):
|
|
90
103
|
click.echo(line)
|
|
91
104
|
raise SystemExit(exit_code(status))
|
|
@@ -15,10 +15,11 @@ commands (#220).
|
|
|
15
15
|
|
|
16
16
|
Envelope contract: ``status`` is ``ok`` for a supported interpreter,
|
|
17
17
|
``unverifiable`` when the platform matrix rejects it (unreachable for an
|
|
18
|
-
installed wl -- the wheel requires Python 3.11+), and ``error``
|
|
19
|
-
payload itself cannot be built
|
|
20
|
-
reason when unsupported; the matrix's
|
|
21
|
-
``platform_reason``, so the two keys never
|
|
18
|
+
installed wl -- the wheel requires Python 3.11+), and ``error`` when the
|
|
19
|
+
payload itself cannot be built or a ``--require`` assertion fails (#231). The
|
|
20
|
+
envelope's ``reason`` is the platform reason when unsupported; the matrix's
|
|
21
|
+
own ``reason`` is always carried as ``platform_reason``, so the two keys never
|
|
22
|
+
collide.
|
|
22
23
|
"""
|
|
23
24
|
|
|
24
25
|
from __future__ import annotations
|
|
@@ -36,7 +37,7 @@ from .envelope import OK_STATUSES, dump, exit_code
|
|
|
36
37
|
from .platform import platform_payload
|
|
37
38
|
|
|
38
39
|
if TYPE_CHECKING:
|
|
39
|
-
from collections.abc import Generator
|
|
40
|
+
from collections.abc import Generator, Sequence
|
|
40
41
|
|
|
41
42
|
#: Stable tool name in the envelope's ``tool`` key (the alias reuses it: both
|
|
42
43
|
#: commands answer the same question, so consumers key off one name).
|
|
@@ -101,15 +102,71 @@ def install_fields() -> dict[str, str]:
|
|
|
101
102
|
return {"command": INSTALL_COMMAND, "floor": INSTALL_FLOOR}
|
|
102
103
|
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
#: Reason prefixes for the ``--require`` contract (#231). A known capability
|
|
106
|
+
#: that this build does not advertise is ``no_capability:``; a name that is
|
|
107
|
+
#: not in the registry at all is ``unknown_capability:`` -- reporting a typo as
|
|
108
|
+
#: satisfied would turn one misspelling into a gate that never fails.
|
|
109
|
+
NO_CAPABILITY = "no_capability:"
|
|
110
|
+
UNKNOWN_CAPABILITY = "unknown_capability:"
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def evaluate_requirements(
|
|
114
|
+
required: Sequence[str],
|
|
115
|
+
capabilities: Sequence[str],
|
|
116
|
+
) -> tuple[str | None, list[str]]:
|
|
117
|
+
"""Evaluate ``--require`` names against the advertised capabilities (#231).
|
|
118
|
+
|
|
119
|
+
The registry (:data:`wl_cli.capabilities.CAPABILITY_SINCE`) answers "is
|
|
120
|
+
this a capability name at all"; the envelope's ``capabilities`` list
|
|
121
|
+
answers "does this build have it". A registered name that is not
|
|
122
|
+
advertised is missing (``no_capability:<names>``); an unregistered name is
|
|
123
|
+
a typo (``unknown_capability:<names>``), never a satisfied requirement.
|
|
124
|
+
|
|
125
|
+
Names are de-duplicated in request order. When both classes are present
|
|
126
|
+
the unknown names win the ``reason`` (the request itself is invalid while
|
|
127
|
+
``missing`` still carries every known-but-unavailable name), so a caller
|
|
128
|
+
fixing the payload sees the typo first.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
required: Capability names from ``--require``, in request order.
|
|
132
|
+
capabilities: The names this build advertises (the envelope payload).
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
``(reason, missing)``. ``reason`` is ``None`` when every requested
|
|
136
|
+
capability is advertised; ``missing`` is always the known-but-
|
|
137
|
+
unavailable names in request order.
|
|
138
|
+
"""
|
|
139
|
+
known = set(CAPABILITY_SINCE)
|
|
140
|
+
advertised = set(capabilities)
|
|
141
|
+
ordered = list(dict.fromkeys(required))
|
|
142
|
+
unknown = [name for name in ordered if name not in known]
|
|
143
|
+
missing = [name for name in ordered if name in known and name not in advertised]
|
|
144
|
+
if unknown:
|
|
145
|
+
return UNKNOWN_CAPABILITY + ",".join(unknown), missing
|
|
146
|
+
if missing:
|
|
147
|
+
return NO_CAPABILITY + ",".join(missing), missing
|
|
148
|
+
return None, missing
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def build_payload(
|
|
152
|
+
*, require: Sequence[str] = ()
|
|
153
|
+
) -> tuple[str, str | None, dict[str, Any]]:
|
|
105
154
|
"""Build the ``wl env check`` fields.
|
|
106
155
|
|
|
156
|
+
Args:
|
|
157
|
+
require: Capability names asserted with ``--require`` (#231). They are
|
|
158
|
+
checked against the advertised ``capabilities`` only when the
|
|
159
|
+
probe itself holds; a platform failure keeps its own status and
|
|
160
|
+
reason, as before.
|
|
161
|
+
|
|
107
162
|
Returns:
|
|
108
163
|
``(status, reason, fields)``. ``status`` is ``ok`` when the running
|
|
109
164
|
interpreter is supported, ``unverifiable`` when the shared platform
|
|
110
|
-
matrix says otherwise, and ``error``
|
|
111
|
-
|
|
112
|
-
status is not ``ok``;
|
|
165
|
+
matrix says otherwise, and ``error`` when the payload cannot be built
|
|
166
|
+
at all or a requested capability is missing/unknown. ``reason``
|
|
167
|
+
carries the readable explanation when the status is not ``ok``;
|
|
168
|
+
``fields`` is the envelope payload, with a ``missing`` list only when
|
|
169
|
+
a requested capability is known but not advertised.
|
|
113
170
|
"""
|
|
114
171
|
executable = executable_path()
|
|
115
172
|
try:
|
|
@@ -142,16 +199,39 @@ def build_payload() -> tuple[str, str | None, dict[str, Any]]:
|
|
|
142
199
|
)
|
|
143
200
|
|
|
144
201
|
if fields["supported"] is True:
|
|
145
|
-
|
|
146
|
-
|
|
202
|
+
status, reason = "ok", None
|
|
203
|
+
else:
|
|
204
|
+
status, reason = "unverifiable", platform_reason or "unsupported platform"
|
|
205
|
+
|
|
206
|
+
# Capability requirements are an assertion about a healthy probe: when the
|
|
207
|
+
# platform itself is unsupported, the platform reason is the actionable
|
|
208
|
+
# answer and stays untouched.
|
|
209
|
+
if status in OK_STATUSES and require:
|
|
210
|
+
requirement_reason, missing = evaluate_requirements(
|
|
211
|
+
require, fields["capabilities"]
|
|
212
|
+
)
|
|
213
|
+
if requirement_reason is not None:
|
|
214
|
+
status, reason = "error", requirement_reason
|
|
215
|
+
if missing:
|
|
216
|
+
fields["missing"] = missing
|
|
217
|
+
return status, reason, fields
|
|
147
218
|
|
|
148
219
|
|
|
149
|
-
def emit_check() -> int:
|
|
220
|
+
def emit_check(required: Sequence[str] = ()) -> int:
|
|
150
221
|
"""Write the ``env check`` envelope to stdout and return its exit code.
|
|
151
222
|
|
|
152
223
|
Both ``wl env check --json`` and the deprecated ``wl self capabilities
|
|
153
224
|
--json`` alias call this, so the two commands cannot answer differently.
|
|
225
|
+
``required`` carries the repeatable ``--require`` names (empty for the
|
|
226
|
+
alias, which reports rather than asserts).
|
|
227
|
+
|
|
228
|
+
Args:
|
|
229
|
+
required: Capability names the caller asserts, in request order.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
The envelope exit code: ``0`` when the probe holds and every required
|
|
233
|
+
capability is present, ``1`` otherwise.
|
|
154
234
|
"""
|
|
155
|
-
status, reason, fields = build_payload()
|
|
235
|
+
status, reason, fields = build_payload(require=required)
|
|
156
236
|
dump(status, status in OK_STATUSES, tool=TOOL, reason=reason, **fields)
|
|
157
237
|
return exit_code(status)
|
py_wlcli-0.8.1/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.8.1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{py_wlcli-0.8.1 → py_wlcli-0.8.2}/src/wl_cli/commands/buildcommands/builders/rust_builder.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|