apm-cli 0.8.6__tar.gz → 0.8.7__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.
- {apm_cli-0.8.6/src/apm_cli.egg-info → apm_cli-0.8.7}/PKG-INFO +1 -1
- {apm_cli-0.8.6 → apm_cli-0.8.7}/pyproject.toml +1 -1
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/deps/__init__.py +0 -4
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/deps/_utils.py +2 -106
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/deps/cli.py +177 -38
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/install.py +119 -207
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/uninstall/engine.py +69 -76
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/deps/github_downloader.py +36 -10
- apm_cli-0.8.7/src/apm_cli/integration/agent_integrator.py +382 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/integration/base_integrator.py +83 -40
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/integration/command_integrator.py +113 -114
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/integration/hook_integrator.py +40 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/integration/instruction_integrator.py +113 -102
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/integration/prompt_integrator.py +60 -1
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/integration/skill_integrator.py +26 -17
- {apm_cli-0.8.6 → apm_cli-0.8.7/src/apm_cli.egg-info}/PKG-INFO +1 -1
- apm_cli-0.8.6/src/apm_cli/integration/agent_integrator.py +0 -487
- {apm_cli-0.8.6 → apm_cli-0.8.7}/AUTHORS +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/LICENSE +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/README.md +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/setup.cfg +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/adapters/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/adapters/client/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/adapters/client/base.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/adapters/client/codex.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/adapters/client/copilot.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/adapters/client/cursor.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/adapters/client/opencode.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/adapters/client/vscode.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/adapters/package_manager/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/adapters/package_manager/base.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/adapters/package_manager/default_manager.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/bundle/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/bundle/lockfile_enrichment.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/bundle/packer.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/bundle/plugin_exporter.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/bundle/unpacker.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/cli.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/_helpers.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/audit.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/compile/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/compile/cli.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/compile/watcher.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/config.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/init.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/list_cmd.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/mcp.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/pack.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/prune.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/run.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/runtime.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/uninstall/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/uninstall/cli.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/commands/update.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/compilation/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/compilation/agents_compiler.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/compilation/claude_formatter.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/compilation/constants.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/compilation/constitution.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/compilation/constitution_block.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/compilation/context_optimizer.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/compilation/distributed_compiler.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/compilation/injector.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/compilation/link_resolver.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/compilation/template_builder.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/config.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/constants.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/core/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/core/auth.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/core/command_logger.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/core/conflict_detector.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/core/docker_args.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/core/operations.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/core/safe_installer.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/core/script_runner.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/core/target_detection.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/core/token_manager.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/deps/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/deps/aggregator.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/deps/apm_resolver.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/deps/collection_parser.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/deps/dependency_graph.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/deps/lockfile.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/deps/package_validator.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/deps/plugin_parser.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/deps/verifier.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/drift.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/factory.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/integration/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/integration/mcp_integrator.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/integration/skill_transformer.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/integration/targets.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/integration/utils.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/models/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/models/apm_package.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/models/dependency/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/models/dependency/mcp.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/models/dependency/reference.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/models/dependency/types.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/models/plugin.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/models/results.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/models/validation.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/output/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/output/formatters.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/output/models.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/output/script_formatters.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/policy/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/policy/ci_checks.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/policy/discovery.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/policy/inheritance.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/policy/matcher.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/policy/models.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/policy/parser.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/policy/policy_checks.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/policy/schema.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/primitives/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/primitives/discovery.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/primitives/models.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/primitives/parser.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/registry/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/registry/client.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/registry/integration.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/registry/operations.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/runtime/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/runtime/base.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/runtime/codex_runtime.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/runtime/copilot_runtime.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/runtime/factory.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/runtime/llm_runtime.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/runtime/manager.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/security/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/security/audit_report.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/security/content_scanner.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/security/file_scanner.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/security/gate.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/utils/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/utils/console.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/utils/content_hash.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/utils/diagnostics.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/utils/file_ops.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/utils/github_host.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/utils/helpers.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/utils/path_security.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/utils/paths.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/utils/version_checker.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/utils/yaml_io.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/version.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/workflow/__init__.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/workflow/discovery.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/workflow/parser.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli/workflow/runner.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli.egg-info/SOURCES.txt +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli.egg-info/dependency_links.txt +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli.egg-info/entry_points.txt +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli.egg-info/requires.txt +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/src/apm_cli.egg-info/top_level.txt +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_apm_package_models.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_apm_resolver.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_codex_docker_args_fix.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_codex_empty_string_and_defaults.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_collision_integration.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_console.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_distributed_compilation.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_empty_string_and_defaults.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_enhanced_discovery.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_github_downloader.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_github_downloader_token_precedence.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_lockfile.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_runnable_prompts.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_runtime_manager_token_precedence.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_token_manager.py +0 -0
- {apm_cli-0.8.6 → apm_cli-0.8.7}/tests/test_virtual_package_multi_install.py +0 -0
|
@@ -9,8 +9,6 @@ from ._utils import (
|
|
|
9
9
|
_get_detailed_context_counts,
|
|
10
10
|
_get_package_display_info,
|
|
11
11
|
_get_detailed_package_info,
|
|
12
|
-
_update_single_package,
|
|
13
|
-
_update_all_packages,
|
|
14
12
|
)
|
|
15
13
|
|
|
16
14
|
__all__ = [
|
|
@@ -29,6 +27,4 @@ __all__ = [
|
|
|
29
27
|
"_get_detailed_context_counts",
|
|
30
28
|
"_get_package_display_info",
|
|
31
29
|
"_get_detailed_package_info",
|
|
32
|
-
"_update_single_package",
|
|
33
|
-
"_update_all_packages",
|
|
34
30
|
]
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"""Utility helpers for APM dependency commands."""
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import Any, Dict
|
|
4
|
+
from typing import Any, Dict
|
|
5
5
|
|
|
6
|
-
from ...constants import APM_DIR,
|
|
6
|
+
from ...constants import APM_DIR, APM_YML_FILENAME, SKILL_MD_FILENAME
|
|
7
7
|
from ...models.apm_package import APMPackage
|
|
8
|
-
from ...deps.github_downloader import GitHubPackageDownloader
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
def _scan_installed_packages(apm_modules_dir: Path) -> list:
|
|
@@ -221,106 +220,3 @@ def _get_detailed_package_info(package_path: Path) -> Dict[str, Any]:
|
|
|
221
220
|
'workflows': 0,
|
|
222
221
|
'hooks': 0
|
|
223
222
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
def _update_single_package(package_name: str, project_deps: List, apm_modules_path: Path, logger=None):
|
|
227
|
-
"""Update a specific package."""
|
|
228
|
-
if logger is None:
|
|
229
|
-
from ...core.command_logger import CommandLogger
|
|
230
|
-
logger = CommandLogger("deps-update")
|
|
231
|
-
|
|
232
|
-
# Find the dependency reference for this package
|
|
233
|
-
target_dep = None
|
|
234
|
-
for dep in project_deps:
|
|
235
|
-
if dep.get_display_name() == package_name or dep.repo_url.split('/')[-1] == package_name:
|
|
236
|
-
target_dep = dep
|
|
237
|
-
break
|
|
238
|
-
|
|
239
|
-
if not target_dep:
|
|
240
|
-
logger.error(f"Package '{package_name}' not found in apm.yml dependencies")
|
|
241
|
-
return
|
|
242
|
-
|
|
243
|
-
# Find the installed package directory using namespaced structure
|
|
244
|
-
# GitHub: owner/repo (2 parts)
|
|
245
|
-
# Azure DevOps: org/project/repo (3 parts)
|
|
246
|
-
package_dir = None
|
|
247
|
-
if target_dep.alias:
|
|
248
|
-
package_dir = apm_modules_path / target_dep.alias
|
|
249
|
-
else:
|
|
250
|
-
# Parse path from repo_url
|
|
251
|
-
repo_parts = target_dep.repo_url.split('/')
|
|
252
|
-
if target_dep.is_azure_devops() and len(repo_parts) >= 3:
|
|
253
|
-
# ADO structure: apm_modules/org/project/repo
|
|
254
|
-
package_dir = apm_modules_path / repo_parts[0] / repo_parts[1] / repo_parts[2]
|
|
255
|
-
elif len(repo_parts) >= 2:
|
|
256
|
-
package_dir = apm_modules_path / repo_parts[0] / repo_parts[1]
|
|
257
|
-
else:
|
|
258
|
-
# Fallback to simple name matching
|
|
259
|
-
package_dir = apm_modules_path / package_name
|
|
260
|
-
|
|
261
|
-
if not package_dir.exists():
|
|
262
|
-
logger.error(f"Package '{package_name}' not installed in apm_modules/")
|
|
263
|
-
logger.progress(f"Run 'apm install' to install it first")
|
|
264
|
-
return
|
|
265
|
-
|
|
266
|
-
try:
|
|
267
|
-
downloader = GitHubPackageDownloader()
|
|
268
|
-
logger.progress(f"Updating {target_dep.repo_url}...")
|
|
269
|
-
|
|
270
|
-
# Download latest version
|
|
271
|
-
package_info = downloader.download_package(target_dep, package_dir)
|
|
272
|
-
|
|
273
|
-
logger.success(f"Updated {target_dep.repo_url}")
|
|
274
|
-
|
|
275
|
-
except Exception as e:
|
|
276
|
-
logger.error(f"Failed to update {package_name}: {e}")
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
def _update_all_packages(project_deps: List, apm_modules_path: Path, logger=None):
|
|
280
|
-
"""Update all packages."""
|
|
281
|
-
if logger is None:
|
|
282
|
-
from ...core.command_logger import CommandLogger
|
|
283
|
-
logger = CommandLogger("deps-update")
|
|
284
|
-
|
|
285
|
-
if not project_deps:
|
|
286
|
-
logger.progress("No APM dependencies to update")
|
|
287
|
-
return
|
|
288
|
-
|
|
289
|
-
logger.start(f"Updating {len(project_deps)} APM dependencies...")
|
|
290
|
-
|
|
291
|
-
downloader = GitHubPackageDownloader()
|
|
292
|
-
updated_count = 0
|
|
293
|
-
|
|
294
|
-
for dep in project_deps:
|
|
295
|
-
# Determine package directory using namespaced structure
|
|
296
|
-
# GitHub: apm_modules/owner/repo (2 parts)
|
|
297
|
-
# Azure DevOps: apm_modules/org/project/repo (3 parts)
|
|
298
|
-
if dep.alias:
|
|
299
|
-
package_dir = apm_modules_path / dep.alias
|
|
300
|
-
else:
|
|
301
|
-
# Parse path from repo_url
|
|
302
|
-
repo_parts = dep.repo_url.split('/')
|
|
303
|
-
if dep.is_azure_devops() and len(repo_parts) >= 3:
|
|
304
|
-
# ADO structure
|
|
305
|
-
package_dir = apm_modules_path / repo_parts[0] / repo_parts[1] / repo_parts[2]
|
|
306
|
-
elif len(repo_parts) >= 2:
|
|
307
|
-
package_dir = apm_modules_path / repo_parts[0] / repo_parts[1]
|
|
308
|
-
else:
|
|
309
|
-
# Fallback to simple repo name (shouldn't happen)
|
|
310
|
-
package_dir = apm_modules_path / dep.repo_url
|
|
311
|
-
|
|
312
|
-
if not package_dir.exists():
|
|
313
|
-
logger.warning(f"{dep.repo_url} not installed - skipping")
|
|
314
|
-
continue
|
|
315
|
-
|
|
316
|
-
try:
|
|
317
|
-
logger.verbose_detail(f" Updating {dep.repo_url}...")
|
|
318
|
-
package_info = downloader.download_package(dep, package_dir)
|
|
319
|
-
updated_count += 1
|
|
320
|
-
logger.success(f" {dep.repo_url}")
|
|
321
|
-
|
|
322
|
-
except Exception as e:
|
|
323
|
-
logger.error(f" Failed to update {dep.repo_url}: {e}")
|
|
324
|
-
continue
|
|
325
|
-
|
|
326
|
-
logger.success(f"Updated {updated_count} of {len(project_deps)} packages")
|
|
@@ -11,10 +11,6 @@ from ...constants import APM_DIR, APM_MODULES_DIR, APM_YML_FILENAME, SKILL_MD_FI
|
|
|
11
11
|
from ...models.apm_package import APMPackage, ValidationResult, validate_apm_package
|
|
12
12
|
from ...core.command_logger import CommandLogger
|
|
13
13
|
|
|
14
|
-
# Import APM dependency system components (with fallback)
|
|
15
|
-
from ...deps.github_downloader import GitHubPackageDownloader
|
|
16
|
-
from ...deps.apm_resolver import APMDependencyResolver
|
|
17
|
-
|
|
18
14
|
from ._utils import (
|
|
19
15
|
_is_nested_under_package,
|
|
20
16
|
_count_primitives,
|
|
@@ -23,8 +19,6 @@ from ._utils import (
|
|
|
23
19
|
_get_detailed_context_counts,
|
|
24
20
|
_get_package_display_info,
|
|
25
21
|
_get_detailed_package_info,
|
|
26
|
-
_update_single_package,
|
|
27
|
-
_update_all_packages,
|
|
28
22
|
)
|
|
29
23
|
|
|
30
24
|
|
|
@@ -443,43 +437,188 @@ def clean(dry_run: bool, yes: bool):
|
|
|
443
437
|
sys.exit(1)
|
|
444
438
|
|
|
445
439
|
|
|
446
|
-
@deps.command(help="Update APM dependencies")
|
|
447
|
-
@click.argument(
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
440
|
+
@deps.command(help="Update APM dependencies to latest refs")
|
|
441
|
+
@click.argument("packages", nargs=-1)
|
|
442
|
+
@click.option("--verbose", "-v", is_flag=True, help="Show detailed update information")
|
|
443
|
+
@click.option(
|
|
444
|
+
"--force", is_flag=True,
|
|
445
|
+
help="Overwrite locally-authored files on collision",
|
|
446
|
+
)
|
|
447
|
+
@click.option(
|
|
448
|
+
"--target", "-t",
|
|
449
|
+
type=click.Choice(
|
|
450
|
+
["copilot", "claude", "cursor", "opencode", "vscode", "agents", "all"],
|
|
451
|
+
case_sensitive=False,
|
|
452
|
+
),
|
|
453
|
+
default=None,
|
|
454
|
+
help="Force deployment to a specific target (overrides auto-detection)",
|
|
455
|
+
)
|
|
456
|
+
@click.option(
|
|
457
|
+
"--parallel-downloads",
|
|
458
|
+
type=int,
|
|
459
|
+
default=4,
|
|
460
|
+
show_default=True,
|
|
461
|
+
help="Max concurrent package downloads (0 to disable parallelism)",
|
|
462
|
+
)
|
|
463
|
+
def update(packages, verbose, force, target, parallel_downloads):
|
|
464
|
+
"""Update APM dependencies to latest git refs.
|
|
465
|
+
|
|
466
|
+
Re-resolves git references (branches/tags) to their current SHAs,
|
|
467
|
+
downloads updated content, re-integrates primitives, and regenerates
|
|
468
|
+
the lockfile.
|
|
469
|
+
|
|
470
|
+
\b
|
|
471
|
+
Examples:
|
|
472
|
+
apm deps update # Update all packages
|
|
473
|
+
apm deps update org/repo # Update one package
|
|
474
|
+
apm deps update org/a org/b # Update specific packages
|
|
475
|
+
apm deps update --verbose # Show detailed progress
|
|
476
|
+
"""
|
|
477
|
+
from ..install import (
|
|
478
|
+
_install_apm_dependencies,
|
|
479
|
+
APM_DEPS_AVAILABLE,
|
|
480
|
+
_APM_IMPORT_ERROR,
|
|
481
|
+
)
|
|
482
|
+
from ...core.command_logger import InstallLogger
|
|
483
|
+
from ...core.auth import AuthResolver
|
|
484
|
+
|
|
485
|
+
logger = InstallLogger(verbose=verbose, partial=bool(packages))
|
|
486
|
+
|
|
487
|
+
if not APM_DEPS_AVAILABLE:
|
|
488
|
+
logger.error("APM dependency system not available")
|
|
489
|
+
if _APM_IMPORT_ERROR:
|
|
490
|
+
logger.progress(f"Import error: {_APM_IMPORT_ERROR}")
|
|
491
|
+
sys.exit(1)
|
|
492
|
+
|
|
493
|
+
project_root = Path.cwd()
|
|
494
|
+
apm_yml_path = project_root / APM_YML_FILENAME
|
|
495
|
+
|
|
496
|
+
if not apm_yml_path.exists():
|
|
497
|
+
logger.error(f"No {APM_YML_FILENAME} found in current directory")
|
|
498
|
+
sys.exit(1)
|
|
451
499
|
|
|
452
|
-
project_root = Path(".")
|
|
453
|
-
apm_modules_path = project_root / APM_MODULES_DIR
|
|
454
|
-
|
|
455
|
-
if not apm_modules_path.exists():
|
|
456
|
-
logger.progress("No apm_modules/ directory found - no packages to update")
|
|
457
|
-
return
|
|
458
|
-
|
|
459
|
-
# Get project dependencies to validate updates
|
|
460
500
|
try:
|
|
461
|
-
|
|
462
|
-
if not apm_yml_path.exists():
|
|
463
|
-
logger.error(f"No {APM_YML_FILENAME} found in current directory")
|
|
464
|
-
return
|
|
465
|
-
|
|
466
|
-
project_package = APMPackage.from_apm_yml(apm_yml_path)
|
|
467
|
-
project_deps = project_package.get_apm_dependencies()
|
|
468
|
-
|
|
469
|
-
if not project_deps:
|
|
470
|
-
logger.progress("No APM dependencies defined in apm.yml")
|
|
471
|
-
return
|
|
472
|
-
|
|
501
|
+
apm_package = APMPackage.from_apm_yml(apm_yml_path)
|
|
473
502
|
except Exception as e:
|
|
474
|
-
logger.error(f"
|
|
503
|
+
logger.error(f"Failed to parse {APM_YML_FILENAME}: {e}")
|
|
504
|
+
sys.exit(1)
|
|
505
|
+
|
|
506
|
+
all_deps = apm_package.get_apm_dependencies() + apm_package.get_dev_apm_dependencies()
|
|
507
|
+
if not all_deps:
|
|
508
|
+
logger.progress("No APM dependencies defined in apm.yml")
|
|
475
509
|
return
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
510
|
+
|
|
511
|
+
# Validate and normalize requested packages to canonical dependency keys.
|
|
512
|
+
# The install engine matches only_packages by DependencyReference identity
|
|
513
|
+
# (e.g. "owner/repo"), so short names like "compliance-rules" must be
|
|
514
|
+
# mapped to their canonical form before calling the engine.
|
|
515
|
+
only_pkgs = None
|
|
516
|
+
if packages:
|
|
517
|
+
token_to_canonical: Dict[str, str] = {}
|
|
518
|
+
for dep in all_deps:
|
|
519
|
+
canonical_key = dep.get_unique_key() or dep.repo_url or dep.get_display_name()
|
|
520
|
+
tokens = {canonical_key, dep.get_display_name(), dep.repo_url}
|
|
521
|
+
if hasattr(dep, "alias") and dep.alias:
|
|
522
|
+
tokens.add(dep.alias)
|
|
523
|
+
parts = dep.repo_url.split("/")
|
|
524
|
+
if len(parts) >= 2:
|
|
525
|
+
tokens.add(parts[-1])
|
|
526
|
+
for token in tokens:
|
|
527
|
+
if token and token not in token_to_canonical:
|
|
528
|
+
token_to_canonical[token] = canonical_key
|
|
529
|
+
|
|
530
|
+
only_pkgs = []
|
|
531
|
+
seen: Dict[str, bool] = {}
|
|
532
|
+
for pkg in packages:
|
|
533
|
+
canonical = token_to_canonical.get(pkg)
|
|
534
|
+
if not canonical:
|
|
535
|
+
available = ", ".join(dep.get_display_name() for dep in all_deps)
|
|
536
|
+
logger.error(f"Package '{pkg}' not found in {APM_YML_FILENAME}")
|
|
537
|
+
logger.progress(f"Available: {available}")
|
|
538
|
+
sys.exit(1)
|
|
539
|
+
if canonical not in seen:
|
|
540
|
+
seen[canonical] = True
|
|
541
|
+
only_pkgs.append(canonical)
|
|
542
|
+
|
|
543
|
+
# Migrate legacy lockfile first, then snapshot SHAs for before/after diff
|
|
544
|
+
from ...deps.lockfile import LockFile, get_lockfile_path, migrate_lockfile_if_needed
|
|
545
|
+
|
|
546
|
+
lockfile_path = get_lockfile_path(project_root)
|
|
547
|
+
migrate_lockfile_if_needed(project_root)
|
|
548
|
+
|
|
549
|
+
old_lockfile = LockFile.read(lockfile_path)
|
|
550
|
+
had_baseline = old_lockfile is not None
|
|
551
|
+
old_shas: dict = {}
|
|
552
|
+
if old_lockfile:
|
|
553
|
+
for key, dep in old_lockfile.dependencies.items():
|
|
554
|
+
old_shas[key] = dep.resolved_commit
|
|
555
|
+
|
|
556
|
+
auth_resolver = AuthResolver()
|
|
557
|
+
|
|
558
|
+
if packages:
|
|
559
|
+
noun = f"{len(packages)} package(s)"
|
|
560
|
+
else:
|
|
561
|
+
noun = f"all {len(all_deps)} dependencies"
|
|
562
|
+
logger.start(f"Updating {noun}...")
|
|
563
|
+
|
|
564
|
+
try:
|
|
565
|
+
install_result = _install_apm_dependencies(
|
|
566
|
+
apm_package,
|
|
567
|
+
update_refs=True,
|
|
568
|
+
verbose=verbose,
|
|
569
|
+
only_packages=only_pkgs,
|
|
570
|
+
force=force,
|
|
571
|
+
parallel_downloads=parallel_downloads,
|
|
572
|
+
logger=logger,
|
|
573
|
+
auth_resolver=auth_resolver,
|
|
574
|
+
target=target,
|
|
575
|
+
)
|
|
576
|
+
except Exception as e:
|
|
577
|
+
logger.error(f"Update failed: {e}")
|
|
578
|
+
if not verbose:
|
|
579
|
+
logger.progress("Run with --verbose for detailed diagnostics")
|
|
580
|
+
sys.exit(1)
|
|
581
|
+
|
|
582
|
+
# Show diagnostics if any
|
|
583
|
+
if install_result.diagnostics and install_result.diagnostics.has_diagnostics:
|
|
584
|
+
install_result.diagnostics.render_summary()
|
|
585
|
+
|
|
586
|
+
# Compare old vs new lockfile SHAs to show what changed
|
|
587
|
+
new_lockfile = LockFile.read(lockfile_path)
|
|
588
|
+
changed: list = []
|
|
589
|
+
if new_lockfile:
|
|
590
|
+
for key, dep in new_lockfile.dependencies.items():
|
|
591
|
+
old_sha = old_shas.get(key)
|
|
592
|
+
new_sha = dep.resolved_commit
|
|
593
|
+
if old_sha and new_sha and old_sha != new_sha:
|
|
594
|
+
changed.append(
|
|
595
|
+
(key, old_sha[:8], new_sha[:8], dep.resolved_ref or "")
|
|
596
|
+
)
|
|
597
|
+
|
|
598
|
+
error_count = 0
|
|
599
|
+
if install_result.diagnostics:
|
|
600
|
+
try:
|
|
601
|
+
error_count = int(install_result.diagnostics.error_count)
|
|
602
|
+
except (TypeError, ValueError):
|
|
603
|
+
error_count = 0
|
|
604
|
+
|
|
605
|
+
if changed:
|
|
606
|
+
pkg_noun = "package" if len(changed) == 1 else "packages"
|
|
607
|
+
if error_count > 0:
|
|
608
|
+
logger.warning(
|
|
609
|
+
f"Updated {len(changed)} {pkg_noun} with {error_count} error(s)."
|
|
610
|
+
)
|
|
611
|
+
else:
|
|
612
|
+
logger.success(f"Updated {len(changed)} {pkg_noun}:")
|
|
613
|
+
for key, old_sha, new_sha, ref in changed:
|
|
614
|
+
ref_str = f" ({ref})" if ref else ""
|
|
615
|
+
click.echo(f" {key}{ref_str}: {old_sha} -> {new_sha}")
|
|
616
|
+
elif error_count > 0:
|
|
617
|
+
logger.error(f"Update failed with {error_count} error(s).")
|
|
618
|
+
elif not had_baseline:
|
|
619
|
+
logger.success("Update complete.")
|
|
480
620
|
else:
|
|
481
|
-
|
|
482
|
-
_update_all_packages(project_deps, apm_modules_path, logger=logger)
|
|
621
|
+
logger.success("All packages already at latest refs.")
|
|
483
622
|
|
|
484
623
|
|
|
485
624
|
@deps.command(help="Show detailed package information")
|