diff --git a/.github/workflows/validate-skills.yml b/.github/workflows/validate-skills.yml new file mode 100644 index 0000000..d5dad1c --- /dev/null +++ b/.github/workflows/validate-skills.yml @@ -0,0 +1,24 @@ +name: Validate skills + +on: + pull_request: + paths: + - 'skills/**' + - 'scripts/check-skill-frontmatter.mjs' + - '.github/workflows/validate-skills.yml' + push: + branches: [main] + paths: + - 'skills/**' + +jobs: + frontmatter: + name: SKILL.md frontmatter + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - run: npm install --no-save --no-audit --no-fund js-yaml@4 + - run: node scripts/check-skill-frontmatter.mjs skills diff --git a/README.md b/README.md index 84e9221..110ba71 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ also shows `unity` as installed and enabled. ``` PLUGIN STATUS VERSION -unity@unity-agent-plugin installed, enabled 0.1.0-beta +unity@unity-agent-plugin installed, enabled 0.1.6-beta ``` ### Manual install diff --git a/scripts/check-skill-frontmatter.mjs b/scripts/check-skill-frontmatter.mjs new file mode 100644 index 0000000..e30dcba --- /dev/null +++ b/scripts/check-skill-frontmatter.mjs @@ -0,0 +1,54 @@ +#!/usr/bin/env node +// Fails when any skills/*/SKILL.md has frontmatter that a strict YAML parser rejects, +// or that lacks a non-empty `name` matching its folder or a non-empty `description`. +// Agents parse the frontmatter with a real YAML parser and silently drop a skill that +// fails, so this is the only place the defect becomes visible. +import { readdirSync, readFileSync, existsSync } from 'node:fs'; +import { join } from 'node:path'; +import yaml from 'js-yaml'; + +const root = process.argv[2] ?? 'skills'; +let checked = 0; +const failures = []; + +for (const dir of readdirSync(root, { withFileTypes: true })) { + if (!dir.isDirectory()) continue; + const path = join(root, dir.name, 'SKILL.md'); + if (!existsSync(path)) { + failures.push(`${path}: missing`); + continue; + } + const text = readFileSync(path, 'utf8'); + const match = text.match(/^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/); + if (!match) { + failures.push(`${path}: no YAML frontmatter block`); + continue; + } + let data; + try { + data = yaml.load(match[1]); + } catch (error) { + failures.push(`${path}: frontmatter is not valid YAML: ${error.message.split('\n')[0]}`); + continue; + } + if (typeof data !== 'object' || data === null) { + failures.push(`${path}: frontmatter is not a mapping`); + continue; + } + if (typeof data.name !== 'string' || data.name.trim() === '') { + failures.push(`${path}: missing or empty name`); + } else if (data.name !== dir.name) { + failures.push(`${path}: name "${data.name}" does not match folder "${dir.name}"`); + } + if (typeof data.description !== 'string' || data.description.trim() === '') { + failures.push(`${path}: missing or empty description`); + } + checked += 1; +} + +if (failures.length > 0) { + console.error(`${failures.length} problem(s) in ${checked} skill(s):`); + for (const failure of failures) console.error(` ${failure}`); + process.exit(1); +} +console.log(`${checked} skills: frontmatter OK`); diff --git a/skills/physics-3d-collision/SKILL.md b/skills/physics-3d-collision/SKILL.md index 2766169..b7c1e7e 100644 --- a/skills/physics-3d-collision/SKILL.md +++ b/skills/physics-3d-collision/SKILL.md @@ -1,6 +1,13 @@ --- name: physics-3d-collision -description: 3D PhysX collision and trigger diagnostics for MonoBehaviour-based Unity projects. Primary scope: OnCollisionEnter / OnTriggerEnter not firing, objects passing through each other, Physics.Raycast missing, ragdoll explosion, AddForce stops working after settling, MeshCollider rules, and similar 3D PhysX symptoms. Adjacent topics (2D physics, OTS / Unity Physics package): provides a brief best-effort answer with a scope disclaimer and a documentation link, rather than refusing outright. When dedicated specialist skills (physics-2d, physics-dots) are installed, those should handle their respective domains and this skill defers to them. +description: >- + 3D PhysX collision and trigger diagnostics for MonoBehaviour-based Unity projects. Primary scope: + OnCollisionEnter / OnTriggerEnter not firing, objects passing through each other, Physics.Raycast + missing, ragdoll explosion, AddForce stops working after settling, MeshCollider rules, and similar + 3D PhysX symptoms. Adjacent topics (2D physics, OTS / Unity Physics package): provides a brief + best-effort answer with a scope disclaimer and a documentation link, rather than refusing + outright. When dedicated specialist skills (physics-2d, physics-dots) are installed, those should + handle their respective domains and this skill defers to them. --- # Skill: physics-3d-collision (PhysX MonoBehaviour) diff --git a/skills/tilemap-ruletile-createfromsegment/SKILL.md b/skills/tilemap-ruletile-createfromsegment/SKILL.md index 2938e05..a8821c4 100644 --- a/skills/tilemap-ruletile-createfromsegment/SKILL.md +++ b/skills/tilemap-ruletile-createfromsegment/SKILL.md @@ -1,6 +1,13 @@ --- name: tilemap-ruletile-createfromsegment -description: Use when the user wants tiles that auto-tile (autotile) as they paint, wants a RuleTile built from existing terrain or edge sprites, or asks to make sprites "tile correctly" or "connect properly". Also converts sprite-segment-3x3grid output patterns into Unity RuleTile TilingRules: 3x3 grid text patterns (X, ., *) become TilingRule neighbor configurations, mapping '.' to 'This' rules and 'X' to 'DontCare', sorted by specificity (more 'This' rules first). Use when creating RuleTiles from sprite analysis or defining tile neighbor rules programmatically. Sprites must be provided as input. +description: >- + Use when the user wants tiles that auto-tile (autotile) as they paint, wants a RuleTile built from + existing terrain or edge sprites, or asks to make sprites "tile correctly" or "connect properly". + Also converts sprite-segment-3x3grid output patterns into Unity RuleTile TilingRules: 3x3 grid + text patterns (X, ., *) become TilingRule neighbor configurations, mapping '.' to 'This' rules and + 'X' to 'DontCare', sorted by specificity (more 'This' rules first). Use when creating RuleTiles + from sprite analysis or defining tile neighbor rules programmatically. Sprites must be provided as + input. required_packages: com.unity.2d.tilemap: ">=1.0.0" com.unity.2d.tilemap.extras: ">=4.0.0" diff --git a/skills/ui-imgui/SKILL.md b/skills/ui-imgui/SKILL.md index 6999e28..e32c593 100644 --- a/skills/ui-imgui/SKILL.md +++ b/skills/ui-imgui/SKILL.md @@ -1,6 +1,12 @@ --- name: ui-imgui -description: Unity IMGUI (Immediate Mode GUI) expert for legacy editor tools using OnGUI/immediate mode. Generates and modifies IMGUI EditorWindows, custom Inspectors, PropertyDrawers, and scripts with IMGUI code (OnGUI, OnInspectorGUI). Use when maintaining existing IMGUI editor code or when user explicitly requests IMGUI/OnGUI. Do not use for NEW editor windows or tools: new editor UI defaults to UI Toolkit (ui-uitk) unless the project already uses IMGUI exclusively or the user asks for OnGUI by name. +description: >- + Unity IMGUI (Immediate Mode GUI) expert for legacy editor tools using OnGUI/immediate mode. + Generates and modifies IMGUI EditorWindows, custom Inspectors, PropertyDrawers, and scripts with + IMGUI code (OnGUI, OnInspectorGUI). Use when maintaining existing IMGUI editor code or when user + explicitly requests IMGUI/OnGUI. Do not use for NEW editor windows or tools: new editor UI + defaults to UI Toolkit (ui-uitk) unless the project already uses IMGUI exclusively or the user + asks for OnGUI by name. --- **Before proceeding:** If the user is asking about creating a **new** editor window, custom inspector, or PropertyDrawer without explicitly mentioning IMGUI/OnGUI, recommend using UI Toolkit (CreateGUI) instead, as it's the modern approach. Only proceed with IMGUI if: diff --git a/skills/ui/SKILL.md b/skills/ui/SKILL.md index 6e857e4..5a099b9 100644 --- a/skills/ui/SKILL.md +++ b/skills/ui/SKILL.md @@ -1,6 +1,14 @@ --- name: ui -description: Unity UI expert for menus, HUDs, screens, panels, buttons, labels, and all visual interface elements. Handles questions about UI in scenes or prefabs (how many elements, what exists, structure analysis), styling changes (colors, borders, backgrounds, fonts, spacing, rounded corners), layout adjustments, and UI generation. Routes to UI Toolkit, uGUI, or IMGUI based on project context. Use for ANY request to build, edit, or understand game UI (menus, HUDs, settings or pause screens) when no framework is named: consult this skill to detect which UI system the project uses before writing any UI code, even for a request that looks simple enough to build directly. +description: >- + Unity UI expert for menus, HUDs, screens, panels, buttons, labels, and all visual interface + elements. Handles questions about UI in scenes or prefabs (how many elements, what exists, + structure analysis), styling changes (colors, borders, backgrounds, fonts, spacing, rounded + corners), layout adjustments, and UI generation. Routes to UI Toolkit, uGUI, or IMGUI based on + project context. Use for ANY request to build, edit, or understand game UI (menus, HUDs, settings + or pause screens) when no framework is named: consult this skill to detect which UI system the + project uses before writing any UI code, even for a request that looks simple enough to build + directly. --- Determine the appropriate UI system for the project and route to the correct specialized skill.