diff --git a/gitea_mcp_server.py b/gitea_mcp_server.py index c960185..241b278 100644 --- a/gitea_mcp_server.py +++ b/gitea_mcp_server.py @@ -9457,35 +9457,42 @@ def gitea_resolve_task_capability( resolved_cwd = os.environ.get("GITEA_ACTIVE_WORKTREE") or PROJECT_ROOT probe_res = native_mcp_preference.probe_terminal_spawn(resolved_cwd) if not probe_res["healthy"]: - profile = get_profile() - h = host or (REMOTES.get(remote, {}).get("host") if remote in REMOTES else None) - username = _authenticated_username(h) if h else None - next_safe_action = ( - "BLOCKED + DIAGNOSE: terminal-launcher-failure " - f"({probe_res['error_type']}): {probe_res['error_msg']}. " - "Do not attempt git/pytest finalization or unsafe fallbacks. " - "Run gitea_diagnose_terminal, emit blocked-diagnose-report, and stop." + # Only block if the failure is due to a missing CWD, missing shell, or the circuit breaker is tripped. + # Other failures (like missing executable in the MCP process's limited PATH) should not block the agent's shell capability. + is_real_blocker = ( + probe_res.get("error_type") in ("missing cwd", "missing shell") + or native_mcp_preference.shell_health_status().get("hard_stopped") ) - return { - "requested_task": task, - "required_operation_permission": required_permission, - "required_role_kind": required_role, - "active_profile": profile["profile_name"], - "active_identity": username, - "active_profile_allowed_operations": profile.get("allowed_operations") or [], - "allowed_in_current_session": False, - "stop_required": True, - "infra_stop": True, - "blocked": True, - "blocked_reason": "BLOCKED + DIAGNOSE", - "terminal_launcher_unhealthy": True, - "terminal_launcher_diagnostics": probe_res, - "task_role_guidance": [next_safe_action], - "matching_configured_profile": [], - "runtime_switching_supported": gitea_config.is_runtime_switching_enabled(), - "different_mcp_namespace_required": False, - "exact_safe_next_action": next_safe_action, - } + if is_real_blocker: + profile = get_profile() + h = host or (REMOTES.get(remote, {}).get("host") if remote in REMOTES else None) + username = _authenticated_username(h) if h else None + next_safe_action = ( + "BLOCKED + DIAGNOSE: terminal-launcher-failure " + f"({probe_res['error_type']}): {probe_res['error_msg']}. " + "Do not attempt git/pytest finalization or unsafe fallbacks. " + "Run gitea_diagnose_terminal, emit blocked-diagnose-report, and stop." + ) + return { + "requested_task": task, + "required_operation_permission": required_permission, + "required_role_kind": required_role, + "active_profile": profile["profile_name"], + "active_identity": username, + "active_profile_allowed_operations": profile.get("allowed_operations") or [], + "allowed_in_current_session": False, + "stop_required": True, + "infra_stop": True, + "blocked": True, + "blocked_reason": "BLOCKED + DIAGNOSE", + "terminal_launcher_unhealthy": True, + "terminal_launcher_diagnostics": probe_res, + "task_role_guidance": [next_safe_action], + "matching_configured_profile": [], + "runtime_switching_supported": gitea_config.is_runtime_switching_enabled(), + "different_mcp_namespace_required": False, + "exact_safe_next_action": next_safe_action, + } record_preflight_check("capability", required_role, resolved_task=task)