I find this kind of input error prone, because the inner list related to an item is placed far from it.
It's possible to get what you want, but perhaps a different syntax can be better.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand\ucextensions{mm}
{
\jani_ucextensions:nn { #1 } { #2 }
}
\seq_new:N \l__jani_ucext_outer_seq
\seq_new:N \l__jani_ucext_inner_seq
\seq_new:N \l__jani_ucext_temp_seq
\int_new:N \l__jani_ucext_step_int
\cs_new_protected:Npn \jani_ucextensions:nn #1 #2
{
\seq_set_split:Nnn \l__jani_ucext_outer_seq { , } { #1 }
\seq_set_split:Nnn \l__jani_ucext_inner_seq { , } { #2 }
\int_zero:N \l__jani_ucext_step_int
\par Extensions:
\begin{enumerate}
\seq_map_inline:Nn \l__jani_ucext_outer_seq
{
\item {##1}
\int_incr:N \l__jani_ucext_step_int
\seq_set_split:Nnx \l__jani_ucext_temp_seq { , }
{ \seq_item:Nn \l__jani_ucext_inner_seq { \l__jani_ucext_step_int } }
\begin{itemize}
\item \seq_use:Nn \l__jani_ucext_temp_seq { \item }
\end{itemize}
}
\end{enumerate}
}
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\ExplSyntaxOff
\begin{document}
\ucextensions{[2.a] xyz, [5.b] abc}{{a, b, c}, {x, y}}
\end{document}
I define two sequences, storing the items in the first and second argument, split at commas.
An enumerate
environment is opened, then I do a mapping on the first sequence, using the corresponding element in the second sequence, that I again split at commas for building the inner itemize
.

A different syntax can be accommodated with a very similar macro for doing the job.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\ucextensions}{m}
{
\group_begin:
\jani_ucextensions:n { #1 }
\group_end:
}
\seq_new:N \l__jani_ucext_outer_seq
\seq_new:N \l__jani_ucext_inner_seq
\seq_new:N \l__jani_ucext_temp_seq
\int_new:N \l__jani_ucext_step_int
\keys_define:nn { jani/ucext }
{
ext .code:n = \seq_put_right:Nn \l__jani_ucext_outer_seq { #1 },
spec .code:n = \seq_put_right:Nn \l__jani_ucext_inner_seq { #1 },
}
\cs_new_protected:Npn \jani_ucextensions:n #1
{
\keys_set:nn { jani/ucext } { #1 }
\int_zero:N \l__jani_ucext_step_int
\par Extensions:
\begin{enumerate}
\seq_map_inline:Nn \l__jani_ucext_outer_seq
{
\item {##1}
\int_incr:N \l__jani_ucext_step_int
\seq_set_split:Nnx \l__jani_ucext_temp_seq { \\ }
{ \seq_item:Nn \l__jani_ucext_inner_seq { \l__jani_ucext_step_int } }
\begin{itemize}
\item \seq_use:Nn \l__jani_ucext_temp_seq { \item }
\end{itemize}
}
\end{enumerate}
}
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\ExplSyntaxOff
\begin{document}
\ucextensions{
ext = [2.a] xyz,
spec = a \\ b \\ c,
ext = [5.b] abc,
spec = x \\ y
}
\end{document}
Each extension should be followed by its specifications, so it's impossible to forget something.
The output is exactly the same.
{}
argument with comma separated values. No latex command takes a variable number of{}
arguments. (Although it is technically possible to implement that it would break all latex syntax guidelines)