fix(install): add rust, cpp, csharp to legacy language alias map (#747)

* fix(install): add rust, cpp, csharp to legacy language alias map

The legacy installer compatibility layer in install-manifests.js was
missing entries for rust, cpp, and csharp — languages that have
rules/ directories and (for rust/cpp) install-components.json entries.

Running `./install.sh rust` fails with "Unknown legacy language: rust"
because LEGACY_LANGUAGE_ALIAS_TO_CANONICAL and
LEGACY_LANGUAGE_EXTRA_MODULE_IDS didn't include these languages.

Fixes the issue reported in #694 by @mpiton.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>

* fix(install): complete csharp legacy support and add resolution tests

- Add lang:csharp component to install-components.json with
  framework-language module (matching cpp/rust pattern)
- Update csharp mapping in LEGACY_LANGUAGE_EXTRA_MODULE_IDS from
  empty array to ['framework-language']
- Add end-to-end resolution tests for rust, cpp, and csharp verifying
  framework-language module is included in resolved moduleIds

Addresses review feedback from Copilot, Greptile, CodeRabbit, and Cubic.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>
This commit is contained in:
Chris Yau
2026-03-23 06:39:27 +08:00
committed by GitHub
parent 4f6f587700
commit 4e6b5cc19f
3 changed files with 50 additions and 0 deletions

View File

@@ -210,6 +210,14 @@
"framework-language" "framework-language"
] ]
}, },
{
"id": "lang:csharp",
"family": "language",
"description": "C# coding standards and patterns guidance. Currently resolves through the shared framework-language module.",
"modules": [
"framework-language"
]
},
{ {
"id": "framework:laravel", "id": "framework:laravel",
"family": "framework", "family": "framework",

View File

@@ -37,6 +37,8 @@ const LEGACY_COMPAT_BASE_MODULE_IDS_BY_TARGET = Object.freeze({
], ],
}); });
const LEGACY_LANGUAGE_ALIAS_TO_CANONICAL = Object.freeze({ const LEGACY_LANGUAGE_ALIAS_TO_CANONICAL = Object.freeze({
cpp: 'cpp',
csharp: 'csharp',
go: 'go', go: 'go',
golang: 'go', golang: 'go',
java: 'java', java: 'java',
@@ -45,15 +47,19 @@ const LEGACY_LANGUAGE_ALIAS_TO_CANONICAL = Object.freeze({
perl: 'perl', perl: 'perl',
php: 'php', php: 'php',
python: 'python', python: 'python',
rust: 'rust',
swift: 'swift', swift: 'swift',
typescript: 'typescript', typescript: 'typescript',
}); });
const LEGACY_LANGUAGE_EXTRA_MODULE_IDS = Object.freeze({ const LEGACY_LANGUAGE_EXTRA_MODULE_IDS = Object.freeze({
cpp: ['framework-language'],
csharp: ['framework-language'],
go: ['framework-language'], go: ['framework-language'],
java: ['framework-language'], java: ['framework-language'],
perl: [], perl: [],
php: [], php: [],
python: ['framework-language'], python: ['framework-language'],
rust: ['framework-language'],
swift: [], swift: [],
typescript: ['framework-language'], typescript: ['framework-language'],
}); });

View File

@@ -85,6 +85,9 @@ function runTests() {
assert.ok(languages.includes('go')); assert.ok(languages.includes('go'));
assert.ok(languages.includes('golang')); assert.ok(languages.includes('golang'));
assert.ok(languages.includes('kotlin')); assert.ok(languages.includes('kotlin'));
assert.ok(languages.includes('rust'));
assert.ok(languages.includes('cpp'));
assert.ok(languages.includes('csharp'));
})) passed++; else failed++; })) passed++; else failed++;
if (test('resolves a real project profile with target-specific skips', () => { if (test('resolves a real project profile with target-specific skips', () => {
@@ -155,6 +158,39 @@ function runTests() {
assert.ok(selection.moduleIds.includes('framework-language')); assert.ok(selection.moduleIds.includes('framework-language'));
})) passed++; else failed++; })) passed++; else failed++;
if (test('resolves rust legacy compatibility into framework-language module', () => {
const selection = resolveLegacyCompatibilitySelection({
target: 'cursor',
legacyLanguages: ['rust'],
});
assert.ok(selection.moduleIds.includes('rules-core'));
assert.ok(selection.moduleIds.includes('framework-language'),
'rust should resolve to framework-language module');
})) passed++; else failed++;
if (test('resolves cpp legacy compatibility into framework-language module', () => {
const selection = resolveLegacyCompatibilitySelection({
target: 'cursor',
legacyLanguages: ['cpp'],
});
assert.ok(selection.moduleIds.includes('rules-core'));
assert.ok(selection.moduleIds.includes('framework-language'),
'cpp should resolve to framework-language module');
})) passed++; else failed++;
if (test('resolves csharp legacy compatibility into framework-language module', () => {
const selection = resolveLegacyCompatibilitySelection({
target: 'cursor',
legacyLanguages: ['csharp'],
});
assert.ok(selection.moduleIds.includes('rules-core'));
assert.ok(selection.moduleIds.includes('framework-language'),
'csharp should resolve to framework-language module');
})) passed++; else failed++;
if (test('keeps antigravity legacy compatibility selections target-safe', () => { if (test('keeps antigravity legacy compatibility selections target-safe', () => {
const selection = resolveLegacyCompatibilitySelection({ const selection = resolveLegacyCompatibilitySelection({
target: 'antigravity', target: 'antigravity',