Why does expansion sometimes echos the braces and sometimes don't?

$ echo --hidden-import={a,b}
--hidden-import=a --hidden-import=b

as compared to

echo --hidden-import={$FILES}
--hidden-import={cpu_mon disk_mon mem_mon network_mon}

Where FILES was created by

export FILES=$(ls)

In the example I expected to get

--hidden-import=cpu_mon --hidden-import==disk_mon --hidden-import==mem_mon --hidden-import==network_mon

Brace expansion happens before variable expansion. If you have {$x,$y} the shell first processes it into two arguments $x and $y, and only then expands the variables within each argument separately. And if you have only one item, brace expansion doesn't happen at all; {xy} always remains just {xy}.

If you're writing for Bash, use arrays and parameter expansion instead:

files=(*)
echo "${files[@]/#/--hidden-import=}"

Here the # in ${var/#match/replacement} makes it replace the (zero-length) matching string only at the beginning of the variable. Also note the usage of files[@] to get all elements of the array instead of just the first one.

If that doesn't work, just build the argument list using a loop:

args=()
for file in *; do
    args+=("--hidden-import=$file")
done
echo "${args[@]}"

Alternatively, Bash's printf can be used to add prefixes/suffixes to multiple arguments at once:

printf '--hidden-import=%s\n' * | xargs -d '\n' echo

In the worst case (if you have no Bash and you've ruled out all alternative CLI scripting languages such as Perl or Python or even PHP), try sed:

\ls | sed "s/^/--hidden-import=/" | xargs -d '\n' echo

(Deliberate backslash to bypass aliases such as 'ls -F'.)