feat(build): support directory-shaped rules with references/

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Julian lechnerandClaude Sonnet 5 committed 2026-09-16 15:38:28 +02:00
1 parent 01220cebd4
commit 3a01d28506
3 files changed
+25 -12

No files matched your search

+3 -3
View File
@@ -1,5 +1,5 @@
rule_file skill_name trigger rule_file skill_name trigger
angular.md rules-angular Angular component, template, or RxJS/signal work angular rules-angular Angular component, template, or RxJS/signal work
csharp.md rules-csharp C# or .NET implementation, review, or refactoring work csharp.md rules-csharp C# or .NET implementation, review, or refactoring work
decision-rule.md rules-decision-rule evaluating requirements, ambiguous behavior, or technical choices that need a decision decision-rule.md rules-decision-rule evaluating requirements, ambiguous behavior, or technical choices that need a decision
definition-of-done.md rules-definition-of-done validating that a task is complete or ready for review definition-of-done.md rules-definition-of-done validating that a task is complete or ready for review
@@ -16,5 +16,5 @@ security-network.md rules-security-network network, URL fetch, proxy, outbound r
security-crypto.md rules-security-crypto cryptography, secrets, credentials, key, or token work security-crypto.md rules-security-crypto cryptography, secrets, credentials, key, or token work
security-supply-chain.md rules-security-supply-chain dependency, package, plugin, build, deployment, or CI supply-chain work security-supply-chain.md rules-security-supply-chain dependency, package, plugin, build, deployment, or CI supply-chain work
typescript.md rules-typescript TypeScript or modern ECMAScript implementation work typescript.md rules-typescript TypeScript or modern ECMAScript implementation work
ui-ux.md rules-ui-ux UI or UX design and interaction decisions ui-ux rules-ui-ux UI or UX design and interaction decisions
wpf.md rules-wpf WPF, XAML, or MVVM desktop UI work wpf rules-wpf WPF, XAML, or MVVM desktop UI work
1 rule_file skill_name trigger
2 angular.md angular rules-angular Angular component, template, or RxJS/signal work
3 csharp.md rules-csharp C# or .NET implementation, review, or refactoring work
4 decision-rule.md rules-decision-rule evaluating requirements, ambiguous behavior, or technical choices that need a decision
5 definition-of-done.md rules-definition-of-done validating that a task is complete or ready for review
16 security-crypto.md rules-security-crypto cryptography, secrets, credentials, key, or token work
17 security-supply-chain.md rules-security-supply-chain dependency, package, plugin, build, deployment, or CI supply-chain work
18 typescript.md rules-typescript TypeScript or modern ECMAScript implementation work
19 ui-ux.md ui-ux rules-ui-ux UI or UX design and interaction decisions
20 wpf.md wpf rules-wpf WPF, XAML, or MVVM desktop UI work
+11 -4
View File
@@ -109,11 +109,11 @@ Load rule files when their subject applies:
- rules/security-network.md for network access, URLs, TLS, proxies, or SSRF. - rules/security-network.md for network access, URLs, TLS, proxies, or SSRF.
- rules/security-crypto.md for cryptography, secrets, credentials, keys, or tokens. - rules/security-crypto.md for cryptography, secrets, credentials, keys, or tokens.
- rules/security-supply-chain.md for dependencies, packages, plugins, builds, deployments, or CI. - rules/security-supply-chain.md for dependencies, packages, plugins, builds, deployments, or CI.
- rules/angular.md for Angular work. - rules/angular/index.md for Angular work.
- rules/typescript.md for TypeScript work. - rules/typescript.md for TypeScript work.
- rules/csharp.md for C# or .NET work. - rules/csharp.md for C# or .NET work.
- rules/wpf.md for WPF work. - rules/wpf/index.md for WPF work.
- rules/ui-ux.md for UI or UX decisions. - rules/ui-ux/index.md for UI or UX decisions.
- rules/microsoft.md for Microsoft 365, Azure DevOps, or Teams work. - rules/microsoft.md for Microsoft 365, Azure DevOps, or Teams work.
- rules/git.md for Git operations. - rules/git.md for Git operations.
- rules/refactoring.md for refactoring work. - rules/refactoring.md for refactoring work.
@@ -140,11 +140,18 @@ foreach ($platform in @('windows','linux')) {
$claudeRuleSkillLines = @() $claudeRuleSkillLines = @()
foreach ($entry in $ruleSkillEntries) { foreach ($entry in $ruleSkillEntries) {
$ruleSourcePath = Join-Path $shared "rules/$($entry.rule_file)"
$isDirectory = Test-Path -LiteralPath $ruleSourcePath -PathType Container
$ruleBodyPath = if ($isDirectory) { Join-Path $ruleSourcePath 'index.md' } else { $ruleSourcePath }
$skillDir = Join-Path $output "claude-$platform/skills/rules/$($entry.skill_name)" $skillDir = Join-Path $output "claude-$platform/skills/rules/$($entry.skill_name)"
New-Item $skillDir -ItemType Directory -Force | Out-Null New-Item $skillDir -ItemType Directory -Force | Out-Null
$ruleContent = Get-Content (Join-Path $shared "rules/$($entry.rule_file)") -Raw $ruleContent = Get-Content $ruleBodyPath -Raw
$skillBody = "---`r`nname: $($entry.skill_name)`r`ndescription: Use for $($entry.trigger).`r`n---`r`n`r`n$ruleContent" $skillBody = "---`r`nname: $($entry.skill_name)`r`ndescription: Use for $($entry.trigger).`r`n---`r`n`r`n$ruleContent"
Set-Content (Join-Path $skillDir 'SKILL.md') $skillBody -Encoding UTF8 Set-Content (Join-Path $skillDir 'SKILL.md') $skillBody -Encoding UTF8
if ($isDirectory) {
$referencesSource = Join-Path $ruleSourcePath 'references'
if (Test-Path -LiteralPath $referencesSource) { Copy-Directory $referencesSource (Join-Path $skillDir 'references') }
}
$claudeRuleSkillLines += "- $($entry.skill_name) for $($entry.trigger)." $claudeRuleSkillLines += "- $($entry.skill_name) for $($entry.trigger)."
} }
$claudeRuleLoading = "Always apply ``rules/general.md`` before starting any task, embedded below.`r`n`r`nDetect the languages, frameworks, tools, and change areas from the repository and the requested work. Invoke every matching rule skill before editing. Invoke all matching rule skills when multiple technologies apply.`r`n`r`nInvoke rule skills when their subject applies:`r`n`r`n" + ($claudeRuleSkillLines -join "`r`n") $claudeRuleLoading = "Always apply ``rules/general.md`` before starting any task, embedded below.`r`n`r`nDetect the languages, frameworks, tools, and change areas from the repository and the requested work. Invoke every matching rule skill before editing. Invoke all matching rule skills when multiple technologies apply.`r`n`r`nInvoke rule skills when their subject applies:`r`n`r`n" + ($claudeRuleSkillLines -join "`r`n")
+11 -5
View File
@@ -38,7 +38,7 @@ while IFS=$'\t' read -r rule_file skill_name trigger; do
[ -n "$rule_file" ] || continue [ -n "$rule_file" ] || continue
[ -n "$skill_name" ] || { printf 'Missing skill_name in rule-skill manifest row for %s.\n' "$rule_file" >&2; exit 1; } [ -n "$skill_name" ] || { printf 'Missing skill_name in rule-skill manifest row for %s.\n' "$rule_file" >&2; exit 1; }
[ -n "$trigger" ] || { printf 'Missing trigger in rule-skill manifest row for %s.\n' "$rule_file" >&2; exit 1; } [ -n "$trigger" ] || { printf 'Missing trigger in rule-skill manifest row for %s.\n' "$rule_file" >&2; exit 1; }
[ -f "$shared/rules/$rule_file" ] || { printf 'Rule-skill manifest references a missing rule file: %s\n' "$rule_file" >&2; exit 1; } [ -f "$shared/rules/$rule_file" ] || [ -d "$shared/rules/$rule_file" ] || { printf 'Rule-skill manifest references a missing rule file: %s\n' "$rule_file" >&2; exit 1; }
[ -z "${rule_skill_seen[$skill_name]+x}" ] || { printf 'Duplicate rule-skill name in manifest: %s\n' "$skill_name" >&2; exit 1; } [ -z "${rule_skill_seen[$skill_name]+x}" ] || { printf 'Duplicate rule-skill name in manifest: %s\n' "$skill_name" >&2; exit 1; }
rule_skill_seen[$skill_name]=1 rule_skill_seen[$skill_name]=1
rule_skill_files+=("$rule_file") rule_skill_files+=("$rule_file")
@@ -99,11 +99,11 @@ Load rule files when their subject applies:
- rules/security-network.md for network access, URLs, TLS, proxies, or SSRF. - rules/security-network.md for network access, URLs, TLS, proxies, or SSRF.
- rules/security-crypto.md for cryptography, secrets, credentials, keys, or tokens. - rules/security-crypto.md for cryptography, secrets, credentials, keys, or tokens.
- rules/security-supply-chain.md for dependencies, packages, plugins, builds, deployments, or CI. - rules/security-supply-chain.md for dependencies, packages, plugins, builds, deployments, or CI.
- rules/angular.md for Angular work. - rules/angular/index.md for Angular work.
- rules/typescript.md for TypeScript work. - rules/typescript.md for TypeScript work.
- rules/csharp.md for C# or .NET work. - rules/csharp.md for C# or .NET work.
- rules/wpf.md for WPF work. - rules/wpf/index.md for WPF work.
- rules/ui-ux.md for UI or UX decisions. - rules/ui-ux/index.md for UI or UX decisions.
- rules/microsoft.md for Microsoft 365, Azure DevOps, or Teams work. - rules/microsoft.md for Microsoft 365, Azure DevOps, or Teams work.
- rules/git.md for Git operations. - rules/git.md for Git operations.
- rules/refactoring.md for refactoring work. - rules/refactoring.md for refactoring work.
@@ -131,9 +131,15 @@ for i in "${!rule_skill_names[@]}"; do
rule_file=${rule_skill_files[$i]} rule_file=${rule_skill_files[$i]}
skill_name=${rule_skill_names[$i]} skill_name=${rule_skill_names[$i]}
trigger=${rule_skill_triggers[$i]} trigger=${rule_skill_triggers[$i]}
rule_source="$shared/rules/$rule_file"
rule_body="$rule_source"
[ -d "$rule_source" ] && rule_body="$rule_source/index.md"
skill_dir="$output/claude-$platform/skills/rules/$skill_name" skill_dir="$output/claude-$platform/skills/rules/$skill_name"
mkdir -p "$skill_dir" mkdir -p "$skill_dir"
{ printf -- '---\nname: %s\ndescription: Use for %s.\n---\n\n' "$skill_name" "$trigger"; cat "$shared/rules/$rule_file"; } > "$skill_dir/SKILL.md" { printf -- '---\nname: %s\ndescription: Use for %s.\n---\n\n' "$skill_name" "$trigger"; cat "$rule_body"; } > "$skill_dir/SKILL.md"
if [ -d "$rule_source/references" ]; then
copy_directory "$rule_source/references" "$skill_dir/references"
fi
claude_rule_loading_list="${claude_rule_loading_list}- ${skill_name} for ${trigger}. claude_rule_loading_list="${claude_rule_loading_list}- ${skill_name} for ${trigger}.
" "
done done