Dynamo library tree structure for custom Dynamo Zero-Touch package

I need help with library organization in a custom Dynamo package (tree structure).

This is a sample test package I built to check how Dynamo reads categories and node organization.
I’m currently working on UI-based nodes, and for maintainability I need to keep each node’s code in its own separate .cs file — but Dynamo isn’t grouping them correctly in the library.

My Current Setup

Package name: MyTest
Environment: Revit 2025 + Dynamo 3.3
Build target: .NET 8.0 (x64)

What I Expect

In Dynamo’s library I want a clean hierarchy like this:

MyTest
 ├─ Elements
 │   ├─ Get Parameter (String)
 │   └─ Set Parameter (String)
 └─ Math
     ├─ Addition
     └─ Multiplication

:cross_mark: What I’m Actually Getting

Dynamo adds extra sub-categories based on my class names, resulting in this unwanted structure:

MyTest
 ├─ Elements
 │   ├─ GetParameterNode
 │   │   └─ GetParameter
 │   └─ SetParameterNode
 │       └─ SetParameter
 └─ Math
     ├─ AdditionNode
     │   └─ Addition
     └─ MultiplicationNode
         └─ Multiplication

How can I define my nodes so Dynamo does not create sub-folders based on class names
and the nodes appear directly under MyTest.Elements and MyTest.Math as intended —
while still keeping each node in a separate .cs file?

MyTest.csproj

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<TargetFramework>net8.0-windows</TargetFramework>
		<Platforms>x64</Platforms>
		<UseWPF>false</UseWPF>
		<AssemblyName>MyTest</AssemblyName>
		<RootNamespace>MyTest</RootNamespace>
	</PropertyGroup>

	<ItemGroup>
		<Reference Include="DynamoServices">
		  <HintPath>..\..\..\..\..\Program Files\Autodesk\Revit 2025\AddIns\DynamoForRevit\DynamoServices.dll</HintPath>
		</Reference>
		<Reference Include="ProtoGeometry">
			<HintPath>$(ProgramFiles)\Autodesk\Revit 2025\AddIns\DynamoForRevit\ProtoGeometry.dll</HintPath>
			<Private>false</Private>
		</Reference>
		<Reference Include="DynamoCore">
			<HintPath>$(ProgramFiles)\Autodesk\Revit 2025\AddIns\DynamoForRevit\DynamoCore.dll</HintPath>
			<Private>false</Private>
		</Reference>
		<Reference Include="RevitServices">
			<HintPath>$(ProgramFiles)\Autodesk\Revit 2025\AddIns\DynamoForRevit\Revit\RevitServices.dll</HintPath>
			<Private>false</Private>
		</Reference>
		<Reference Include="RevitAPI">
			<HintPath>$(ProgramFiles)\Autodesk\Revit 2025\RevitAPI.dll</HintPath>
			<Private>false</Private>
		</Reference>
		<Reference Include="RevitNodes">
			<HintPath>$(ProgramFiles)\Autodesk\Revit 2025\AddIns\DynamoForRevit\Revit\RevitNodes.dll</HintPath>
			<Private>false</Private>
		</Reference>
	</ItemGroup>

</Project>

GetParameter.cs

using Dynamo.Graph.Nodes;
using RevitServices.Persistence;
using DB = Autodesk.Revit.DB;
using RevitElement = Revit.Elements.Element;

namespace MyTest.Elements
{
    [NodeCategory("MyTest.Elements")]
    public static class GetParameterNode
    {
        [NodeName("Get Parameter (String)")]
        [NodeDescription("Returns the string value of a parameter (only for string parameters).")]
        public static string GetParameter(RevitElement element, string parameterName)
        {
            if (element == null || string.IsNullOrWhiteSpace(parameterName)) return null;

            var dbElem = element.InternalElement as DB.Element;
            if (dbElem == null) return null;

            var p = dbElem.LookupParameter(parameterName);
            if (p == null || p.StorageType != DB.StorageType.String) return null;

            return p.AsString();
        }
    }
}

SetParameter.cs

using System;
using Dynamo.Graph.Nodes;
using RevitServices.Persistence;
using DB = Autodesk.Revit.DB;
using RevitElement = Revit.Elements.Element;

namespace MyTest.Elements
{
    [NodeCategory("MyTest.Elements")]
    public static class SetParameterNode
    {
        [NodeName("Set Parameter (String)")]
        [NodeDescription("Sets the string value of a parameter (only for string parameters). Returns the same element.")]
        public static RevitElement SetParameter(RevitElement element, string parameterName, string value)
        {
            if (element == null || string.IsNullOrWhiteSpace(parameterName)) return null;

            var doc = DocumentManager.Instance.CurrentDBDocument;
            var dbElem = element.InternalElement as DB.Element;
            if (dbElem == null) return element;

            var p = dbElem.LookupParameter(parameterName);
            if (p == null || p.StorageType != DB.StorageType.String) return element;

            // Fully-qualified TransactionManager to avoid ambiguity
            RevitServices.Transactions.TransactionManager.Instance.EnsureInTransaction(doc);
            try
            {
                p.Set(value ?? string.Empty);
            }
            finally
            {
                RevitServices.Transactions.TransactionManager.Instance.TransactionTaskDone();
            }

            return element;
        }
    }
}

Addition.cs

using Dynamo.Graph.Nodes;

namespace MyTest.Math
{
    [NodeCategory("MyTest.Math")]
    public static class AdditionNode
    {
        [NodeName("Addition")]
        [NodeDescription("Adds two numbers.")]
        public static double Addition(double a, double b) => a + b;
    }
}

Multiplication.cs

using Dynamo.Graph.Nodes;

namespace MyTest.Math
{
    [NodeCategory("MyTest.Math")]
    public static class MultiplicationNode
    {
        [NodeName("Multiplication")]
        [NodeDescription("Multiplies two numbers.")]
        public static double Multiplication(double a, double b) => a * b;
    }
}