claude-mpm 4.24.0__py3-none-any.whl → 5.4.41__py3-none-any.whl
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.
Potentially problematic release.
This version of claude-mpm might be problematic. Click here for more details.
- claude_mpm/VERSION +1 -1
- claude_mpm/__init__.py +4 -0
- claude_mpm/agents/BASE_AGENT.md +164 -0
- claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +3 -48
- claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
- claude_mpm/agents/MEMORY.md +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +735 -925
- claude_mpm/agents/WORKFLOW.md +5 -254
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +14 -48
- claude_mpm/agents/base_agent.json +7 -4
- claude_mpm/agents/frontmatter_validator.py +71 -3
- claude_mpm/agents/templates/circuit-breakers.md +1391 -0
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +48 -0
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/cli/__init__.py +37 -2
- claude_mpm/cli/__main__.py +4 -0
- claude_mpm/cli/chrome_devtools_installer.py +175 -0
- claude_mpm/cli/commands/__init__.py +2 -0
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +180 -31
- claude_mpm/cli/commands/agents.py +1116 -55
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/auto_configure.py +725 -242
- claude_mpm/cli/commands/config.py +95 -6
- claude_mpm/cli/commands/configure.py +1875 -46
- claude_mpm/cli/commands/configure_agent_display.py +29 -10
- claude_mpm/cli/commands/configure_navigation.py +63 -46
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/doctor.py +10 -2
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/local_deploy.py +1 -4
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mpm_init/core.py +229 -2
- claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
- claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
- claude_mpm/cli/commands/mpm_init/prompts.py +286 -6
- claude_mpm/cli/commands/postmortem.py +401 -0
- claude_mpm/cli/commands/profile.py +277 -0
- claude_mpm/cli/commands/run.py +123 -165
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +782 -20
- claude_mpm/cli/commands/summarize.py +413 -0
- claude_mpm/cli/executor.py +96 -3
- claude_mpm/cli/interactive/agent_wizard.py +1030 -45
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +307 -10
- claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
- claude_mpm/cli/parsers/base_parser.py +65 -0
- claude_mpm/cli/parsers/config_parser.py +162 -39
- claude_mpm/cli/parsers/profile_parser.py +148 -0
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +146 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +1280 -118
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/commands/mpm-config.md +21 -134
- claude_mpm/commands/mpm-doctor.md +16 -20
- claude_mpm/commands/mpm-help.md +13 -283
- claude_mpm/commands/mpm-init.md +88 -489
- claude_mpm/commands/mpm-monitor.md +23 -401
- claude_mpm/commands/mpm-organize.md +72 -247
- claude_mpm/commands/mpm-postmortem.md +21 -0
- claude_mpm/commands/mpm-session-resume.md +30 -0
- claude_mpm/commands/mpm-status.md +13 -68
- claude_mpm/commands/mpm-ticket-view.md +109 -0
- claude_mpm/commands/mpm-version.md +13 -106
- claude_mpm/commands/mpm.md +10 -0
- claude_mpm/config/agent_presets.py +488 -0
- claude_mpm/config/agent_sources.py +352 -0
- claude_mpm/config/skill_presets.py +392 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +13 -0
- claude_mpm/core/claude_runner.py +5 -34
- claude_mpm/core/config.py +15 -1
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/formatters/content_formatter.py +3 -13
- claude_mpm/core/framework/loaders/agent_loader.py +8 -5
- claude_mpm/core/framework/loaders/file_loader.py +54 -101
- claude_mpm/core/framework/loaders/instruction_loader.py +66 -5
- claude_mpm/core/framework_loader.py +4 -2
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +91 -10
- claude_mpm/core/logger.py +16 -1
- claude_mpm/core/oneshot_session.py +71 -8
- claude_mpm/core/optimized_startup.py +59 -0
- claude_mpm/core/output_style_manager.py +173 -43
- claude_mpm/core/protocols/__init__.py +23 -0
- claude_mpm/core/protocols/runner_protocol.py +103 -0
- claude_mpm/core/protocols/session_protocol.py +131 -0
- claude_mpm/core/shared/config_loader.py +1 -1
- claude_mpm/core/shared/singleton_manager.py +11 -4
- claude_mpm/core/socketio_pool.py +3 -3
- claude_mpm/core/system_context.py +38 -0
- claude_mpm/core/unified_agent_registry.py +134 -16
- claude_mpm/core/unified_config.py +22 -0
- claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
- claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
- claude_mpm/dashboard/static/svelte-build/index.html +36 -0
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
- claude_mpm/hooks/claude_hooks/event_handlers.py +214 -79
- claude_mpm/hooks/claude_hooks/hook_handler.py +155 -1
- claude_mpm/hooks/claude_hooks/installer.py +33 -10
- claude_mpm/hooks/claude_hooks/memory_integration.py +28 -0
- claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
- claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
- claude_mpm/hooks/claude_hooks/services/connection_manager.py +30 -6
- claude_mpm/hooks/failure_learning/__init__.py +2 -8
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
- claude_mpm/hooks/kuzu_response_hook.py +1 -5
- claude_mpm/hooks/memory_integration_hook.py +46 -1
- claude_mpm/init.py +63 -19
- claude_mpm/models/agent_definition.py +7 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +60 -20
- claude_mpm/scripts/launch_monitor.py +93 -13
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +48 -12
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_recommendation_service.py +278 -0
- claude_mpm/services/agents/agent_review_service.py +280 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/cache_git_manager.py +621 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +148 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +104 -73
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
- claude_mpm/services/agents/deployment/agent_template_builder.py +238 -15
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
- claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +422 -31
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +841 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
- claude_mpm/services/agents/git_source_manager.py +663 -0
- claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
- claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
- claude_mpm/services/agents/local_template_manager.py +50 -10
- claude_mpm/services/agents/recommender.py +5 -3
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1094 -0
- claude_mpm/services/agents/startup_sync.py +259 -0
- claude_mpm/services/agents/toolchain_detector.py +478 -0
- claude_mpm/services/analysis/__init__.py +35 -0
- claude_mpm/services/analysis/clone_detector.py +1030 -0
- claude_mpm/services/analysis/postmortem_reporter.py +474 -0
- claude_mpm/services/analysis/postmortem_service.py +765 -0
- claude_mpm/services/cli/session_pause_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +271 -6
- claude_mpm/services/core/base.py +7 -2
- claude_mpm/services/core/interfaces/__init__.py +1 -3
- claude_mpm/services/core/interfaces/health.py +1 -4
- claude_mpm/services/core/models/__init__.py +2 -11
- claude_mpm/services/diagnostics/checks/__init__.py +4 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +2 -4
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
- claude_mpm/services/event_bus/config.py +3 -1
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +579 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
- claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +3 -13
- claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
- claude_mpm/services/local_ops/health_manager.py +1 -4
- claude_mpm/services/local_ops/resource_monitor.py +1 -1
- claude_mpm/services/mcp_config_manager.py +75 -145
- claude_mpm/services/mcp_service_verifier.py +6 -3
- claude_mpm/services/model/model_router.py +1 -2
- claude_mpm/services/monitor/daemon.py +38 -11
- claude_mpm/services/monitor/daemon_manager.py +134 -21
- claude_mpm/services/monitor/management/lifecycle.py +8 -1
- claude_mpm/services/monitor/server.py +700 -24
- claude_mpm/services/pm_skills_deployer.py +676 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/profile_manager.py +331 -0
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/project_organizer.py +4 -0
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +16 -3
- claude_mpm/services/self_upgrade_service.py +120 -12
- claude_mpm/services/session_management_service.py +16 -4
- claude_mpm/services/skills/__init__.py +21 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1297 -0
- claude_mpm/services/skills/selective_skill_deployer.py +704 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +1072 -0
- claude_mpm/services/socketio/dashboard_server.py +1 -0
- claude_mpm/services/socketio/event_normalizer.py +51 -6
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +1 -1
- claude_mpm/services/socketio/server/core.py +387 -112
- claude_mpm/services/socketio/server/main.py +1 -3
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
- claude_mpm/services/unified/unified_deployment.py +1 -5
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/version_control/git_operations.py +103 -0
- claude_mpm/services/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
- claude_mpm/skills/skill_manager.py +92 -3
- claude_mpm/skills/skills_registry.py +0 -1
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/utils/agent_dependency_loader.py +91 -12
- claude_mpm/utils/agent_filters.py +261 -0
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +244 -0
- claude_mpm/utils/migration.py +372 -0
- claude_mpm/utils/progress.py +387 -0
- claude_mpm/utils/robust_installer.py +49 -7
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/METADATA +445 -122
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/RECORD +298 -503
- claude_mpm-5.4.41.dist-info/entry_points.txt +5 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE +94 -0
- claude_mpm-5.4.41.dist-info/licenses/LICENSE-FAQ.md +153 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
- claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
- claude_mpm/agents/BASE_OPS.md +0 -219
- claude_mpm/agents/BASE_PM.md +0 -468
- claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
- claude_mpm/agents/BASE_QA.md +0 -167
- claude_mpm/agents/BASE_RESEARCH.md +0 -53
- claude_mpm/agents/base_agent_loader.py +0 -626
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/agent-manager.json +0 -273
- claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
- claude_mpm/agents/templates/api_qa.json +0 -183
- claude_mpm/agents/templates/circuit_breakers.md +0 -638
- claude_mpm/agents/templates/clerk-ops.json +0 -235
- claude_mpm/agents/templates/code_analyzer.json +0 -101
- claude_mpm/agents/templates/content-agent.json +0 -358
- claude_mpm/agents/templates/dart_engineer.json +0 -307
- claude_mpm/agents/templates/data_engineer.json +0 -225
- claude_mpm/agents/templates/documentation.json +0 -238
- claude_mpm/agents/templates/engineer.json +0 -210
- claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
- claude_mpm/agents/templates/golang_engineer.json +0 -270
- claude_mpm/agents/templates/imagemagick.json +0 -264
- claude_mpm/agents/templates/java_engineer.json +0 -346
- claude_mpm/agents/templates/javascript_engineer_agent.json +0 -380
- claude_mpm/agents/templates/local_ops_agent.json +0 -1840
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/agents/templates/memory_manager.json +0 -158
- claude_mpm/agents/templates/nextjs_engineer.json +0 -285
- claude_mpm/agents/templates/ops.json +0 -185
- claude_mpm/agents/templates/php-engineer.json +0 -287
- claude_mpm/agents/templates/product_owner.json +0 -338
- claude_mpm/agents/templates/project_organizer.json +0 -144
- claude_mpm/agents/templates/prompt-engineer.json +0 -737
- claude_mpm/agents/templates/python_engineer.json +0 -387
- claude_mpm/agents/templates/qa.json +0 -243
- claude_mpm/agents/templates/react_engineer.json +0 -239
- claude_mpm/agents/templates/refactoring_engineer.json +0 -276
- claude_mpm/agents/templates/research.json +0 -188
- claude_mpm/agents/templates/ruby-engineer.json +0 -280
- claude_mpm/agents/templates/rust_engineer.json +0 -275
- claude_mpm/agents/templates/security.json +0 -202
- claude_mpm/agents/templates/svelte-engineer.json +0 -225
- claude_mpm/agents/templates/tauri_engineer.json +0 -274
- claude_mpm/agents/templates/ticketing.json +0 -178
- claude_mpm/agents/templates/typescript_engineer.json +0 -285
- claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
- claude_mpm/agents/templates/version_control.json +0 -159
- claude_mpm/agents/templates/web_qa.json +0 -400
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/cli/commands/agents_detect.py +0 -380
- claude_mpm/cli/commands/agents_recommend.py +0 -309
- claude_mpm/cli/ticket_cli.py +0 -35
- claude_mpm/commands/mpm-agents-detect.md +0 -168
- claude_mpm/commands/mpm-agents-recommend.md +0 -214
- claude_mpm/commands/mpm-agents.md +0 -122
- claude_mpm/commands/mpm-auto-configure.md +0 -269
- claude_mpm/commands/mpm-resume.md +0 -372
- claude_mpm/commands/mpm-tickets.md +0 -151
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/analysis_runner.py +0 -455
- claude_mpm/dashboard/index.html +0 -13
- claude_mpm/dashboard/open_dashboard.py +0 -66
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
- claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
- claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/built/connection-manager.js +0 -536
- claude_mpm/dashboard/static/built/dashboard.js +0 -2
- claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/built/react/events.js +0 -30
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
- claude_mpm/dashboard/static/built/shared/logger.js +0 -385
- claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/built/socket-client.js +0 -2
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/css/activity.css +0 -1958
- claude_mpm/dashboard/static/css/connection-status.css +0 -370
- claude_mpm/dashboard/static/css/dashboard.css +0 -4701
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/events.html +0 -607
- claude_mpm/dashboard/static/index.html +0 -635
- claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
- claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
- claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
- claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
- claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
- claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
- claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
- claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
- claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
- claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
- claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
- claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
- claude_mpm/dashboard/static/js/connection-manager.js +0 -536
- claude_mpm/dashboard/static/js/dashboard.js +0 -1896
- claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/js/shared/logger.js +0 -385
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/js/socket-client.js +0 -1457
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
- claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/legacy/activity.html +0 -736
- claude_mpm/dashboard/static/legacy/agents.html +0 -786
- claude_mpm/dashboard/static/legacy/files.html +0 -747
- claude_mpm/dashboard/static/legacy/tools.html +0 -831
- claude_mpm/dashboard/static/monitors.html +0 -431
- claude_mpm/dashboard/static/production/events.html +0 -659
- claude_mpm/dashboard/static/production/main.html +0 -698
- claude_mpm/dashboard/static/production/monitors.html +0 -483
- claude_mpm/dashboard/static/socket.io.min.js +0 -7
- claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
- claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
- claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
- claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/dashboard/templates/code_simple.html +0 -153
- claude_mpm/dashboard/templates/index.html +0 -606
- claude_mpm/dashboard/test_dashboard.html +0 -372
- claude_mpm/scripts/mcp_server.py +0 -75
- claude_mpm/scripts/mcp_wrapper.py +0 -39
- claude_mpm/services/mcp_gateway/__init__.py +0 -159
- claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
- claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
- claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
- claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
- claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
- claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
- claude_mpm/services/mcp_gateway/core/base.py +0 -312
- claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
- claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
- claude_mpm/services/mcp_gateway/core/process_pool.py +0 -971
- claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
- claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
- claude_mpm/services/mcp_gateway/main.py +0 -589
- claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
- claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
- claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
- claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -419
- claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -714
- claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
- claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
- claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
- claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
- claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -551
- claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
- claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
- claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
- claude_mpm-4.24.0.dist-info/entry_points.txt +0 -10
- claude_mpm-4.24.0.dist-info/licenses/LICENSE +0 -21
- /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
- /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
- /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
- /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/WHEEL +0 -0
- {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
"""ASCII Progress Bar Utility for Git Operations.
|
|
2
|
+
|
|
3
|
+
WHY: Provides visual feedback during long-running operations like agent/skill downloads
|
|
4
|
+
from Git sources. Enhances user experience with real-time progress indicators.
|
|
5
|
+
|
|
6
|
+
DESIGN DECISION: Terminal-aware progress bar with graceful degradation
|
|
7
|
+
|
|
8
|
+
Rationale: Use sys.stdout for line overwriting with \r to create animated progress bars.
|
|
9
|
+
Detect TTY environments to avoid breaking non-interactive terminals (CI/CD, pipes).
|
|
10
|
+
ASCII-based to ensure compatibility across all terminal types.
|
|
11
|
+
|
|
12
|
+
Trade-offs:
|
|
13
|
+
- Performance: Progress updates are throttled to avoid output flooding
|
|
14
|
+
- Compatibility: Works in both TTY and non-TTY modes (graceful degradation)
|
|
15
|
+
- Simplicity: Pure Python, no external dependencies (tqdm would be overkill)
|
|
16
|
+
|
|
17
|
+
Extension Points: Can be extended to support multi-line progress (parallel downloads),
|
|
18
|
+
nested progress bars, or integration with logging frameworks.
|
|
19
|
+
|
|
20
|
+
Performance:
|
|
21
|
+
- Time Complexity: O(1) for each update operation
|
|
22
|
+
- Space Complexity: O(1) - no state accumulation
|
|
23
|
+
- Expected Performance: <1ms per update, negligible overhead
|
|
24
|
+
|
|
25
|
+
Example Usage:
|
|
26
|
+
>>> with ProgressBar(total=100, prefix="Downloading") as pb:
|
|
27
|
+
... for i in range(100):
|
|
28
|
+
... time.sleep(0.01)
|
|
29
|
+
... pb.update(i + 1)
|
|
30
|
+
... # Progress bar updates automatically
|
|
31
|
+
>>> # Automatically prints completion message and newline
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
import os
|
|
35
|
+
import sys
|
|
36
|
+
import time
|
|
37
|
+
from typing import Any, Optional
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ProgressBar:
|
|
41
|
+
"""ASCII progress bar for terminal output.
|
|
42
|
+
|
|
43
|
+
Features:
|
|
44
|
+
- Animated progress bar with percentage
|
|
45
|
+
- Current/total item counter
|
|
46
|
+
- Customizable prefix message
|
|
47
|
+
- TTY detection for safe degradation
|
|
48
|
+
- Automatic terminal width detection
|
|
49
|
+
- Context manager support for cleanup
|
|
50
|
+
|
|
51
|
+
Design Decision: Use █ (U+2588) for filled sections and ░ (U+2591) for empty
|
|
52
|
+
|
|
53
|
+
Rationale: These Unicode block characters provide clear visual progress while
|
|
54
|
+
maintaining compatibility with most modern terminals. Alternative ASCII chars
|
|
55
|
+
like '#' and '-' were rejected for being less visually appealing.
|
|
56
|
+
|
|
57
|
+
Compatibility: Gracefully degrades to simple logging in non-TTY environments
|
|
58
|
+
(CI/CD, redirected output, etc.)
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
def __init__(
|
|
62
|
+
self,
|
|
63
|
+
total: int,
|
|
64
|
+
prefix: str = "Progress",
|
|
65
|
+
bar_width: int = 20,
|
|
66
|
+
show_percentage: bool = True,
|
|
67
|
+
show_counter: bool = True,
|
|
68
|
+
enabled: Optional[bool] = None,
|
|
69
|
+
):
|
|
70
|
+
"""Initialize progress bar.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
total: Total number of items to process
|
|
74
|
+
prefix: Message to display before progress bar (e.g., "Downloading")
|
|
75
|
+
bar_width: Width of the progress bar in characters (default: 20)
|
|
76
|
+
show_percentage: Show percentage complete (default: True)
|
|
77
|
+
show_counter: Show current/total counter (default: True)
|
|
78
|
+
enabled: Override TTY detection (None = auto-detect, True = always show, False = disable)
|
|
79
|
+
|
|
80
|
+
Example:
|
|
81
|
+
>>> pb = ProgressBar(100, prefix="Syncing agents", bar_width=30)
|
|
82
|
+
>>> pb.update(50, message="agent.md")
|
|
83
|
+
>>> # Displays: Syncing agents [███████████████░░░░░░░░░░░░░░░] 50% (50/100) agent.md
|
|
84
|
+
"""
|
|
85
|
+
self.total = total
|
|
86
|
+
self.prefix = prefix
|
|
87
|
+
self.bar_width = bar_width
|
|
88
|
+
self.show_percentage = show_percentage
|
|
89
|
+
self.show_counter = show_counter
|
|
90
|
+
self.current = 0
|
|
91
|
+
self.start_time = time.time()
|
|
92
|
+
self.last_update_time = 0.0
|
|
93
|
+
self.update_throttle = (
|
|
94
|
+
0.1 # Minimum seconds between updates (throttle to 10 Hz)
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Auto-detect TTY unless explicitly overridden
|
|
98
|
+
if enabled is None:
|
|
99
|
+
self.enabled = self._is_tty()
|
|
100
|
+
else:
|
|
101
|
+
self.enabled = enabled
|
|
102
|
+
|
|
103
|
+
# Terminal width detection for preventing overflow
|
|
104
|
+
self.terminal_width = self._get_terminal_width()
|
|
105
|
+
|
|
106
|
+
def _is_tty(self) -> bool:
|
|
107
|
+
"""Check if stdout is a TTY (interactive terminal).
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
True if stdout is a TTY, False otherwise (e.g., piped, redirected)
|
|
111
|
+
|
|
112
|
+
Design Decision: Disable progress bars in non-TTY environments
|
|
113
|
+
|
|
114
|
+
Rationale: Progress bars use \r (carriage return) for line overwriting,
|
|
115
|
+
which appears as garbage in log files, CI/CD output, and piped commands.
|
|
116
|
+
Detecting TTY ensures clean output in all contexts.
|
|
117
|
+
|
|
118
|
+
Example:
|
|
119
|
+
$ python script.py # TTY - progress bars enabled
|
|
120
|
+
$ python script.py > log.txt # Non-TTY - simple logging
|
|
121
|
+
$ python script.py | grep foo # Non-TTY - simple logging
|
|
122
|
+
"""
|
|
123
|
+
try:
|
|
124
|
+
return sys.stdout.isatty()
|
|
125
|
+
except AttributeError:
|
|
126
|
+
# sys.stdout might not have isatty() in some environments
|
|
127
|
+
return False
|
|
128
|
+
|
|
129
|
+
def _get_terminal_width(self) -> int:
|
|
130
|
+
"""Get terminal width for preventing line overflow.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
Terminal width in characters (default: 80 if detection fails)
|
|
134
|
+
|
|
135
|
+
Error Handling:
|
|
136
|
+
- OSError: Returns 80 (standard terminal width)
|
|
137
|
+
- AttributeError: Returns 80 (fallback)
|
|
138
|
+
- ValueError: Returns 80 (invalid terminal size)
|
|
139
|
+
"""
|
|
140
|
+
try:
|
|
141
|
+
# Try to get terminal size from os module (Python 3.3+)
|
|
142
|
+
size = os.get_terminal_size()
|
|
143
|
+
return size.columns
|
|
144
|
+
except (OSError, AttributeError, ValueError):
|
|
145
|
+
# Fallback to standard terminal width
|
|
146
|
+
return 80
|
|
147
|
+
|
|
148
|
+
def update(self, current: int, message: str = "") -> None:
|
|
149
|
+
"""Update progress bar to current position.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
current: Current progress value (0 to total)
|
|
153
|
+
message: Optional message to display after progress bar (e.g., filename)
|
|
154
|
+
|
|
155
|
+
Performance: Updates are throttled to 10 Hz to avoid output flooding.
|
|
156
|
+
Non-TTY mode: Logs milestone updates (0%, 25%, 50%, 75%, 100%) instead of every update.
|
|
157
|
+
|
|
158
|
+
Example:
|
|
159
|
+
>>> pb = ProgressBar(10, prefix="Downloading")
|
|
160
|
+
>>> for i in range(10):
|
|
161
|
+
... pb.update(i + 1, message=f"file_{i}.md")
|
|
162
|
+
>>> # Progress bar updates in-place, then prints completion
|
|
163
|
+
"""
|
|
164
|
+
self.current = min(current, self.total) # Clamp to total
|
|
165
|
+
|
|
166
|
+
# Throttle updates to avoid flooding terminal
|
|
167
|
+
current_time = time.time()
|
|
168
|
+
if (
|
|
169
|
+
current_time - self.last_update_time < self.update_throttle
|
|
170
|
+
and current < self.total
|
|
171
|
+
):
|
|
172
|
+
return # Skip update, too soon since last one
|
|
173
|
+
|
|
174
|
+
self.last_update_time = current_time
|
|
175
|
+
|
|
176
|
+
if not self.enabled:
|
|
177
|
+
# Non-TTY mode: Log milestone updates only
|
|
178
|
+
self._log_milestone(message)
|
|
179
|
+
return
|
|
180
|
+
|
|
181
|
+
# TTY mode: Render and display progress bar
|
|
182
|
+
self._render_progress_bar(message)
|
|
183
|
+
|
|
184
|
+
def _log_milestone(self, message: str) -> None:
|
|
185
|
+
"""Log progress at milestone percentages in non-TTY mode.
|
|
186
|
+
|
|
187
|
+
Milestones: 0%, 25%, 50%, 75%, 100%
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
message: Optional message to include in log
|
|
191
|
+
|
|
192
|
+
Design Decision: Log milestones instead of every update in non-TTY
|
|
193
|
+
|
|
194
|
+
Rationale: Avoids flooding logs with hundreds of progress lines while
|
|
195
|
+
still providing useful feedback. Rejected logging every update because
|
|
196
|
+
it creates noise in CI/CD logs and log files.
|
|
197
|
+
|
|
198
|
+
Respects show_percentage and show_counter settings for consistent output
|
|
199
|
+
across TTY and non-TTY modes.
|
|
200
|
+
"""
|
|
201
|
+
percentage = int((self.current / self.total) * 100) if self.total > 0 else 0
|
|
202
|
+
|
|
203
|
+
# Log at milestones: 0%, 25%, 50%, 75%, 100%
|
|
204
|
+
milestones = [0, 25, 50, 75, 100]
|
|
205
|
+
if percentage in milestones or self.current == self.total:
|
|
206
|
+
# Build output respecting show_percentage and show_counter settings
|
|
207
|
+
if message and not (self.show_counter or self.show_percentage):
|
|
208
|
+
# Simple format: "Prefix: message"
|
|
209
|
+
output = f"{self.prefix}: {message}"
|
|
210
|
+
else:
|
|
211
|
+
# Complex format with counter/percentage
|
|
212
|
+
parts = [self.prefix]
|
|
213
|
+
|
|
214
|
+
if self.show_counter:
|
|
215
|
+
parts.append(f"{self.current}/{self.total}")
|
|
216
|
+
|
|
217
|
+
if self.show_percentage:
|
|
218
|
+
parts.append(f"({percentage}%)")
|
|
219
|
+
|
|
220
|
+
if message:
|
|
221
|
+
parts.append(f"- {message}")
|
|
222
|
+
|
|
223
|
+
output = " ".join(parts)
|
|
224
|
+
|
|
225
|
+
print(output, flush=True)
|
|
226
|
+
|
|
227
|
+
def _render_progress_bar(self, message: str) -> None:
|
|
228
|
+
"""Render and display progress bar in TTY mode.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
message: Optional message to display after progress bar
|
|
232
|
+
|
|
233
|
+
Output Format:
|
|
234
|
+
[Prefix] [████████░░░░░░░░░░░░] XX% (current/total) message
|
|
235
|
+
|
|
236
|
+
Design Decision: Use \r to overwrite same line for animation effect
|
|
237
|
+
|
|
238
|
+
Rationale: Creates smooth animation by updating the same line instead
|
|
239
|
+
of printing new lines. Requires TTY for proper display (hence TTY check).
|
|
240
|
+
|
|
241
|
+
Terminal Width Handling:
|
|
242
|
+
- Calculates available space based on terminal width
|
|
243
|
+
- Truncates message if output would overflow
|
|
244
|
+
- Ensures progress bar always fits on one line
|
|
245
|
+
"""
|
|
246
|
+
percentage = int((self.current / self.total) * 100) if self.total > 0 else 0
|
|
247
|
+
filled = (
|
|
248
|
+
int(self.bar_width * self.current / self.total) if self.total > 0 else 0
|
|
249
|
+
)
|
|
250
|
+
bar = "█" * filled + "░" * (self.bar_width - filled)
|
|
251
|
+
|
|
252
|
+
# Build output components
|
|
253
|
+
parts = [f"{self.prefix} [{bar}]"]
|
|
254
|
+
|
|
255
|
+
if self.show_percentage:
|
|
256
|
+
parts.append(f"{percentage}%")
|
|
257
|
+
|
|
258
|
+
if self.show_counter:
|
|
259
|
+
parts.append(f"({self.current}/{self.total})")
|
|
260
|
+
|
|
261
|
+
if message:
|
|
262
|
+
parts.append(message)
|
|
263
|
+
|
|
264
|
+
output = " ".join(parts)
|
|
265
|
+
|
|
266
|
+
# Truncate if exceeds terminal width (leave 2 chars margin)
|
|
267
|
+
max_width = self.terminal_width - 2
|
|
268
|
+
if len(output) > max_width:
|
|
269
|
+
# Truncate message part, preserve progress bar
|
|
270
|
+
truncate_at = max_width - 3 # Leave room for "..."
|
|
271
|
+
output = output[:truncate_at] + "..."
|
|
272
|
+
|
|
273
|
+
# Pad output to terminal width to clear previous longer text
|
|
274
|
+
# This prevents text artifacts when current message is shorter than previous
|
|
275
|
+
padded_output = output.ljust(max_width)
|
|
276
|
+
|
|
277
|
+
# Write to stdout with carriage return (overwrite current line)
|
|
278
|
+
sys.stdout.write(f"\r{padded_output}")
|
|
279
|
+
sys.stdout.flush()
|
|
280
|
+
|
|
281
|
+
def finish(self, message: str = "Complete") -> None:
|
|
282
|
+
"""Complete progress bar and print final message.
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
message: Final message to display (default: "Complete")
|
|
286
|
+
|
|
287
|
+
Design Decision: Print newline after completion to prevent terminal corruption
|
|
288
|
+
|
|
289
|
+
Rationale: Without newline, next shell prompt or log message would
|
|
290
|
+
overwrite the final progress bar state. Explicit finish() ensures
|
|
291
|
+
clean terminal output.
|
|
292
|
+
|
|
293
|
+
Bug Fix: Avoid duplicate completion messages in non-TTY mode by not
|
|
294
|
+
calling update() again if already at 100%. The final milestone was
|
|
295
|
+
already logged during the last update() call.
|
|
296
|
+
|
|
297
|
+
Example:
|
|
298
|
+
>>> pb = ProgressBar(100)
|
|
299
|
+
>>> pb.update(100)
|
|
300
|
+
>>> pb.finish(message="Download complete")
|
|
301
|
+
>>> # Output: [████████████████████] 100% (100/100) Download complete
|
|
302
|
+
"""
|
|
303
|
+
if self.enabled:
|
|
304
|
+
# TTY mode: Update to show final message, then add newline
|
|
305
|
+
self.update(self.total, message=message)
|
|
306
|
+
sys.stdout.write("\n")
|
|
307
|
+
sys.stdout.flush()
|
|
308
|
+
# Non-TTY mode: Only log if not already at 100%
|
|
309
|
+
# If already at 100%, _log_milestone() already printed during last update()
|
|
310
|
+
elif self.current < self.total:
|
|
311
|
+
self.update(self.total, message=message)
|
|
312
|
+
|
|
313
|
+
def __enter__(self) -> "ProgressBar":
|
|
314
|
+
"""Context manager entry.
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
Self for use in with statements
|
|
318
|
+
|
|
319
|
+
Example:
|
|
320
|
+
>>> with ProgressBar(100, prefix="Processing") as pb:
|
|
321
|
+
... for i in range(100):
|
|
322
|
+
... pb.update(i + 1)
|
|
323
|
+
>>> # Automatically calls finish() on exit
|
|
324
|
+
"""
|
|
325
|
+
return self
|
|
326
|
+
|
|
327
|
+
def __exit__(
|
|
328
|
+
self,
|
|
329
|
+
exc_type: Optional[type],
|
|
330
|
+
exc_val: Optional[BaseException],
|
|
331
|
+
exc_tb: Optional[Any],
|
|
332
|
+
) -> None:
|
|
333
|
+
"""Context manager exit - ensures finish() is called.
|
|
334
|
+
|
|
335
|
+
Args:
|
|
336
|
+
exc_type: Exception type (if raised)
|
|
337
|
+
exc_val: Exception value (if raised)
|
|
338
|
+
exc_tb: Exception traceback (if raised)
|
|
339
|
+
|
|
340
|
+
Error Handling:
|
|
341
|
+
- Calls finish() even if exception occurred
|
|
342
|
+
- Displays "Failed" message if exception raised
|
|
343
|
+
- Re-raises exception after cleanup
|
|
344
|
+
|
|
345
|
+
Returns:
|
|
346
|
+
None (does not suppress exceptions)
|
|
347
|
+
"""
|
|
348
|
+
if exc_type is not None:
|
|
349
|
+
# Exception occurred - finish with error message
|
|
350
|
+
self.finish(message="Failed")
|
|
351
|
+
else:
|
|
352
|
+
# Normal completion
|
|
353
|
+
self.finish()
|
|
354
|
+
|
|
355
|
+
# Don't suppress exceptions (returning None is equivalent to returning False)
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
# Convenience function for simple use cases
|
|
359
|
+
def create_progress_bar(
|
|
360
|
+
total: int,
|
|
361
|
+
prefix: str = "Progress",
|
|
362
|
+
enabled: Optional[bool] = None,
|
|
363
|
+
) -> ProgressBar:
|
|
364
|
+
"""Create a progress bar with sensible defaults.
|
|
365
|
+
|
|
366
|
+
Args:
|
|
367
|
+
total: Total number of items
|
|
368
|
+
prefix: Progress message
|
|
369
|
+
enabled: Override TTY detection (None = auto)
|
|
370
|
+
|
|
371
|
+
Returns:
|
|
372
|
+
Configured ProgressBar instance
|
|
373
|
+
|
|
374
|
+
Example:
|
|
375
|
+
>>> pb = create_progress_bar(100, "Downloading agents")
|
|
376
|
+
>>> for i in range(100):
|
|
377
|
+
... pb.update(i + 1, message=f"agent_{i}.md")
|
|
378
|
+
>>> pb.finish()
|
|
379
|
+
"""
|
|
380
|
+
return ProgressBar(
|
|
381
|
+
total=total,
|
|
382
|
+
prefix=prefix,
|
|
383
|
+
bar_width=20,
|
|
384
|
+
show_percentage=True,
|
|
385
|
+
show_counter=True,
|
|
386
|
+
enabled=enabled,
|
|
387
|
+
)
|
|
@@ -82,6 +82,7 @@ class RobustPackageInstaller:
|
|
|
82
82
|
self.attempts: List[InstallAttempt] = []
|
|
83
83
|
self.success_cache: Dict[str, bool] = {}
|
|
84
84
|
self.in_virtualenv = self._check_virtualenv()
|
|
85
|
+
self.is_uv_tool = self._check_uv_tool_installation()
|
|
85
86
|
self.is_pep668_managed = self._check_pep668_managed()
|
|
86
87
|
self.pep668_warning_shown = False
|
|
87
88
|
|
|
@@ -218,8 +219,7 @@ class RobustPackageInstaller:
|
|
|
218
219
|
return (
|
|
219
220
|
(
|
|
220
221
|
# venv creates sys.base_prefix
|
|
221
|
-
hasattr(sys, "base_prefix")
|
|
222
|
-
and sys.base_prefix != sys.prefix
|
|
222
|
+
hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix
|
|
223
223
|
)
|
|
224
224
|
or (
|
|
225
225
|
# virtualenv creates sys.real_prefix
|
|
@@ -227,8 +227,7 @@ class RobustPackageInstaller:
|
|
|
227
227
|
)
|
|
228
228
|
or (
|
|
229
229
|
# VIRTUAL_ENV environment variable
|
|
230
|
-
os.environ.get("VIRTUAL_ENV")
|
|
231
|
-
is not None
|
|
230
|
+
os.environ.get("VIRTUAL_ENV") is not None
|
|
232
231
|
)
|
|
233
232
|
)
|
|
234
233
|
|
|
@@ -263,6 +262,36 @@ class RobustPackageInstaller:
|
|
|
263
262
|
|
|
264
263
|
return False
|
|
265
264
|
|
|
265
|
+
def _check_uv_tool_installation(self) -> bool:
|
|
266
|
+
"""
|
|
267
|
+
Check if running in UV tool environment (no pip available).
|
|
268
|
+
|
|
269
|
+
WHY: UV tool environments don't have pip installed. The executable
|
|
270
|
+
path typically contains ".local/share/uv/tools/" and the UV_TOOL_DIR
|
|
271
|
+
environment variable is set. In such environments, we need to use
|
|
272
|
+
'uv pip' instead of 'python -m pip'.
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
True if UV tool environment, False otherwise
|
|
276
|
+
"""
|
|
277
|
+
import os
|
|
278
|
+
|
|
279
|
+
# Check UV_TOOL_DIR environment variable
|
|
280
|
+
uv_tool_dir = os.environ.get("UV_TOOL_DIR", "")
|
|
281
|
+
if uv_tool_dir and "claude-mpm" in uv_tool_dir:
|
|
282
|
+
logger.debug(f"UV tool environment detected via UV_TOOL_DIR: {uv_tool_dir}")
|
|
283
|
+
return True
|
|
284
|
+
|
|
285
|
+
# Check executable path for UV tool patterns
|
|
286
|
+
executable = sys.executable
|
|
287
|
+
if ".local/share/uv/tools/" in executable or "/uv/tools/" in executable:
|
|
288
|
+
logger.debug(
|
|
289
|
+
f"UV tool environment detected via executable path: {executable}"
|
|
290
|
+
)
|
|
291
|
+
return True
|
|
292
|
+
|
|
293
|
+
return False
|
|
294
|
+
|
|
266
295
|
def _show_pep668_warning(self) -> None:
|
|
267
296
|
"""
|
|
268
297
|
Show warning about PEP 668 managed environment.
|
|
@@ -303,7 +332,12 @@ class RobustPackageInstaller:
|
|
|
303
332
|
Returns:
|
|
304
333
|
Command as list of arguments
|
|
305
334
|
"""
|
|
306
|
-
|
|
335
|
+
# UV tool environments don't have pip; use uv pip instead
|
|
336
|
+
if self.is_uv_tool:
|
|
337
|
+
base_cmd = ["uv", "pip", "install"]
|
|
338
|
+
logger.debug("Using 'uv pip install' for UV tool environment")
|
|
339
|
+
else:
|
|
340
|
+
base_cmd = [sys.executable, "-m", "pip", "install"]
|
|
307
341
|
|
|
308
342
|
# Determine appropriate flags based on environment
|
|
309
343
|
if self.in_virtualenv:
|
|
@@ -653,7 +687,12 @@ class RobustPackageInstaller:
|
|
|
653
687
|
Tuple of (success, error_message)
|
|
654
688
|
"""
|
|
655
689
|
try:
|
|
656
|
-
|
|
690
|
+
# UV tool environments don't have pip; use uv pip instead
|
|
691
|
+
if self.is_uv_tool:
|
|
692
|
+
cmd = ["uv", "pip", "install"]
|
|
693
|
+
logger.debug("Using 'uv pip install' for batch installation")
|
|
694
|
+
else:
|
|
695
|
+
cmd = [sys.executable, "-m", "pip", "install"]
|
|
657
696
|
|
|
658
697
|
# Add appropriate flags based on environment
|
|
659
698
|
if self.in_virtualenv:
|
|
@@ -704,7 +743,10 @@ class RobustPackageInstaller:
|
|
|
704
743
|
|
|
705
744
|
# Add environment status
|
|
706
745
|
lines.append("")
|
|
707
|
-
if self.
|
|
746
|
+
if self.is_uv_tool:
|
|
747
|
+
lines.append("✓ Environment: UV Tool Environment")
|
|
748
|
+
lines.append(" Using 'uv pip' command (pip not available)")
|
|
749
|
+
elif self.in_virtualenv:
|
|
708
750
|
lines.append("✓ Environment: Virtual Environment (isolated)")
|
|
709
751
|
lines.append(" No special pip flags needed")
|
|
710
752
|
elif self.is_pep668_managed:
|