Merge pull request #437 from nubenetes/develop

🚀 Release: Agentic V2 Portal Update
This commit is contained in:
Inaki
2026-06-20 19:41:30 +02:00
committed by GitHub
5 changed files with 191 additions and 63 deletions
+5 -5
View File
@@ -142,7 +142,7 @@ Additionally, as of May 2026, Nubenetes has reached the **Platinum Operational T
| :--- | :--- |
| **Total Technical Resources (Links)** | **18647+** |
| **Specialized MD Pages** | **162** |
| **Total Commits** | **6397+** |
| **Total Commits** | **6402+** |
| **Primary AI Engine** | **Google Gemini (Agentic)** |
<!-- HEART_STATS_END -->
@@ -180,7 +180,7 @@ The growth of Nubenetes reflects the acceleration of the Cloud Native ecosystem.
| 6 | 2023 | 30 | 123 | Maintenance & Refinement |
| 7 | 2024 | 53 | 218 | Curation Strategy Pivot |
| 8 | 2025 | 5 | 20 | Stability & Research Phase |
| 9 | 2026 | 2838 | 11,720 | **Agentic AI Surge** (May 2026 Inception) |
| 9 | 2026 | 2843 | 11,741 | **Agentic AI Surge** (May 2026 Inception) |
<!-- ANNUAL_GROWTH_END -->
<!-- ANNUAL_CHART_START -->
@@ -196,8 +196,8 @@ xychart-beta
title "Nubenetes Annual Growth Metrics (20182026)"
x-axis ["2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025", "2026"]
y-axis "Volume (Commits / Estimated New Refs)" 0 --> 12000
bar [1445, 586, 8449, 2193, 1660, 123, 218, 20, 11720]
bar [350, 142, 2046, 531, 402, 30, 53, 5, 2838]
bar [1445, 586, 8449, 2193, 1660, 123, 218, 20, 11741]
bar [350, 142, 2046, 531, 402, 30, 53, 5, 2843]
```
<!-- ANNUAL_CHART_END -->
@@ -207,7 +207,7 @@ xychart-beta
| :--- | :---: | :---: | :--- |
| 2026-04 | 25 | 103 | Active Curation |
| 2026-05 | 2101 | 8,677 | **Agentic Inception (Gemini Era)** |
| 2026-06 | 712 | 2,940 | Active Curation |
| 2026-06 | 717 | 2,961 | Active Curation |
<!-- MONTHLY_SURGE_END -->
### 2.4. Content Distribution and Semantic Clustering
+1 -1
View File
@@ -7440,6 +7440,6 @@
"method": "fallback_small"
}
},
"last_updated": "2026-06-20T19:22:20.010536+02:00"
"last_updated": "2026-06-20T19:40:49.213297+02:00"
}
}
+97 -54
View File
@@ -1142,6 +1142,18 @@ class V2VisionEngine:
" - **Status**: The system is incrementally processing pending resources to complete the knowledge graph.\n"
)
# Label Heatmap for the index: identical tag aggregation to the Tags page
# (deterministic slugs), but each label deep-links across to /tags/#slug.
heat_sorted, heat_meta, _ = self._aggregate_tags(data)
index_heatmap = self._render_tag_heatmap(
heat_sorted, heat_meta, href_base="/tags/",
intro=(
"Every technical label across Nubenetes, sized by how many "
"resources carry it. Click any label to open it on the "
"[Technical Tags](/tags/) page."
),
)
index_md = (
"# Nubenetes Elite Portal (V2) | Awesome Kubernetes & Cloud [![Awesome](https://cdn.jsdelivr.net/gh/sindresorhus/awesome@d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome)\n\n"
"!!! tip \"Nubenetes V2 Elite Portal: AI-Curated & High-Density\"\n"
@@ -1220,6 +1232,9 @@ class V2VisionEngine:
f"{pulse_md}\n\n"
"## The Cloud Native Universe We Track\n\n"
f"<center markdown=\"1\">\n{mosaic_html}\n</center>\n\n"
# Label Heatmap: full tag cloud sized by resource count, deep-linking
# to the matching section on the Technical Tags page (cross-page).
f"{index_heatmap}"
"---\n\n"
"**Reference:** [🗺️ Full Topic Map](./topic-map/) · "
"[📐 Methodology &amp; Maturity Taxonomy](./methodology/) · "
@@ -1535,7 +1550,16 @@ class V2VisionEngine:
if md != existing_content:
with open(target_path, "w") as f: f.write(md)
async def _generate_global_tag_index(self, v2_structure: Dict[str, Dict]):
def _aggregate_tags(self, v2_structure: Dict[str, Dict]):
"""Collect every active resource's tags into deterministic, slug-stable
metadata shared by the Technical Tags page and the index Label Heatmap.
Returns (sorted_tags, tag_meta, by_tag) where tag_meta[tag] holds
``display``, ``slug``, ``count`` and ``kind`` (maturity | language |
domain). The slug logic is identical to (and deterministic with) what the
Tags page renders, so the heatmap on the index can deep-link to the right
``/tags/#slug`` section even though it is generated in a separate pass.
"""
active_links = {}
def collect_links(node):
if "__links__" in node:
@@ -1579,23 +1603,10 @@ class V2VisionEngine:
"[LEGACY]",
"[SPANISH CONTENT]"
]
sorted_tags = []
for st in standard_order:
if st in by_tag:
sorted_tags.append(st)
custom_tags = sorted([t for t in by_tag.keys() if t not in standard_order])
sorted_tags.extend(custom_tags)
md = (
"# Technical Tags Index\n\n"
"!!! tip \"Nubenetes V2 Elite Portal\"\n"
" You are browsing the AI-Curated V2 Elite Edition. Looking for the exhaustive list of references? Check out the [**V1 Historical Archive**](/v1/).\n\n"
"!!! info \"Universal Tag Index\"\n"
" Browse all V2 resources grouped by maturity levels and technical domains.\n\n"
)
sorted_tags = [st for st in standard_order if st in by_tag]
sorted_tags.extend(sorted(t for t in by_tag.keys() if t not in standard_order))
# Precompute display name + UNIQUE slug for every tag, shared by both the
# grouped TOC and the section headers so anchors always match. This fixes
# collisions where C / C# / C++ all slugged to "c-content" (broken links).
@@ -1618,59 +1629,91 @@ class V2VisionEngine:
_seen_slugs.add(s)
return s
def _tag_kind(tag):
if tag in standard_order:
return "maturity"
if tag.endswith("CONTENT]"):
return "language"
return "domain"
tag_meta = {
tag: {"display": _tag_display(tag), "slug": _tag_slug(tag), "count": len(by_tag[tag])}
tag: {
"display": _tag_display(tag),
"slug": _tag_slug(tag),
"count": len(by_tag[tag]),
"kind": _tag_kind(tag),
}
for tag in sorted_tags
}
return sorted_tags, tag_meta, by_tag
def _render_tag_heatmap(self, sorted_tags, tag_meta, href_base: str = "", intro: str = None) -> str:
"""Confluence-style "popular labels" Label Heatmap: every label is listed
alphabetically and sized/coloured by how many resources carry it, so the
most-used tags read biggest/warmest. Sizing uses a LOG scale because counts
span ~1..2800; a linear scale would collapse everything except the few giant
maturity tags into the smallest bucket. Six levels map onto .v2-heat-1..6.
``href_base`` is prefixed before each ``#slug`` so the same cloud can live on
the Tags page (same-page anchors, "") or the index (cross-page, "/tags/").
"""
counts = [tag_meta[t]["count"] for t in sorted_tags]
if not counts:
return ""
lmin, lmax = math.log(min(counts)), math.log(max(counts))
def _heat_level(count):
if lmax == lmin:
return 3
return 1 + round((math.log(count) - lmin) / (lmax - lmin) * 5) # 1..6
if intro is None:
intro = (
"Bigger, warmer labels cover more resources. "
"Click any label to jump to its section below."
)
md = f"## Label Heatmap\n\n{intro}\n\n"
md += '<div class="v2-tag-heatmap">\n'
for t in sorted(sorted_tags, key=lambda x: tag_meta[x]["display"].lower()):
m = tag_meta[t]
disp = m["display"].replace(" Content", "")
lvl = _heat_level(m["count"])
md += (
f'<a class="v2-heat-tag v2-heat-{lvl}" href="{href_base}#{m["slug"]}" '
f'title="{m["count"]} resources">{disp}'
f'<span class="v2-heat-n">{m["count"]}</span></a>\n'
)
md += "</div>\n\n"
return md
async def _generate_global_tag_index(self, v2_structure: Dict[str, Dict]):
sorted_tags, tag_meta, by_tag = self._aggregate_tags(v2_structure)
md = (
"# Technical Tags Index\n\n"
"!!! tip \"Nubenetes V2 Elite Portal\"\n"
" You are browsing the AI-Curated V2 Elite Edition. Looking for the exhaustive list of references? Check out the [**V1 Historical Archive**](/v1/).\n\n"
"!!! info \"Universal Tag Index\"\n"
" Browse all V2 resources grouped by maturity levels and technical domains.\n\n"
)
def _count_label(n):
return f"{n} resource" + ("" if n == 1 else "s")
# Partition custom tags: language/format ("X CONTENT") vs technical domains,
# so the long, low-signal language tail does not bury the maturity tags.
maturity_tags = [t for t in sorted_tags if t in standard_order]
maturity_tags = [t for t in sorted_tags if tag_meta[t]["kind"] == "maturity"]
lang_tags = sorted(
[t for t in sorted_tags if t not in standard_order and t.endswith("CONTENT]")],
[t for t in sorted_tags if tag_meta[t]["kind"] == "language"],
key=lambda t: -tag_meta[t]["count"],
)
other_tags = sorted(
[t for t in sorted_tags if t not in standard_order and not t.endswith("CONTENT]")],
[t for t in sorted_tags if tag_meta[t]["kind"] == "domain"],
key=lambda t: -tag_meta[t]["count"],
)
# Label Heatmap (Confluence-style "popular labels" cloud): every label is
# listed alphabetically and sized/coloured by how many resources carry it,
# so the most-used tags read biggest/warmest. Clicking jumps to the section.
# Sizing uses a LOG scale because counts span ~1..2800; a linear scale would
# collapse everything except the few giant maturity tags into the smallest
# bucket. Six levels map onto the .v2-heat-1..6 CSS ramp.
_heat_counts = [tag_meta[t]["count"] for t in sorted_tags]
if _heat_counts:
_cmin, _cmax = min(_heat_counts), max(_heat_counts)
_lmin, _lmax = math.log(_cmin), math.log(_cmax)
def _heat_level(count):
if _lmax == _lmin:
return 3
frac = (math.log(count) - _lmin) / (_lmax - _lmin)
return 1 + round(frac * 5) # 1..6
md += "## Label Heatmap\n\n"
md += (
"Bigger, warmer labels cover more resources. "
"Click any label to jump to its section below.\n\n"
)
md += '<div class="v2-tag-heatmap">\n'
for t in sorted(sorted_tags, key=lambda x: tag_meta[x]["display"].lower()):
m = tag_meta[t]
disp = m["display"].replace(" Content", "")
lvl = _heat_level(m["count"])
md += (
f'<a class="v2-heat-tag v2-heat-{lvl}" href="#{m["slug"]}" '
f'title="{m["count"]} resources">{disp}'
f'<span class="v2-heat-n">{m["count"]}</span></a>\n'
)
md += "</div>\n\n"
# Label Heatmap at the top of the Tags page (same-page anchors).
md += self._render_tag_heatmap(sorted_tags, tag_meta, href_base="")
# Build a grouped TOC: maturity as a clean numbered list; domains and the
# language/format tail as compact, count-sorted inline pill rows.
+82
View File
@@ -203,6 +203,88 @@
</div>
</center>
## Label Heatmap
Every technical label across Nubenetes, sized by how many resources carry it. Click any label to open it on the [Technical Tags](/tags/) page.
<div class="v2-tag-heatmap">
<a class="v2-heat-tag v2-heat-3" href="/tags/#agnostic-content" title="23 resources">Agnostic<span class="v2-heat-n">23</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#asciidoc-content" title="1 resources">Asciidoc<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#ballerina-content" title="1 resources">Ballerina<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-2" href="/tags/#bash-content" title="9 resources">Bash<span class="v2-heat-n">9</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#bash-yaml-content" title="1 resources">Bash/Yaml<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-2" href="/tags/#bicep-content" title="3 resources">Bicep<span class="v2-heat-n">3</span></a>
<a class="v2-heat-tag v2-heat-2" href="/tags/#c-content" title="3 resources">C<span class="v2-heat-n">3</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#c-sharp-python-js-content" title="1 resources">C# / Python / Js<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-3" href="/tags/#c-sharp-content" title="17 resources">C#<span class="v2-heat-n">17</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#c-plus-plus-go-python-content" title="1 resources">C++ / Go / Python<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#c-plus-plus-go-content" title="1 resources">C++ / Go<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#c-plus-plus-content" title="2 resources">C++<span class="v2-heat-n">2</span></a>
<a class="v2-heat-tag v2-heat-3" href="/tags/#case-study" title="39 resources">Case Study<span class="v2-heat-n">39</span></a>
<a class="v2-heat-tag v2-heat-6" href="/tags/#community-tool" title="1764 resources">Community-Tool<span class="v2-heat-n">1764</span></a>
<a class="v2-heat-tag v2-heat-3" href="/tags/#conceptual-content" title="12 resources">Conceptual<span class="v2-heat-n">12</span></a>
<a class="v2-heat-tag v2-heat-5" href="/tags/#de-facto-standard" title="323 resources">De Facto Standard<span class="v2-heat-n">323</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#docker-content" title="1 resources">Docker<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-2" href="/tags/#dockerfile-content" title="8 resources">Dockerfile<span class="v2-heat-n">8</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#elixir-content" title="1 resources">Elixir<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-3" href="/tags/#emerging" title="14 resources">Emerging<span class="v2-heat-n">14</span></a>
<a class="v2-heat-tag v2-heat-5" href="/tags/#enterprise-stable" title="366 resources">Enterprise-Stable<span class="v2-heat-n">366</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#go-javascript-content" title="2 resources">Go / Javascript<span class="v2-heat-n">2</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#go-yaml-content" title="1 resources">Go / Yaml<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-5" href="/tags/#go-content" title="320 resources">Go<span class="v2-heat-n">320</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#go-yaml-content-2" title="1 resources">Go/Yaml<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-3" href="/tags/#groovy-content" title="11 resources">Groovy<span class="v2-heat-n">11</span></a>
<a class="v2-heat-tag v2-heat-5" href="/tags/#guide" title="266 resources">Guide<span class="v2-heat-n">266</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#haskell-content" title="2 resources">Haskell<span class="v2-heat-n">2</span></a>
<a class="v2-heat-tag v2-heat-3" href="/tags/#hcl-content" title="39 resources">Hcl<span class="v2-heat-n">39</span></a>
<a class="v2-heat-tag v2-heat-2" href="/tags/#html-content" title="3 resources">Html<span class="v2-heat-n">3</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#ini-content" title="1 resources">Ini<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#java-go-node-js-content" title="1 resources">Java / Go / Node.Js<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#java-yaml-content" title="2 resources">Java / Yaml<span class="v2-heat-n">2</span></a>
<a class="v2-heat-tag v2-heat-4" href="/tags/#java-content" title="184 resources">Java<span class="v2-heat-n">184</span></a>
<a class="v2-heat-tag v2-heat-3" href="/tags/#javascript-content" title="32 resources">Javascript<span class="v2-heat-n">32</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#javascript-shell-content" title="1 resources">Javascript/Shell<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#javascript-webassembly-content" title="1 resources">Javascript/Webassembly<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#json-content" title="1 resources">Json<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#jsonnet-content" title="2 resources">Jsonnet<span class="v2-heat-n">2</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#kql-content" title="2 resources">Kql<span class="v2-heat-n">2</span></a>
<a class="v2-heat-tag v2-heat-4" href="/tags/#legacy" title="118 resources">Legacy<span class="v2-heat-n">118</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#lua-content" title="1 resources">Lua<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-4" href="/tags/#markdown-content" title="69 resources">Markdown<span class="v2-heat-n">69</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#markdown-images-content" title="1 resources">Markdown/Images<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-2" href="/tags/#node-js-content" title="3 resources">Node.Js<span class="v2-heat-n">3</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#pdf-content" title="1 resources">Pdf<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#php-content" title="1 resources">Php<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-2" href="/tags/#powershell-content" title="3 resources">Powershell<span class="v2-heat-n">3</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#promql-content" title="1 resources">Promql<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#protobuf-content" title="1 resources">Protobuf<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#python-c-plus-plus-content" title="1 resources">Python / C++<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-4" href="/tags/#python-content" title="95 resources">Python<span class="v2-heat-n">95</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#python-terraform-content" title="1 resources">Python/Terraform<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#python-yaml-content" title="1 resources">Python/Yaml<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#rego-content" title="1 resources">Rego<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#ruby-content" title="1 resources">Ruby<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-3" href="/tags/#rust-content" title="18 resources">Rust<span class="v2-heat-n">18</span></a>
<a class="v2-heat-tag v2-heat-2" href="/tags/#scala-content" title="3 resources">Scala<span class="v2-heat-n">3</span></a>
<a class="v2-heat-tag v2-heat-3" href="/tags/#shell-content" title="29 resources">Shell<span class="v2-heat-n">29</span></a>
<a class="v2-heat-tag v2-heat-3" href="/tags/#spanish-content" title="31 resources">Spanish<span class="v2-heat-n">31</span></a>
<a class="v2-heat-tag v2-heat-2" href="/tags/#sql-content" title="4 resources">Sql<span class="v2-heat-n">4</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#terraform-content" title="2 resources">Terraform<span class="v2-heat-n">2</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#terraform-yaml-content" title="1 resources">Terraform/Yaml<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#typescript-go-content" title="1 resources">Typescript / Go<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-3" href="/tags/#typescript-content" title="36 resources">Typescript<span class="v2-heat-n">36</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#typescript-elixir-content" title="1 resources">Typescript/Elixir<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#typescript-rego-content" title="1 resources">Typescript/Rego<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#yaml-c-sharp-content" title="1 resources">Yaml / C#<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#yaml-go-content" title="1 resources">Yaml / Go<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-4" href="/tags/#yaml-content" title="157 resources">Yaml<span class="v2-heat-n">157</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#yaml-bash-content" title="1 resources">Yaml/Bash<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#yaml-go-content-2" title="1 resources">Yaml/Go<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#yaml-hcl-content" title="1 resources">Yaml/Hcl<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#yaml-helm-content" title="1 resources">Yaml/Helm<span class="v2-heat-n">1</span></a>
<a class="v2-heat-tag v2-heat-1" href="/tags/#yaml-terraform-content" title="1 resources">Yaml/Terraform<span class="v2-heat-n">1</span></a>
</div>
---
**Reference:** [🗺️ Full Topic Map](./topic-map/) · [📐 Methodology &amp; Maturity Taxonomy](./methodology/) · [🎥 Agentic Video Hub](./videos/index.md)
+6 -3
View File
@@ -29,9 +29,12 @@ theme:
icon: material/shield-moon-outline
name: Switch to dark mode
features:
# navigation.tabs / .sticky disabled: 18 top-level sections overflowed
# the tab bar (horizontal scroll). The left sidebar handles them as a
# standard vertical list and stays populated on every page incl. home.
# navigation.tabs: top-level sections render as a top tab bar AND the left
# sidebar stays, scoped to the active tab. With ~16 top-level sections the
# bar can overflow on narrow viewports; Material handles that with a
# horizontal scroll, and .sticky keeps the bar pinned while scrolling.
- navigation.tabs
- navigation.tabs.sticky
- navigation.top
- navigation.tracking
# navigation.sections disabled: render top-level as COLLAPSIBLE nested