feat(skills): add 11 new skill packs covering major frameworks and languages
New skill packs with auto-detection: - Java & Spring Boot (github/awesome-copilot, 9.1K installs) - .NET & C# (github/awesome-copilot, 8.1K installs) — scans for *.csproj/*.sln - Flutter (flutter/skills, official, 54.6K total) - Angular (analogjs/angular-skills, official, 33.5K total) - Vue.js (vuejs-ai/skills, official, 30.7K total) — triggers on nuxt.config.* - Svelte (sveltejs/ai-tools, official, 3.1K total) - Next.js (vercel-labs/vercel-plugin, official) — triggers on next.config.* - Docker (github/awesome-copilot, 8.3K installs) - Terraform (hashicorp/agent-skills, official, 9.4K total) - Django (vintasoftware/django-ai-plugins, 2.2K total) - PHP & Laravel (jeffallan/claude-skills, 10.1K total) Detection additions: - PROJECT_FILES: angular.json, next.config.*, nuxt.config.*, svelte.config.*, Dockerfile, docker-compose.*, main.tf, manage.py, requirements.txt - Extension scanning: *.csproj/*.sln/*.fsproj for .NET detection - LANGUAGE_MAP: manage.py and requirements.txt → python - GREENFIELD_STACKS: Angular, Vue, Svelte, Next.js, Flutter, Java, .NET, PHP, Django entries - 8 new detection tests (36 total, up from 28)
This commit is contained in:
parent
a30b125020
commit
3a35eae883
3 changed files with 286 additions and 3 deletions
|
|
@ -109,6 +109,24 @@ export const PROJECT_FILES = [
|
|||
"metro.config.js",
|
||||
"metro.config.ts",
|
||||
"react-native.config.js",
|
||||
// Frontend framework config files
|
||||
"angular.json",
|
||||
"next.config.js",
|
||||
"next.config.ts",
|
||||
"next.config.mjs",
|
||||
"nuxt.config.ts",
|
||||
"nuxt.config.js",
|
||||
"svelte.config.js",
|
||||
"svelte.config.ts",
|
||||
// Container / DevOps config files
|
||||
"Dockerfile",
|
||||
"docker-compose.yml",
|
||||
"docker-compose.yaml",
|
||||
// Infrastructure as Code
|
||||
"main.tf",
|
||||
// Python framework markers
|
||||
"manage.py",
|
||||
"requirements.txt",
|
||||
] as const;
|
||||
|
||||
/** File extensions that indicate SQLite databases in the project. */
|
||||
|
|
@ -117,6 +135,9 @@ const SQLITE_EXTENSIONS = [".sqlite", ".sqlite3", ".db"] as const;
|
|||
/** File extensions that indicate SQL usage (migrations, schemas, seeds). */
|
||||
const SQL_EXTENSIONS = [".sql"] as const;
|
||||
|
||||
/** File extensions that indicate .NET / C# projects. */
|
||||
const DOTNET_EXTENSIONS = [".csproj", ".sln", ".fsproj"] as const;
|
||||
|
||||
const LANGUAGE_MAP: Record<string, string> = {
|
||||
"package.json": "javascript/typescript",
|
||||
"Cargo.toml": "rust",
|
||||
|
|
@ -134,6 +155,8 @@ const LANGUAGE_MAP: Record<string, string> = {
|
|||
"mix.exs": "elixir",
|
||||
"deno.json": "typescript/deno",
|
||||
"deno.jsonc": "typescript/deno",
|
||||
"manage.py": "python",
|
||||
"requirements.txt": "python",
|
||||
};
|
||||
|
||||
const MONOREPO_MARKERS = [
|
||||
|
|
@ -289,9 +312,9 @@ export function detectProjectSignals(basePath: string): ProjectSignals {
|
|||
}
|
||||
}
|
||||
|
||||
// SQLite / SQL file detection — scan root entries for database file extensions.
|
||||
// Adds synthetic markers (e.g. "*.sqlite", "*.sql") to detectedFiles so
|
||||
// skill catalog matchFiles can reference them.
|
||||
// SQLite / SQL / .NET file detection — scan root entries for file extensions.
|
||||
// Adds synthetic markers (e.g. "*.sqlite", "*.sql", "*.csproj") to detectedFiles
|
||||
// so skill catalog matchFiles can reference them.
|
||||
try {
|
||||
const rootEntries = readdirSync(basePath);
|
||||
if (rootEntries.some((e) => SQLITE_EXTENSIONS.some((ext) => e.endsWith(ext)))) {
|
||||
|
|
@ -300,6 +323,10 @@ export function detectProjectSignals(basePath: string): ProjectSignals {
|
|||
if (rootEntries.some((e) => SQL_EXTENSIONS.some((ext) => e.endsWith(ext)))) {
|
||||
detectedFiles.push("*.sql");
|
||||
}
|
||||
if (rootEntries.some((e) => DOTNET_EXTENSIONS.some((ext) => e.endsWith(ext)))) {
|
||||
detectedFiles.push("*.csproj");
|
||||
if (!primaryLanguage) primaryLanguage = "csharp";
|
||||
}
|
||||
} catch {
|
||||
// unreadable root — skip extension scan
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,6 +202,98 @@ export const SKILL_CATALOG: SkillPack[] = [
|
|||
skills: ["frontend-design"],
|
||||
matchLanguages: ["javascript/typescript"],
|
||||
},
|
||||
// ── Angular ───────────────────────────────────────────────────────────────
|
||||
{
|
||||
label: "Angular",
|
||||
description: "Angular components, signals, forms, routing, and testing",
|
||||
repo: "analogjs/angular-skills",
|
||||
skills: [
|
||||
"angular-component",
|
||||
"angular-signals",
|
||||
"angular-forms",
|
||||
"angular-routing",
|
||||
"angular-testing",
|
||||
],
|
||||
matchFiles: ["angular.json"],
|
||||
},
|
||||
// ── Vue.js / Nuxt ────────────────────────────────────────────────────────
|
||||
{
|
||||
label: "Vue.js",
|
||||
description: "Vue best practices, Pinia state, Vue Router, and testing",
|
||||
repo: "vuejs-ai/skills",
|
||||
skills: [
|
||||
"vue-best-practices",
|
||||
"vue-pinia-best-practices",
|
||||
"vue-router-best-practices",
|
||||
"vue-testing-best-practices",
|
||||
],
|
||||
matchFiles: ["nuxt.config.ts", "nuxt.config.js"],
|
||||
},
|
||||
// ── Svelte / SvelteKit ────────────────────────────────────────────────────
|
||||
{
|
||||
label: "Svelte",
|
||||
description: "Svelte code patterns and SvelteKit best practices",
|
||||
repo: "sveltejs/ai-tools",
|
||||
skills: ["svelte-code-writer", "svelte-core-bestpractices"],
|
||||
matchFiles: ["svelte.config.js", "svelte.config.ts"],
|
||||
},
|
||||
// ── Next.js ───────────────────────────────────────────────────────────────
|
||||
{
|
||||
label: "Next.js",
|
||||
description: "Next.js app router, server components, and deployment patterns",
|
||||
repo: "vercel-labs/vercel-plugin",
|
||||
skills: ["nextjs"],
|
||||
matchFiles: ["next.config.js", "next.config.ts", "next.config.mjs"],
|
||||
},
|
||||
// ── Java / Spring Boot ────────────────────────────────────────────────────
|
||||
{
|
||||
label: "Java & Spring Boot",
|
||||
description: "Spring Boot best practices, DI, RESTful APIs, JPA, testing, and security",
|
||||
repo: "github/awesome-copilot",
|
||||
skills: ["java-springboot"],
|
||||
matchLanguages: ["java", "java/kotlin"],
|
||||
matchFiles: ["pom.xml", "build.gradle", "build.gradle.kts"],
|
||||
},
|
||||
// ── .NET / C# ────────────────────────────────────────────────────────────
|
||||
{
|
||||
label: ".NET & C#",
|
||||
description: ".NET best practices, design patterns, and upgrade guidance",
|
||||
repo: "github/awesome-copilot",
|
||||
skills: ["dotnet-best-practices", "dotnet-design-pattern-review"],
|
||||
matchLanguages: ["csharp"],
|
||||
matchFiles: ["*.csproj"],
|
||||
},
|
||||
// ── Flutter / Dart ────────────────────────────────────────────────────────
|
||||
{
|
||||
label: "Flutter",
|
||||
description: "Flutter layouts, architecture, state management, and testing",
|
||||
repo: "flutter/skills",
|
||||
skills: [
|
||||
"flutter-building-layouts",
|
||||
"flutter-architecting-apps",
|
||||
"flutter-managing-state",
|
||||
"flutter-testing-apps",
|
||||
],
|
||||
matchLanguages: ["dart/flutter"],
|
||||
matchFiles: ["pubspec.yaml"],
|
||||
},
|
||||
// ── PHP / Laravel ─────────────────────────────────────────────────────────
|
||||
{
|
||||
label: "PHP & Laravel",
|
||||
description: "Laravel patterns, PHP best practices, and testing",
|
||||
repo: "jeffallan/claude-skills",
|
||||
skills: ["laravel-specialist", "php-pro"],
|
||||
matchLanguages: ["php"],
|
||||
matchFiles: ["composer.json"],
|
||||
},
|
||||
// ── Django ────────────────────────────────────────────────────────────────
|
||||
{
|
||||
label: "Django",
|
||||
description: "Django expert patterns, models, views, and middleware",
|
||||
repo: "vintasoftware/django-ai-plugins",
|
||||
skills: ["django-expert"],
|
||||
matchFiles: ["manage.py"],
|
||||
},
|
||||
// ── Rust ──────────────────────────────────────────────────────────────────
|
||||
{
|
||||
label: "Rust",
|
||||
|
|
@ -303,6 +395,22 @@ export const SKILL_CATALOG: SkillPack[] = [
|
|||
skills: ["deploy", "aws-lambda", "aws-serverless-deployment"],
|
||||
matchFiles: ["cdk.json", "samconfig.toml", "serverless.yml", "serverless.yaml"],
|
||||
},
|
||||
// ── Container / DevOps ─────────────────────────────────────────────────────
|
||||
{
|
||||
label: "Docker",
|
||||
description: "Multi-stage Dockerfiles, layer optimization, and security hardening",
|
||||
repo: "github/awesome-copilot",
|
||||
skills: ["multi-stage-dockerfile"],
|
||||
matchFiles: ["Dockerfile", "docker-compose.yml", "docker-compose.yaml"],
|
||||
},
|
||||
// ── Infrastructure as Code ─────────────────────────────────────────────────
|
||||
{
|
||||
label: "Terraform",
|
||||
description: "Terraform style guide, testing, and stack patterns",
|
||||
repo: "hashicorp/agent-skills",
|
||||
skills: ["terraform-style-guide", "terraform-test", "terraform-stacks"],
|
||||
matchFiles: ["main.tf"],
|
||||
},
|
||||
// ── Essential (all projects) ────────────────────────────────────────────
|
||||
{
|
||||
label: "Skill Discovery",
|
||||
|
|
@ -427,6 +535,60 @@ export const GREENFIELD_STACKS: Array<{
|
|||
description: "Azure deployment, AI, storage, diagnostics",
|
||||
packs: ["Azure"],
|
||||
},
|
||||
{
|
||||
id: "angular",
|
||||
label: "Angular",
|
||||
description: "Angular components, signals, forms, routing",
|
||||
packs: ["Angular", "Frontend Design & UX"],
|
||||
},
|
||||
{
|
||||
id: "vue",
|
||||
label: "Vue.js / Nuxt",
|
||||
description: "Vue.js with Pinia, Vue Router, and testing",
|
||||
packs: ["Vue.js", "Frontend Design & UX"],
|
||||
},
|
||||
{
|
||||
id: "svelte",
|
||||
label: "Svelte / SvelteKit",
|
||||
description: "Svelte 5 and SvelteKit patterns",
|
||||
packs: ["Svelte", "Frontend Design & UX"],
|
||||
},
|
||||
{
|
||||
id: "nextjs",
|
||||
label: "Next.js",
|
||||
description: "Next.js app router, React, and Vercel deployment",
|
||||
packs: ["Next.js", "React & Web Frontend", "shadcn/ui"],
|
||||
},
|
||||
{
|
||||
id: "flutter",
|
||||
label: "Flutter",
|
||||
description: "Cross-platform Flutter/Dart development",
|
||||
packs: ["Flutter"],
|
||||
},
|
||||
{
|
||||
id: "java",
|
||||
label: "Java / Spring Boot",
|
||||
description: "Spring Boot APIs, JPA, and testing",
|
||||
packs: ["Java & Spring Boot"],
|
||||
},
|
||||
{
|
||||
id: "dotnet",
|
||||
label: ".NET / C#",
|
||||
description: "ASP.NET Core, Entity Framework, and design patterns",
|
||||
packs: [".NET & C#"],
|
||||
},
|
||||
{
|
||||
id: "php",
|
||||
label: "PHP / Laravel",
|
||||
description: "Laravel patterns and PHP best practices",
|
||||
packs: ["PHP & Laravel"],
|
||||
},
|
||||
{
|
||||
id: "django",
|
||||
label: "Django",
|
||||
description: "Django models, views, middleware, and Celery",
|
||||
packs: ["Django", "Python"],
|
||||
},
|
||||
{
|
||||
id: "other",
|
||||
label: "Other / Skip",
|
||||
|
|
|
|||
|
|
@ -441,3 +441,97 @@ test("detectProjectSignals: no SQLite markers without matching files", () => {
|
|||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
|
||||
test("detectProjectSignals: .NET project via .csproj extension", () => {
|
||||
const dir = makeTempDir("signals-dotnet");
|
||||
try {
|
||||
writeFileSync(join(dir, "MyApp.csproj"), "<Project></Project>", "utf-8");
|
||||
const signals = detectProjectSignals(dir);
|
||||
assert.ok(signals.detectedFiles.includes("*.csproj"), "should add synthetic *.csproj marker");
|
||||
assert.equal(signals.primaryLanguage, "csharp");
|
||||
} finally {
|
||||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
|
||||
test("detectProjectSignals: .NET project via .sln extension", () => {
|
||||
const dir = makeTempDir("signals-sln");
|
||||
try {
|
||||
writeFileSync(join(dir, "MyApp.sln"), "", "utf-8");
|
||||
const signals = detectProjectSignals(dir);
|
||||
assert.ok(signals.detectedFiles.includes("*.csproj"), "should add synthetic *.csproj marker for .sln files");
|
||||
} finally {
|
||||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
|
||||
test("detectProjectSignals: Angular project via angular.json", () => {
|
||||
const dir = makeTempDir("signals-angular");
|
||||
try {
|
||||
writeFileSync(join(dir, "angular.json"), "{}", "utf-8");
|
||||
writeFileSync(join(dir, "package.json"), "{}", "utf-8");
|
||||
const signals = detectProjectSignals(dir);
|
||||
assert.ok(signals.detectedFiles.includes("angular.json"));
|
||||
assert.equal(signals.primaryLanguage, "javascript/typescript");
|
||||
} finally {
|
||||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
|
||||
test("detectProjectSignals: Next.js project via next.config.ts", () => {
|
||||
const dir = makeTempDir("signals-nextjs");
|
||||
try {
|
||||
writeFileSync(join(dir, "next.config.ts"), "export default {}", "utf-8");
|
||||
writeFileSync(join(dir, "package.json"), "{}", "utf-8");
|
||||
const signals = detectProjectSignals(dir);
|
||||
assert.ok(signals.detectedFiles.includes("next.config.ts"));
|
||||
} finally {
|
||||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
|
||||
test("detectProjectSignals: Flutter project via pubspec.yaml", () => {
|
||||
const dir = makeTempDir("signals-flutter");
|
||||
try {
|
||||
writeFileSync(join(dir, "pubspec.yaml"), "name: my_app", "utf-8");
|
||||
const signals = detectProjectSignals(dir);
|
||||
assert.ok(signals.detectedFiles.includes("pubspec.yaml"));
|
||||
assert.equal(signals.primaryLanguage, "dart/flutter");
|
||||
} finally {
|
||||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
|
||||
test("detectProjectSignals: Django project via manage.py", () => {
|
||||
const dir = makeTempDir("signals-django");
|
||||
try {
|
||||
writeFileSync(join(dir, "manage.py"), "#!/usr/bin/env python", "utf-8");
|
||||
const signals = detectProjectSignals(dir);
|
||||
assert.ok(signals.detectedFiles.includes("manage.py"));
|
||||
assert.equal(signals.primaryLanguage, "python");
|
||||
} finally {
|
||||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
|
||||
test("detectProjectSignals: Docker project via Dockerfile", () => {
|
||||
const dir = makeTempDir("signals-docker");
|
||||
try {
|
||||
writeFileSync(join(dir, "Dockerfile"), "FROM node:18", "utf-8");
|
||||
const signals = detectProjectSignals(dir);
|
||||
assert.ok(signals.detectedFiles.includes("Dockerfile"));
|
||||
} finally {
|
||||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
|
||||
test("detectProjectSignals: Terraform project via main.tf", () => {
|
||||
const dir = makeTempDir("signals-terraform");
|
||||
try {
|
||||
writeFileSync(join(dir, "main.tf"), 'provider "aws" {}', "utf-8");
|
||||
const signals = detectProjectSignals(dir);
|
||||
assert.ok(signals.detectedFiles.includes("main.tf"));
|
||||
} finally {
|
||||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue