diff --git a/CMakeLists.txt b/CMakeLists.txt
index 84ae3268..7288a1cc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1440,6 +1440,7 @@ add_executable(wowee_editor
tools/editor/cli_companions_catalog.cpp
tools/editor/cli_spell_mechanics_catalog.cpp
tools/editor/cli_keybindings_catalog.cpp
+ tools/editor/cli_tree_summary_md.cpp
tools/editor/cli_quest_objective.cpp
tools/editor/cli_quest_reward.cpp
tools/editor/cli_clone.cpp
diff --git a/tools/editor/cli_arg_required.cpp b/tools/editor/cli_arg_required.cpp
index d57e8b9a..adb6f1e6 100644
--- a/tools/editor/cli_arg_required.cpp
+++ b/tools/editor/cli_arg_required.cpp
@@ -135,7 +135,7 @@ const char* const kArgRequired[] = {
"--info-wliq", "--validate-wliq",
"--export-wliq-json", "--import-wliq-json",
"--info-magic", "--summary-dir", "--rename-by-magic",
- "--bulk-rename-by-magic", "--touch-tree",
+ "--bulk-rename-by-magic", "--touch-tree", "--tree-summary-md",
"--gen-animations", "--gen-animations-combat", "--gen-animations-movement",
"--info-wani", "--validate-wani",
"--export-wani-json", "--import-wani-json",
diff --git a/tools/editor/cli_dispatch.cpp b/tools/editor/cli_dispatch.cpp
index c6dbdfff..b55d6570 100644
--- a/tools/editor/cli_dispatch.cpp
+++ b/tools/editor/cli_dispatch.cpp
@@ -89,6 +89,7 @@
#include "cli_companions_catalog.hpp"
#include "cli_spell_mechanics_catalog.hpp"
#include "cli_keybindings_catalog.hpp"
+#include "cli_tree_summary_md.hpp"
#include "cli_quest_objective.hpp"
#include "cli_quest_reward.hpp"
#include "cli_clone.hpp"
@@ -219,6 +220,7 @@ constexpr DispatchFn kDispatchTable[] = {
handleCompanionsCatalog,
handleSpellMechanicsCatalog,
handleKeybindingsCatalog,
+ handleTreeSummaryMd,
handleQuestObjective,
handleQuestReward,
handleClone,
diff --git a/tools/editor/cli_help.cpp b/tools/editor/cli_help.cpp
index b21e5ceb..607ad528 100644
--- a/tools/editor/cli_help.cpp
+++ b/tools/editor/cli_help.cpp
@@ -1359,6 +1359,8 @@ void printUsage(const char* argv0) {
std::printf(" Apply --rename-by-magic recursively to every file in
. Conflicts are skipped without --force; exits 1 if any rename failed\n");
std::printf(" --touch-tree [--json] [--quiet]\n");
std::printf(" CI integrity check: open every recognized .w* file in , parse standard header, report PASS/FAIL + extension mismatches. Exit 1 on any failure\n");
+ std::printf(" --tree-summary-md [out.md]\n");
+ std::printf(" Emit a Markdown report of a content tree (per-format counts + per-file detail with catalog name + entry count). Stdout if no out path\n");
std::printf(" --gen-animations [name]\n");
std::printf(" Emit .wani starter: 5 essential animations (Stand / Walk / Run / Death / AttackUnarmed) with fallback chains\n");
std::printf(" --gen-animations-combat [name]\n");
diff --git a/tools/editor/cli_tree_summary_md.cpp b/tools/editor/cli_tree_summary_md.cpp
new file mode 100644
index 00000000..baf2d0ff
--- /dev/null
+++ b/tools/editor/cli_tree_summary_md.cpp
@@ -0,0 +1,196 @@
+#include "cli_tree_summary_md.hpp"
+#include "cli_arg_parse.hpp"
+#include "cli_format_table.hpp"
+
+#include
+#include
+#include
+#include
+#include
+#include