diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 0e758696..d152d3b4 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,7 +3,7 @@ ## Onboarding type -- [ ] New product onboarding (`components.yml` entry) +- [ ] New product onboarding (new `components.d/.yml` file) - [ ] Other (catalog change, README fix, infrastructure, etc.) ## For new product onboarding — author affirmations @@ -14,14 +14,14 @@ By submitting this PR, I confirm on behalf of my team: - [ ] **License selected:** Apache 2.0 / CC-BY 4.0 / Dual (Apache 2.0 + CC-BY 4.0). Specify: _____ - [ ] **No new license or new third-party component** introduced beyond what the source repo already carries - [ ] **Source repo is public and under an NVIDIA-owned GitHub org** -- [ ] `.agents/skills/` or `skills/` path used for new entries (or existing path retained for legacy entries per `components.yml`) +- [ ] `.agents/skills/` or `skills/` path used for new entries (or existing path retained for legacy entries per `components.d/.yml`) > NVIDIA contributors: see the internal onboarding guide for the IP review process details and license selection. ## Reviewer checklist (OSS Skills PIC) - [ ] Author confirmations above are checked -- [ ] `components.yml` entry valid (required fields, unique `catalog_dir`, path exists in source repo) +- [ ] `components.d/.yml` entry valid (required fields, unique `catalog_dir`, path exists in source repo, filename slug matches name) - [ ] `SKILL.md` frontmatter spec-compliant (at least one sampled) - [ ] No new license or third-party dependency requiring OSRB filing diff --git a/.github/scripts/regenerate-readme.sh b/.github/scripts/regenerate-readme.sh index 4981fbf8..d3b98ce4 100755 --- a/.github/scripts/regenerate-readme.sh +++ b/.github/scripts/regenerate-readme.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash # Regenerate the README's Available Skills and Getting Help & Contributing -# tables from components.yml. Used by the sync-skills workflow; can also +# tables from components.d/*.yml. Used by the sync-skills workflow; can also # be run locally to preview the result. # # Reads: -# components.yml — component catalog (source of truth) +# components.d/*.yml — per-component catalog files (source of truth) # skills// — to count SKILL.md files per component # /tmp/sync-versions.txt — optional, populated by the sync workflow with # upstream short SHA, full SHA, and committer @@ -22,20 +22,25 @@ cd "$(git rev-parse --show-toplevel)" VERSIONS_FILE="${VERSIONS_FILE:-/tmp/sync-versions.txt}" -sorted_indices=$(yq -r '.components | to_entries | sort_by(.value.name | downcase) | .[].key' components.yml) +# Aggregate per-component files into a single config so the existing +# yq queries can index into a flat .components list. +CONFIG=/tmp/components.aggregated.yml +yq ea '[.] | {"components": .}' components.d/*.yml > "$CONFIG" + +sorted_indices=$(yq -r '.components | to_entries | sort_by(.value.name | downcase) | .[].key' "$CONFIG") # Available Skills table { echo "| Product | Description | Skills | Catalog | Source | Version |" echo "|---------|-------------|:------:|---------|--------|---------|" for i in $sorted_indices; do - name=$(yq -r ".components[$i].name" components.yml) - description=$(yq -r ".components[$i].description" components.yml | tr -d '\n' | sed 's/ */ /g; s/^ //; s/ $//') - repo=$(yq -r ".components[$i].repo" components.yml) - ref=$(yq -r ".components[$i].ref // \"main\"" components.yml) - primary_path=$(yq -r ".components[$i].skills[0].path" components.yml) + name=$(yq -r ".components[$i].name" "$CONFIG") + description=$(yq -r ".components[$i].description" "$CONFIG" | tr -d '\n' | sed 's/ */ /g; s/^ //; s/ $//') + repo=$(yq -r ".components[$i].repo" "$CONFIG") + ref=$(yq -r ".components[$i].ref // \"main\"" "$CONFIG") + primary_path=$(yq -r ".components[$i].skills[0].path" "$CONFIG") primary_path=${primary_path%/} - primary_catalog=$(yq -r ".components[$i].skills[0].catalog_dir" components.yml) + primary_catalog=$(yq -r ".components[$i].skills[0].catalog_dir" "$CONFIG") skill_count=0 while read -r catalog_dir; do @@ -43,7 +48,7 @@ sorted_indices=$(yq -r '.components | to_entries | sort_by(.value.name | downcas cnt=$(find "skills/$catalog_dir" -name SKILL.md -type f 2>/dev/null | wc -l | tr -d ' ') skill_count=$((skill_count + cnt)) fi - done < <(yq -r ".components[$i].skills[].catalog_dir" components.yml) + done < <(yq -r ".components[$i].skills[].catalog_dir" "$CONFIG") slug=$(echo "$name" | tr 'A-Z ' 'a-z-') version_cell="—" @@ -64,12 +69,12 @@ sorted_indices=$(yq -r '.components | to_entries | sort_by(.value.name | downcas echo "| Product | Issues | Discussions | Contributing | Security |" echo "|---------|--------|-------------|--------------|----------|" for i in $sorted_indices; do - name=$(yq -r ".components[$i].name" components.yml) - repo=$(yq -r ".components[$i].repo" components.yml) - ref=$(yq -r ".components[$i].ref // \"main\"" components.yml) - contrib=$(yq -r ".components[$i].links.contributing // \"CONTRIBUTING.md\"" components.yml) - discussions=$(yq -r ".components[$i].links.discussions // true" components.yml) - security=$(yq -r ".components[$i].links.security // true" components.yml) + name=$(yq -r ".components[$i].name" "$CONFIG") + repo=$(yq -r ".components[$i].repo" "$CONFIG") + ref=$(yq -r ".components[$i].ref // \"main\"" "$CONFIG") + contrib=$(yq -r ".components[$i].links.contributing // \"CONTRIBUTING.md\"" "$CONFIG") + discussions=$(yq -r ".components[$i].links.discussions // true" "$CONFIG") + security=$(yq -r ".components[$i].links.security // true" "$CONFIG") issues_cell="[Issues](https://github.com/${repo}/issues)" if [ "$discussions" = "true" ]; then diff --git a/.github/workflows/sync-skills.yml b/.github/workflows/sync-skills.yml index 6ce0ae2a..7385de0b 100644 --- a/.github/workflows/sync-skills.yml +++ b/.github/workflows/sync-skills.yml @@ -2,8 +2,9 @@ # Copyright (c) 2026 NVIDIA Corporation. All rights reserved. # # Sync skills from product repos into the nvidia/skills catalog. -# Reads component definitions from components.yml — teams onboard by -# adding an entry there, not by editing this workflow. +# Reads component definitions from components.d/*.yml (one file per +# component) — teams onboard by adding their own file there, not by +# editing this workflow or any shared file. # # Requires a PAT (SKILLS_SYNC_PAT) with read access to all product # repos, stored as a repository secret. @@ -47,16 +48,23 @@ jobs: truncate -s 0 /tmp/failed-components.txt truncate -s 0 /tmp/sync-versions.txt + # Aggregate per-component files into a single config so the + # iteration loop below can index by position. The components.d/ + # layout means concurrent onboarding PRs never touch a shared + # file — see components.d/README.md for the schema. + CONFIG=/tmp/components.aggregated.yml + yq ea '[.] | {"components": .}' components.d/*.yml > "$CONFIG" + # Configure git to use the token via credential helper # so it never appears in clone URLs or error output git config --global credential.helper '!f() { echo "username=x-access-token"; echo "password=${GH_TOKEN}"; }; f' - component_count=$(yq '.components | length' components.yml) + component_count=$(yq '.components | length' "$CONFIG") for i in $(seq 0 $((component_count - 1))); do - name=$(yq -r ".components[$i].name" components.yml) - repo=$(yq -r ".components[$i].repo" components.yml) - ref=$(yq -r ".components[$i].ref // \"main\"" components.yml) + name=$(yq -r ".components[$i].name" "$CONFIG") + repo=$(yq -r ".components[$i].repo" "$CONFIG") + ref=$(yq -r ".components[$i].ref // \"main\"" "$CONFIG") echo "── $name ──" @@ -78,10 +86,10 @@ jobs: echo "$slug|$upstream_short_sha|$upstream_sha|$upstream_date|$repo" >> /tmp/sync-versions.txt # Collect all skill paths for sparse checkout - skill_count=$(yq -r ".components[$i].skills | length" components.yml) + skill_count=$(yq -r ".components[$i].skills | length" "$CONFIG") sparse_paths="" for j in $(seq 0 $((skill_count - 1))); do - path=$(yq -r ".components[$i].skills[$j].path" components.yml) + path=$(yq -r ".components[$i].skills[$j].path" "$CONFIG") sparse_paths="$sparse_paths $path" done (cd "$tmp_dir" && git sparse-checkout set $sparse_paths 2>/dev/null) || true @@ -89,8 +97,8 @@ jobs: # Copy each skill path to its catalog directory synced=false for j in $(seq 0 $((skill_count - 1))); do - path=$(yq -r ".components[$i].skills[$j].path" components.yml) - catalog_dir=$(yq -r ".components[$i].skills[$j].catalog_dir" components.yml) + path=$(yq -r ".components[$i].skills[$j].path" "$CONFIG") + catalog_dir=$(yq -r ".components[$i].skills[$j].catalog_dir" "$CONFIG") src="$tmp_dir/$path" if [ -d "$src" ] && [ -n "$(ls -A "$src" 2>/dev/null)" ]; then @@ -111,7 +119,7 @@ jobs: if $synced; then echo "- $name" >> /tmp/rsynced-components.txt for j in $(seq 0 $((skill_count - 1))); do - catalog_dir=$(yq -r ".components[$i].skills[$j].catalog_dir" components.yml) + catalog_dir=$(yq -r ".components[$i].skills[$j].catalog_dir" "$CONFIG") if [ -n "$(git status --porcelain "skills/$catalog_dir" 2>/dev/null)" ]; then echo "- $name" >> /tmp/changed-components.txt break @@ -197,7 +205,7 @@ jobs: `**Run:** ${context.runId}`, `**Trigger:** \`${context.eventName}\``, ``, - `This usually means the skill path in \`components.yml\` doesn't match the actual directory in the source repo (e.g. symlink, renamed, or removed).` + `This usually means the skill path in \`components.d/.yml\` doesn't match the actual directory in the source repo (e.g. symlink, renamed, or removed).` ].join('\n'); await github.rest.issues.create({ owner: context.repo.owner, diff --git a/components.d/README.md b/components.d/README.md new file mode 100644 index 00000000..083837a5 --- /dev/null +++ b/components.d/README.md @@ -0,0 +1,72 @@ + + + +# `components.d/` — Component catalog + +One file per component, aggregated at workflow runtime. This layout exists so simultaneous onboarding PRs from different teams never touch the same file — eliminating merge conflicts at scale. + +## Onboarding a new component + +1. Create `components.d/.yml` where `` is your component name lowercased with spaces replaced by dashes (e.g., `Nemotron Voice Agent` → `nemotron-voice-agent.yml`). +2. Fill in the fields below. +3. Open a pull request — that's it. The sync workflow picks it up automatically; the README's Available Skills and Getting Help tables regenerate on the next sync. + +## Required fields + +| Field | Type | Description | +|---------------|--------|-----------------------------------------------------------------------------| +| `name` | string | Display name shown in the README (e.g., `CUDA-Q`, `Nemotron Voice Agent`). | +| `repo` | string | GitHub repository (`owner/repo`). | +| `description` | string | One-line description for the README's Available Skills table. | +| `skills` | list | Skill source locations (see below). | + +Each entry under `skills:` requires: + +| Field | Type | Description | +|---------------|--------|--------------------------------------------------------------------------| +| `path` | string | Directory in the source repo containing skills (e.g., `.agents/skills/`).| +| `catalog_dir` | string | Directory name under `skills/` in this catalog (must be unique). | + +## Optional fields + +| Field | Default | Description | +|------------------------|--------------------|------------------------------------------------------------| +| `ref` | `main` | Branch to sync from. | +| `links.contributing` | `CONTRIBUTING.md` | Path to the contributing file in the source repo. | +| `links.discussions` | `true` | Set to `false` if the repo has no Discussions tab. | +| `links.security` | `true` | Set to `false` if the repo has no `SECURITY.md`. | + +## Example + +```yaml +# components.d/your-product.yml +name: Your Product +repo: NVIDIA/your-product +description: One-line description of what the skills do. +skills: + - path: .agents/skills/ + catalog_dir: your-product +``` + +For multi-skill components, add multiple entries under `skills:`: + +```yaml +name: NeMo Evaluator +repo: NVIDIA-NeMo/Evaluator +description: LLM evaluation — launch evaluations, access MLflow results, and bring-your-own benchmarks. +skills: + - path: packages/nemo-evaluator-launcher/.claude/skills/ + catalog_dir: NeMo-Evaluator-Launcher + - path: packages/nemo-evaluator/.claude/skills/ + catalog_dir: NeMo-Evaluator +``` + +## How aggregation works + +The sync workflow runs: + +```bash +yq ea '[.] | {"components": .}' components.d/*.yml > /tmp/components.aggregated.yml +``` + +Then iterates the resulting `components` list. Files are read in alphabetical order; the README regenerator sorts the result by display name independently. diff --git a/components.d/cuda-q.yml b/components.d/cuda-q.yml new file mode 100644 index 00000000..433ad514 --- /dev/null +++ b/components.d/cuda-q.yml @@ -0,0 +1,8 @@ +name: CUDA-Q +repo: NVIDIA/cuda-quantum +description: CUDA Quantum — onboarding guide for installation, test programs, GPU simulation, QPU hardware, and quantum applications. +skills: + - path: .claude/skills/ + catalog_dir: CUDA-Q +links: + contributing: Contributing.md diff --git a/components.d/cuopt.yml b/components.d/cuopt.yml new file mode 100644 index 00000000..0464008f --- /dev/null +++ b/components.d/cuopt.yml @@ -0,0 +1,6 @@ +name: cuOpt +repo: NVIDIA/cuopt +description: GPU-accelerated optimization — vehicle routing, linear programming, quadratic programming, installation, server deployment, and developer tools. +skills: + - path: skills/ + catalog_dir: cuopt diff --git a/components.d/megatron-bridge.yml b/components.d/megatron-bridge.yml new file mode 100644 index 00000000..2d15cfd0 --- /dev/null +++ b/components.d/megatron-bridge.yml @@ -0,0 +1,8 @@ +name: Megatron-Bridge +repo: NVIDIA-NeMo/Megatron-Bridge +description: Bridge between NeMo and Megatron — data processing, model conversion, and training utilities. +skills: + - path: skills/ + catalog_dir: Megatron-Bridge +links: + security: false diff --git a/components.d/megatron-core.yml b/components.d/megatron-core.yml new file mode 100644 index 00000000..2168873b --- /dev/null +++ b/components.d/megatron-core.yml @@ -0,0 +1,8 @@ +name: Megatron-Core +repo: NVIDIA/Megatron-LM +description: Large-scale distributed training — model parallelism, pipeline parallelism, and mixed precision. +skills: + - path: skills/ + catalog_dir: Megatron-Core +links: + security: false diff --git a/components.d/model-optimizer.yml b/components.d/model-optimizer.yml new file mode 100644 index 00000000..65dc2ccd --- /dev/null +++ b/components.d/model-optimizer.yml @@ -0,0 +1,8 @@ +name: Model-Optimizer +repo: NVIDIA/Model-Optimizer +description: Model optimization — quantization, sparsity, and distillation for efficient inference. +skills: + - path: .claude/skills/ + catalog_dir: Model-Optimizer +links: + discussions: false diff --git a/components.d/nemo-evaluator.yml b/components.d/nemo-evaluator.yml new file mode 100644 index 00000000..204caa6f --- /dev/null +++ b/components.d/nemo-evaluator.yml @@ -0,0 +1,8 @@ +name: NeMo Evaluator +repo: NVIDIA-NeMo/Evaluator +description: LLM evaluation — launch evaluations, access MLflow results, NeMo Evaluator Launcher assistant, and bring-your-own benchmarks. +skills: + - path: packages/nemo-evaluator-launcher/.claude/skills/ + catalog_dir: NeMo-Evaluator-Launcher + - path: packages/nemo-evaluator/.claude/skills/ + catalog_dir: NeMo-Evaluator diff --git a/components.d/nemo-gym.yml b/components.d/nemo-gym.yml new file mode 100644 index 00000000..601fac71 --- /dev/null +++ b/components.d/nemo-gym.yml @@ -0,0 +1,6 @@ +name: NeMo Gym +repo: NVIDIA-NeMo/Gym +description: RL training environments — add benchmarks, resources servers, agent wiring, and reward profiling. +skills: + - path: .claude/skills/ + catalog_dir: NeMo-Gym diff --git a/components.d/nemoclaw.yml b/components.d/nemoclaw.yml new file mode 100644 index 00000000..56078c64 --- /dev/null +++ b/components.d/nemoclaw.yml @@ -0,0 +1,6 @@ +name: NemoClaw +repo: NVIDIA/NemoClaw +description: Secure agent sandboxing — run OpenClaw inside NVIDIA OpenShell with managed inference, policy management, remote deployment, sandbox monitoring, and contributor/maintainer workflows. +skills: + - path: .agents/skills/ + catalog_dir: NemoClaw diff --git a/components.d/nemotron-voice-agent.yml b/components.d/nemotron-voice-agent.yml new file mode 100644 index 00000000..804ea3b2 --- /dev/null +++ b/components.d/nemotron-voice-agent.yml @@ -0,0 +1,6 @@ +name: Nemotron Voice Agent +repo: NVIDIA-AI-Blueprints/nemotron-voice-agent +description: Real-time conversational AI — deploy speech-to-speech voice agents on Workstation, Jetson Thor, or Cloud NIMs. +skills: + - path: .agents/skills/ + catalog_dir: nemotron-voice-agent diff --git a/components.d/rag-blueprint.yml b/components.d/rag-blueprint.yml new file mode 100644 index 00000000..ee927bbb --- /dev/null +++ b/components.d/rag-blueprint.yml @@ -0,0 +1,6 @@ +name: RAG Blueprint +repo: NVIDIA-AI-Blueprints/rag +description: RAG pipeline — deploy, configure, troubleshoot, and manage retrieval augmented generation with Docker Compose or Helm. +skills: + - path: skill-source/.agents/skills/ + catalog_dir: rag diff --git a/components.d/tensorrt-llm.yml b/components.d/tensorrt-llm.yml new file mode 100644 index 00000000..7d3adffd --- /dev/null +++ b/components.d/tensorrt-llm.yml @@ -0,0 +1,6 @@ +name: TensorRT-LLM +repo: NVIDIA/TensorRT-LLM +description: LLM inference optimization — model onboarding, performance analysis and optimization, kernel writing, CI diagnostics, code contribution, and codebase exploration. +skills: + - path: .claude/skills/ + catalog_dir: TensorRT-LLM diff --git a/components.yml b/components.yml deleted file mode 100644 index 1c6cbb13..00000000 --- a/components.yml +++ /dev/null @@ -1,137 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# Copyright (c) 2026 NVIDIA Corporation. All rights reserved. -# -# Component catalog — single source of truth for NVIDIA Agent Skills. -# -# To onboard a new component: -# 1. Add an entry to this file following the pattern below -# 2. Open a pull request — that's it! -# -# The sync workflow reads this file automatically. -# -# Required fields: -# name Display name shown in the README -# repo GitHub repository (owner/repo) -# description One-line description for the README -# skills List of skill locations in the source repo -# path Directory containing skills in the source repo -# catalog_dir Directory name under skills/ in this catalog -# -# Optional fields: -# ref Branch to sync from (default: main) -# links Override default link behavior (see examples below) -# contributing Path to CONTRIBUTING file (default: CONTRIBUTING.md) -# discussions Set to false if repo has no Discussions tab -# security Set to false if repo has no SECURITY.md - -components: - - name: CUDA-Q - repo: NVIDIA/cuda-quantum - description: >- - CUDA Quantum — onboarding guide for installation, test programs, - GPU simulation, QPU hardware, and quantum applications. - skills: - - path: .claude/skills/ - catalog_dir: CUDA-Q - links: - contributing: Contributing.md - - - name: cuOpt - repo: NVIDIA/cuopt - description: >- - GPU-accelerated optimization — vehicle routing, linear programming, - quadratic programming, installation, server deployment, and developer tools. - skills: - - path: skills/ - catalog_dir: cuopt - - - name: TensorRT-LLM - repo: NVIDIA/TensorRT-LLM - description: >- - LLM inference optimization — model onboarding, performance analysis - and optimization, kernel writing, CI diagnostics, code contribution, - and codebase exploration. - skills: - - path: .claude/skills/ - catalog_dir: TensorRT-LLM - - - name: Model-Optimizer - repo: NVIDIA/Model-Optimizer - description: >- - Model optimization — quantization, sparsity, and distillation - for efficient inference. - skills: - - path: .claude/skills/ - catalog_dir: Model-Optimizer - links: - discussions: false - - - name: Megatron-Core - repo: NVIDIA/Megatron-LM - description: >- - Large-scale distributed training — model parallelism, pipeline - parallelism, and mixed precision. - skills: - - path: skills/ - catalog_dir: Megatron-Core - links: - security: false - - - name: Megatron-Bridge - repo: NVIDIA-NeMo/Megatron-Bridge - description: >- - Bridge between NeMo and Megatron — data processing, model conversion, - and training utilities. - skills: - - path: skills/ - catalog_dir: Megatron-Bridge - links: - security: false - - - name: Nemotron Voice Agent - repo: NVIDIA-AI-Blueprints/nemotron-voice-agent - description: >- - Real-time conversational AI — deploy speech-to-speech voice agents - on Workstation, Jetson Thor, or Cloud NIMs. - skills: - - path: .agents/skills/ - catalog_dir: nemotron-voice-agent - - - name: NeMo Gym - repo: NVIDIA-NeMo/Gym - description: >- - RL training environments — add benchmarks, resources servers, - agent wiring, and reward profiling. - skills: - - path: .claude/skills/ - catalog_dir: NeMo-Gym - - - name: NeMo Evaluator - repo: NVIDIA-NeMo/Evaluator - description: >- - LLM evaluation — launch evaluations, access MLflow results, - NeMo Evaluator Launcher assistant, and bring-your-own benchmarks. - skills: - - path: packages/nemo-evaluator-launcher/.claude/skills/ - catalog_dir: NeMo-Evaluator-Launcher - - path: packages/nemo-evaluator/.claude/skills/ - catalog_dir: NeMo-Evaluator - - - name: NemoClaw - repo: NVIDIA/NemoClaw - description: >- - Secure agent sandboxing — run OpenClaw inside NVIDIA OpenShell with - managed inference, policy management, remote deployment, sandbox - monitoring, and contributor/maintainer workflows. - skills: - - path: .agents/skills/ - catalog_dir: NemoClaw - - - name: RAG Blueprint - repo: NVIDIA-AI-Blueprints/rag - description: >- - RAG pipeline — deploy, configure, troubleshoot, and manage retrieval - augmented generation with Docker Compose or Helm. - skills: - - path: skill-source/.agents/skills/ - catalog_dir: rag