It's not shown by your example, but I suspect you want all adjacent items within a list to remain grouped. That makes it a group-adjacent problem:
Code:
<xsl:template match="list">
<xsl:for-each-group select="*" group-adjacent="node-name(.)">
<xsl:choose>
<xsl:when test="self::item">
<list><xsl:apply-templates select="current-group()"/></list>
<xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="item">
<xsl:copy-of select="."/>
</xsl:template>
I haven't handled the level numbers there, and I don't know if it does the right thing with an empty list - you didn't specify. But it's a starter.