From a4c74c869d32c9e1e7c85c24e5d9587ca69b8a3f Mon Sep 17 00:00:00 2001 From: sck_0 Date: Sat, 14 Feb 2026 09:46:41 +0100 Subject: [PATCH] fix: quote scoped package names in skill frontmatter and update validator (#79) - Wrapped unquoted @scope/pkg values in double quotes across 19 SKILL.md files. - Added 'package' to ALLOWED_FIELDS in JS validator. - Added YAML validity regression test to test suite. - Updated package-lock.json. Fixes #79 Closes #80 --- package-lock.json | 4 +- .../tests/validate_skills_headings.test.js | 41 +++- scripts/validate-skills.js | 186 ++++++++++++------ skills/azure-ai-contentsafety-ts/SKILL.md | 2 +- .../SKILL.md | 2 +- skills/azure-ai-projects-ts/SKILL.md | 2 +- skills/azure-ai-translation-ts/SKILL.md | 2 +- skills/azure-ai-voicelive-ts/SKILL.md | 2 +- skills/azure-appconfiguration-ts/SKILL.md | 2 +- skills/azure-cosmos-ts/SKILL.md | 2 +- skills/azure-eventhub-ts/SKILL.md | 2 +- skills/azure-identity-ts/SKILL.md | 2 +- skills/azure-keyvault-keys-ts/SKILL.md | 2 +- skills/azure-keyvault-secrets-ts/SKILL.md | 2 +- .../azure-monitor-opentelemetry-ts/SKILL.md | 2 +- skills/azure-search-documents-ts/SKILL.md | 2 +- skills/azure-servicebus-ts/SKILL.md | 2 +- skills/azure-storage-blob-ts/SKILL.md | 2 +- skills/azure-storage-file-share-ts/SKILL.md | 2 +- skills/azure-storage-queue-ts/SKILL.md | 2 +- skills/azure-web-pubsub-ts/SKILL.md | 2 +- skills/m365-agents-ts/SKILL.md | 2 +- 22 files changed, 180 insertions(+), 89 deletions(-) diff --git a/package-lock.json b/package-lock.json index ea55527d..e2e0e980 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "antigravity-awesome-skills", - "version": "5.2.0", + "version": "5.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "antigravity-awesome-skills", - "version": "5.2.0", + "version": "5.3.0", "license": "MIT", "bin": { "antigravity-awesome-skills": "bin/install.js" diff --git a/scripts/tests/validate_skills_headings.test.js b/scripts/tests/validate_skills_headings.test.js index e980cd7d..d698b51d 100644 --- a/scripts/tests/validate_skills_headings.test.js +++ b/scripts/tests/validate_skills_headings.test.js @@ -1,11 +1,11 @@ -const assert = require('assert'); -const { hasUseSection } = require('../validate-skills'); +const assert = require("assert"); +const { hasUseSection } = require("../validate-skills"); const samples = [ - ['## When to Use', true], - ['## Use this skill when', true], - ['## When to Use This Skill', true], - ['## Overview', false], + ["## When to Use", true], + ["## Use this skill when", true], + ["## When to Use This Skill", true], + ["## Overview", false], ]; for (const [heading, expected] of samples) { @@ -13,4 +13,31 @@ for (const [heading, expected] of samples) { assert.strictEqual(hasUseSection(content), expected, heading); } -console.log('ok'); +// Regression test for YAML validity in frontmatter (Issue #79) +const fs = require("fs"); +const path = require("path"); +const { listSkillIds, parseFrontmatter } = require("../../lib/skill-utils"); + +const SKILLS_DIR = path.join(__dirname, "../../skills"); +const skillIds = listSkillIds(SKILLS_DIR); + +console.log(`Checking YAML validity for ${skillIds.length} skills...`); + +for (const skillId of skillIds) { + const skillPath = path.join(SKILLS_DIR, skillId, "SKILL.md"); + const content = fs.readFileSync(skillPath, "utf8"); + const { errors, hasFrontmatter } = parseFrontmatter(content); + + if (!hasFrontmatter) { + console.warn(`[WARN] No frontmatter in ${skillId}`); + continue; + } + + assert.strictEqual( + errors.length, + 0, + `YAML parse errors in ${skillId}: ${errors.join(", ")}`, + ); +} + +console.log("ok"); diff --git a/scripts/validate-skills.js b/scripts/validate-skills.js index 77318324..606a4867 100644 --- a/scripts/validate-skills.js +++ b/scripts/validate-skills.js @@ -2,13 +2,13 @@ * Legacy / alternative validator. For CI and PR checks, use scripts/validate_skills.py. * Run: npm run validate (or npm run validate:strict) */ -const fs = require('fs'); -const path = require('path'); -const { listSkillIds, parseFrontmatter } = require('../lib/skill-utils'); +const fs = require("fs"); +const path = require("path"); +const { listSkillIds, parseFrontmatter } = require("../lib/skill-utils"); -const ROOT = path.resolve(__dirname, '..'); -const SKILLS_DIR = path.join(ROOT, 'skills'); -const BASELINE_PATH = path.join(ROOT, 'validation-baseline.json'); +const ROOT = path.resolve(__dirname, ".."); +const SKILLS_DIR = path.join(ROOT, "skills"); +const BASELINE_PATH = path.join(ROOT, "validation-baseline.json"); const errors = []; const warnings = []; @@ -17,12 +17,14 @@ const missingDoNotUseSection = []; const missingInstructionsSection = []; const longFiles = []; const unknownFieldSkills = []; -const isStrict = process.argv.includes('--strict') - || process.env.STRICT === '1' - || process.env.STRICT === 'true'; -const writeBaseline = process.argv.includes('--write-baseline') - || process.env.WRITE_BASELINE === '1' - || process.env.WRITE_BASELINE === 'true'; +const isStrict = + process.argv.includes("--strict") || + process.env.STRICT === "1" || + process.env.STRICT === "true"; +const writeBaseline = + process.argv.includes("--write-baseline") || + process.env.WRITE_BASELINE === "1" || + process.env.WRITE_BASELINE === "true"; const NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/; const MAX_NAME_LENGTH = 64; @@ -30,14 +32,15 @@ const MAX_DESCRIPTION_LENGTH = 1024; const MAX_COMPATIBILITY_LENGTH = 500; const MAX_SKILL_LINES = 500; const ALLOWED_FIELDS = new Set([ - 'name', - 'description', - 'risk', - 'source', - 'license', - 'compatibility', - 'metadata', - 'allowed-tools', + "name", + "description", + "risk", + "source", + "license", + "compatibility", + "metadata", + "allowed-tools", + "package", ]); const USE_SECTION_PATTERNS = [ @@ -47,15 +50,19 @@ const USE_SECTION_PATTERNS = [ ]; function hasUseSection(content) { - return USE_SECTION_PATTERNS.some(pattern => pattern.test(content)); + return USE_SECTION_PATTERNS.some((pattern) => pattern.test(content)); } function isPlainObject(value) { - return value && typeof value === 'object' && !Array.isArray(value); + return value && typeof value === "object" && !Array.isArray(value); } -function validateStringField(fieldName, value, { min = 1, max = Infinity } = {}) { - if (typeof value !== 'string') { +function validateStringField( + fieldName, + value, + { min = 1, max = Infinity } = {}, +) { + if (typeof value !== "string") { return `${fieldName} must be a string.`; } const trimmed = value.trim(); @@ -90,24 +97,37 @@ function loadBaseline() { } try { - const parsed = JSON.parse(fs.readFileSync(BASELINE_PATH, 'utf8')); + const parsed = JSON.parse(fs.readFileSync(BASELINE_PATH, "utf8")); return { useSection: Array.isArray(parsed.useSection) ? parsed.useSection : [], - doNotUseSection: Array.isArray(parsed.doNotUseSection) ? parsed.doNotUseSection : [], - instructionsSection: Array.isArray(parsed.instructionsSection) ? parsed.instructionsSection : [], + doNotUseSection: Array.isArray(parsed.doNotUseSection) + ? parsed.doNotUseSection + : [], + instructionsSection: Array.isArray(parsed.instructionsSection) + ? parsed.instructionsSection + : [], longFile: Array.isArray(parsed.longFile) ? parsed.longFile : [], }; } catch (err) { - addWarning('Failed to parse validation-baseline.json; strict mode may fail.'); - return { useSection: [], doNotUseSection: [], instructionsSection: [], longFile: [] }; + addWarning( + "Failed to parse validation-baseline.json; strict mode may fail.", + ); + return { + useSection: [], + doNotUseSection: [], + instructionsSection: [], + longFile: [], + }; } } function addStrictSectionErrors(label, missing, baselineSet) { if (!isStrict) return; - const strictMissing = missing.filter(skillId => !baselineSet.has(skillId)); + const strictMissing = missing.filter((skillId) => !baselineSet.has(skillId)); if (strictMissing.length) { - addError(`Missing "${label}" section (strict): ${strictMissing.length} skills (examples: ${strictMissing.slice(0, 5).join(', ')})`); + addError( + `Missing "${label}" section (strict): ${strictMissing.length} skills (examples: ${strictMissing.slice(0, 5).join(", ")})`, + ); } } @@ -120,15 +140,19 @@ function run() { const baselineLongFile = new Set(baseline.longFile || []); for (const skillId of skillIds) { - const skillPath = path.join(SKILLS_DIR, skillId, 'SKILL.md'); + const skillPath = path.join(SKILLS_DIR, skillId, "SKILL.md"); if (!fs.existsSync(skillPath)) { addError(`Missing SKILL.md: ${skillId}`); continue; } - const content = fs.readFileSync(skillPath, 'utf8'); - const { data, errors: fmErrors, hasFrontmatter } = parseFrontmatter(content); + const content = fs.readFileSync(skillPath, "utf8"); + const { + data, + errors: fmErrors, + hasFrontmatter, + } = parseFrontmatter(content); const lineCount = content.split(/\r?\n/).length; if (!hasFrontmatter) { @@ -136,7 +160,9 @@ function run() { } if (fmErrors && fmErrors.length) { - fmErrors.forEach(error => addError(`Frontmatter parse error (${skillId}): ${error}`)); + fmErrors.forEach((error) => + addError(`Frontmatter parse error (${skillId}): ${error}`), + ); } if (!NAME_PATTERN.test(skillId)) { @@ -144,7 +170,10 @@ function run() { } if (data.name !== undefined) { - const nameError = validateStringField('name', data.name, { min: 1, max: MAX_NAME_LENGTH }); + const nameError = validateStringField("name", data.name, { + min: 1, + max: MAX_NAME_LENGTH, + }); if (nameError) { addError(`${nameError} (${skillId})`); } else { @@ -158,15 +187,22 @@ function run() { } } - const descError = data.description === undefined - ? 'description is required.' - : validateStringField('description', data.description, { min: 1, max: MAX_DESCRIPTION_LENGTH }); + const descError = + data.description === undefined + ? "description is required." + : validateStringField("description", data.description, { + min: 1, + max: MAX_DESCRIPTION_LENGTH, + }); if (descError) { addError(`${descError} (${skillId})`); } if (data.license !== undefined) { - const licenseError = validateStringField('license', data.license, { min: 1, max: 128 }); + const licenseError = validateStringField("license", data.license, { + min: 1, + max: 128, + }); if (licenseError) { addError(`${licenseError} (${skillId})`); } @@ -174,7 +210,7 @@ function run() { if (data.compatibility !== undefined) { const compatibilityError = validateStringField( - 'compatibility', + "compatibility", data.compatibility, { min: 1, max: MAX_COMPATIBILITY_LENGTH }, ); @@ -183,10 +219,12 @@ function run() { } } - if (data['allowed-tools'] !== undefined) { - if (typeof data['allowed-tools'] !== 'string') { - addError(`allowed-tools must be a space-delimited string. (${skillId})`); - } else if (!data['allowed-tools'].trim()) { + if (data["allowed-tools"] !== undefined) { + if (typeof data["allowed-tools"] !== "string") { + addError( + `allowed-tools must be a space-delimited string. (${skillId})`, + ); + } else if (!data["allowed-tools"].trim()) { addError(`allowed-tools cannot be empty. (${skillId})`); } } @@ -196,7 +234,7 @@ function run() { addError(`metadata must be a string map/object. (${skillId})`); } else { for (const [key, value] of Object.entries(data.metadata)) { - if (typeof value !== 'string') { + if (typeof value !== "string") { addError(`metadata.${key} must be a string. (${skillId})`); } } @@ -204,10 +242,14 @@ function run() { } if (data && Object.keys(data).length) { - const unknownFields = Object.keys(data).filter(key => !ALLOWED_FIELDS.has(key)); + const unknownFields = Object.keys(data).filter( + (key) => !ALLOWED_FIELDS.has(key), + ); if (unknownFields.length) { unknownFieldSkills.push(skillId); - addError(`Unknown frontmatter fields (${skillId}): ${unknownFields.join(', ')}`); + addError( + `Unknown frontmatter fields (${skillId}): ${unknownFields.join(", ")}`, + ); } } @@ -219,39 +261,61 @@ function run() { missingUseSection.push(skillId); } - if (!content.includes('## Do not use')) { + if (!content.includes("## Do not use")) { missingDoNotUseSection.push(skillId); } - if (!content.includes('## Instructions')) { + if (!content.includes("## Instructions")) { missingInstructionsSection.push(skillId); } } if (missingUseSection.length) { - addWarning(`Missing "Use this skill when" section: ${missingUseSection.length} skills (examples: ${missingUseSection.slice(0, 5).join(', ')})`); + addWarning( + `Missing "Use this skill when" section: ${missingUseSection.length} skills (examples: ${missingUseSection.slice(0, 5).join(", ")})`, + ); } if (missingDoNotUseSection.length) { - addWarning(`Missing "Do not use" section: ${missingDoNotUseSection.length} skills (examples: ${missingDoNotUseSection.slice(0, 5).join(', ')})`); + addWarning( + `Missing "Do not use" section: ${missingDoNotUseSection.length} skills (examples: ${missingDoNotUseSection.slice(0, 5).join(", ")})`, + ); } if (missingInstructionsSection.length) { - addWarning(`Missing "Instructions" section: ${missingInstructionsSection.length} skills (examples: ${missingInstructionsSection.slice(0, 5).join(', ')})`); + addWarning( + `Missing "Instructions" section: ${missingInstructionsSection.length} skills (examples: ${missingInstructionsSection.slice(0, 5).join(", ")})`, + ); } if (longFiles.length) { - addWarning(`SKILL.md over ${MAX_SKILL_LINES} lines: ${longFiles.length} skills (examples: ${longFiles.slice(0, 5).join(', ')})`); + addWarning( + `SKILL.md over ${MAX_SKILL_LINES} lines: ${longFiles.length} skills (examples: ${longFiles.slice(0, 5).join(", ")})`, + ); } if (unknownFieldSkills.length) { - addWarning(`Unknown frontmatter fields detected: ${unknownFieldSkills.length} skills (examples: ${unknownFieldSkills.slice(0, 5).join(', ')})`); + addWarning( + `Unknown frontmatter fields detected: ${unknownFieldSkills.length} skills (examples: ${unknownFieldSkills.slice(0, 5).join(", ")})`, + ); } - addStrictSectionErrors('Use this skill when', missingUseSection, baselineUse); - addStrictSectionErrors('Do not use', missingDoNotUseSection, baselineDoNotUse); - addStrictSectionErrors('Instructions', missingInstructionsSection, baselineInstructions); - addStrictSectionErrors(`SKILL.md line count <= ${MAX_SKILL_LINES}`, longFiles, baselineLongFile); + addStrictSectionErrors("Use this skill when", missingUseSection, baselineUse); + addStrictSectionErrors( + "Do not use", + missingDoNotUseSection, + baselineDoNotUse, + ); + addStrictSectionErrors( + "Instructions", + missingInstructionsSection, + baselineInstructions, + ); + addStrictSectionErrors( + `SKILL.md line count <= ${MAX_SKILL_LINES}`, + longFiles, + baselineLongFile, + ); if (writeBaseline) { const baselineData = { @@ -266,14 +330,14 @@ function run() { } if (warnings.length) { - console.warn('Warnings:'); + console.warn("Warnings:"); for (const warning of warnings) { console.warn(`- ${warning}`); } } if (errors.length) { - console.error('\nErrors:'); + console.error("\nErrors:"); for (const error of errors) { console.error(`- ${error}`); } diff --git a/skills/azure-ai-contentsafety-ts/SKILL.md b/skills/azure-ai-contentsafety-ts/SKILL.md index 89085b61..89b64c57 100644 --- a/skills/azure-ai-contentsafety-ts/SKILL.md +++ b/skills/azure-ai-contentsafety-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-ai-contentsafety-ts description: Analyze text and images for harmful content using Azure AI Content Safety (@azure-rest/ai-content-safety). Use when moderating user-generated content, detecting hate speech, violence, sexual content, or self-harm, or managing custom blocklists. -package: @azure-rest/ai-content-safety +package: "@azure-rest/ai-content-safety" --- # Azure AI Content Safety REST SDK for TypeScript diff --git a/skills/azure-ai-document-intelligence-ts/SKILL.md b/skills/azure-ai-document-intelligence-ts/SKILL.md index 43f15f5f..91d3e54c 100644 --- a/skills/azure-ai-document-intelligence-ts/SKILL.md +++ b/skills/azure-ai-document-intelligence-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-ai-document-intelligence-ts description: Extract text, tables, and structured data from documents using Azure Document Intelligence (@azure-rest/ai-document-intelligence). Use when processing invoices, receipts, IDs, forms, or building custom document models. -package: @azure-rest/ai-document-intelligence +package: "@azure-rest/ai-document-intelligence" --- # Azure Document Intelligence REST SDK for TypeScript diff --git a/skills/azure-ai-projects-ts/SKILL.md b/skills/azure-ai-projects-ts/SKILL.md index ad622ddb..8c9fbc1b 100644 --- a/skills/azure-ai-projects-ts/SKILL.md +++ b/skills/azure-ai-projects-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-ai-projects-ts description: Build AI applications using Azure AI Projects SDK for JavaScript (@azure/ai-projects). Use when working with Foundry project clients, agents, connections, deployments, datasets, indexes, evaluations, or getting OpenAI clients. -package: @azure/ai-projects +package: "@azure/ai-projects" --- # Azure AI Projects SDK for TypeScript diff --git a/skills/azure-ai-translation-ts/SKILL.md b/skills/azure-ai-translation-ts/SKILL.md index ae826757..e232051a 100644 --- a/skills/azure-ai-translation-ts/SKILL.md +++ b/skills/azure-ai-translation-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-ai-translation-ts description: Build translation applications using Azure Translation SDKs for JavaScript (@azure-rest/ai-translation-text, @azure-rest/ai-translation-document). Use when implementing text translation, transliteration, language detection, or batch document translation. -package: @azure-rest/ai-translation-text, @azure-rest/ai-translation-document +package: "@azure-rest/ai-translation-text, @azure-rest/ai-translation-document" --- # Azure Translation SDKs for TypeScript diff --git a/skills/azure-ai-voicelive-ts/SKILL.md b/skills/azure-ai-voicelive-ts/SKILL.md index 57ff9f4f..8180affe 100644 --- a/skills/azure-ai-voicelive-ts/SKILL.md +++ b/skills/azure-ai-voicelive-ts/SKILL.md @@ -2,7 +2,7 @@ name: azure-ai-voicelive-ts description: | Azure AI Voice Live SDK for JavaScript/TypeScript. Build real-time voice AI applications with bidirectional WebSocket communication. Use for voice assistants, conversational AI, real-time speech-to-speech, and voice-enabled chatbots in Node.js or browser environments. Triggers: "voice live", "real-time voice", "VoiceLiveClient", "VoiceLiveSession", "voice assistant TypeScript", "bidirectional audio", "speech-to-speech JavaScript". -package: @azure/ai-voicelive +package: "@azure/ai-voicelive" --- # @azure/ai-voicelive (JavaScript/TypeScript) diff --git a/skills/azure-appconfiguration-ts/SKILL.md b/skills/azure-appconfiguration-ts/SKILL.md index 8988c46d..2a388473 100644 --- a/skills/azure-appconfiguration-ts/SKILL.md +++ b/skills/azure-appconfiguration-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-appconfiguration-ts description: Build applications using Azure App Configuration SDK for JavaScript (@azure/app-configuration). Use when working with configuration settings, feature flags, Key Vault references, dynamic refresh, or centralized configuration management. -package: @azure/app-configuration +package: "@azure/app-configuration" --- # Azure App Configuration SDK for TypeScript diff --git a/skills/azure-cosmos-ts/SKILL.md b/skills/azure-cosmos-ts/SKILL.md index acaa4998..9f408754 100644 --- a/skills/azure-cosmos-ts/SKILL.md +++ b/skills/azure-cosmos-ts/SKILL.md @@ -2,7 +2,7 @@ name: azure-cosmos-ts description: | Azure Cosmos DB JavaScript/TypeScript SDK (@azure/cosmos) for data plane operations. Use for CRUD operations on documents, queries, bulk operations, and container management. Triggers: "Cosmos DB", "@azure/cosmos", "CosmosClient", "document CRUD", "NoSQL queries", "bulk operations", "partition key", "container.items". -package: @azure/cosmos +package: "@azure/cosmos" --- # @azure/cosmos (TypeScript/JavaScript) diff --git a/skills/azure-eventhub-ts/SKILL.md b/skills/azure-eventhub-ts/SKILL.md index c8ea7ac3..1626a34e 100644 --- a/skills/azure-eventhub-ts/SKILL.md +++ b/skills/azure-eventhub-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-eventhub-ts description: Build event streaming applications using Azure Event Hubs SDK for JavaScript (@azure/event-hubs). Use when implementing high-throughput event ingestion, real-time analytics, IoT telemetry, or event-driven architectures with partitioned consumers. -package: @azure/event-hubs +package: "@azure/event-hubs" --- # Azure Event Hubs SDK for TypeScript diff --git a/skills/azure-identity-ts/SKILL.md b/skills/azure-identity-ts/SKILL.md index 9310a947..05ef7358 100644 --- a/skills/azure-identity-ts/SKILL.md +++ b/skills/azure-identity-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-identity-ts description: Authenticate to Azure services using Azure Identity SDK for JavaScript (@azure/identity). Use when configuring authentication with DefaultAzureCredential, managed identity, service principals, or interactive browser login. -package: @azure/identity +package: "@azure/identity" --- # Azure Identity SDK for TypeScript diff --git a/skills/azure-keyvault-keys-ts/SKILL.md b/skills/azure-keyvault-keys-ts/SKILL.md index 49249cf2..d439ef22 100644 --- a/skills/azure-keyvault-keys-ts/SKILL.md +++ b/skills/azure-keyvault-keys-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-keyvault-keys-ts description: Manage cryptographic keys using Azure Key Vault Keys SDK for JavaScript (@azure/keyvault-keys). Use when creating, encrypting/decrypting, signing, or rotating keys. -package: @azure/keyvault-keys +package: "@azure/keyvault-keys" --- # Azure Key Vault Keys SDK for TypeScript diff --git a/skills/azure-keyvault-secrets-ts/SKILL.md b/skills/azure-keyvault-secrets-ts/SKILL.md index 7bbda886..5ceb3416 100644 --- a/skills/azure-keyvault-secrets-ts/SKILL.md +++ b/skills/azure-keyvault-secrets-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-keyvault-secrets-ts description: Manage secrets using Azure Key Vault Secrets SDK for JavaScript (@azure/keyvault-secrets). Use when storing and retrieving application secrets or configuration values. -package: @azure/keyvault-secrets +package: "@azure/keyvault-secrets" --- # Azure Key Vault Secrets SDK for TypeScript diff --git a/skills/azure-monitor-opentelemetry-ts/SKILL.md b/skills/azure-monitor-opentelemetry-ts/SKILL.md index 265dcd75..ec450a88 100644 --- a/skills/azure-monitor-opentelemetry-ts/SKILL.md +++ b/skills/azure-monitor-opentelemetry-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-monitor-opentelemetry-ts description: Instrument applications with Azure Monitor and OpenTelemetry for JavaScript (@azure/monitor-opentelemetry). Use when adding distributed tracing, metrics, and logs to Node.js applications with Application Insights. -package: @azure/monitor-opentelemetry +package: "@azure/monitor-opentelemetry" --- # Azure Monitor OpenTelemetry SDK for TypeScript diff --git a/skills/azure-search-documents-ts/SKILL.md b/skills/azure-search-documents-ts/SKILL.md index 1194e9de..c35b2085 100644 --- a/skills/azure-search-documents-ts/SKILL.md +++ b/skills/azure-search-documents-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-search-documents-ts description: Build search applications using Azure AI Search SDK for JavaScript (@azure/search-documents). Use when creating/managing indexes, implementing vector/hybrid search, semantic ranking, or building agentic retrieval with knowledge bases. -package: @azure/search-documents +package: "@azure/search-documents" --- # Azure AI Search SDK for TypeScript diff --git a/skills/azure-servicebus-ts/SKILL.md b/skills/azure-servicebus-ts/SKILL.md index e170072f..9240f31c 100644 --- a/skills/azure-servicebus-ts/SKILL.md +++ b/skills/azure-servicebus-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-servicebus-ts description: Build messaging applications using Azure Service Bus SDK for JavaScript (@azure/service-bus). Use when implementing queues, topics/subscriptions, message sessions, dead-letter handling, or enterprise messaging patterns. -package: @azure/service-bus +package: "@azure/service-bus" --- # Azure Service Bus SDK for TypeScript diff --git a/skills/azure-storage-blob-ts/SKILL.md b/skills/azure-storage-blob-ts/SKILL.md index eadccfb3..24bab504 100644 --- a/skills/azure-storage-blob-ts/SKILL.md +++ b/skills/azure-storage-blob-ts/SKILL.md @@ -2,7 +2,7 @@ name: azure-storage-blob-ts description: | Azure Blob Storage JavaScript/TypeScript SDK (@azure/storage-blob) for blob operations. Use for uploading, downloading, listing, and managing blobs and containers. Supports block blobs, append blobs, page blobs, SAS tokens, and streaming. Triggers: "blob storage", "@azure/storage-blob", "BlobServiceClient", "ContainerClient", "upload blob", "download blob", "SAS token", "block blob". -package: @azure/storage-blob +package: "@azure/storage-blob" --- # @azure/storage-blob (TypeScript/JavaScript) diff --git a/skills/azure-storage-file-share-ts/SKILL.md b/skills/azure-storage-file-share-ts/SKILL.md index 231cc2e7..501e06d9 100644 --- a/skills/azure-storage-file-share-ts/SKILL.md +++ b/skills/azure-storage-file-share-ts/SKILL.md @@ -2,7 +2,7 @@ name: azure-storage-file-share-ts description: | Azure File Share JavaScript/TypeScript SDK (@azure/storage-file-share) for SMB file share operations. Use for creating shares, managing directories, uploading/downloading files, and handling file metadata. Supports Azure Files SMB protocol scenarios. Triggers: "file share", "@azure/storage-file-share", "ShareServiceClient", "ShareClient", "SMB", "Azure Files". -package: @azure/storage-file-share +package: "@azure/storage-file-share" --- # @azure/storage-file-share (TypeScript/JavaScript) diff --git a/skills/azure-storage-queue-ts/SKILL.md b/skills/azure-storage-queue-ts/SKILL.md index 304c9f03..8e63d5bb 100644 --- a/skills/azure-storage-queue-ts/SKILL.md +++ b/skills/azure-storage-queue-ts/SKILL.md @@ -2,7 +2,7 @@ name: azure-storage-queue-ts description: | Azure Queue Storage JavaScript/TypeScript SDK (@azure/storage-queue) for message queue operations. Use for sending, receiving, peeking, and deleting messages in queues. Supports visibility timeout, message encoding, and batch operations. Triggers: "queue storage", "@azure/storage-queue", "QueueServiceClient", "QueueClient", "send message", "receive message", "dequeue", "visibility timeout". -package: @azure/storage-queue +package: "@azure/storage-queue" --- # @azure/storage-queue (TypeScript/JavaScript) diff --git a/skills/azure-web-pubsub-ts/SKILL.md b/skills/azure-web-pubsub-ts/SKILL.md index 24a9d056..c3498744 100644 --- a/skills/azure-web-pubsub-ts/SKILL.md +++ b/skills/azure-web-pubsub-ts/SKILL.md @@ -1,7 +1,7 @@ --- name: azure-web-pubsub-ts description: Build real-time messaging applications using Azure Web PubSub SDKs for JavaScript (@azure/web-pubsub, @azure/web-pubsub-client). Use when implementing WebSocket-based real-time features, pub/sub messaging, group chat, or live notifications. -package: @azure/web-pubsub, @azure/web-pubsub-client +package: "@azure/web-pubsub, @azure/web-pubsub-client" --- # Azure Web PubSub SDKs for TypeScript diff --git a/skills/m365-agents-ts/SKILL.md b/skills/m365-agents-ts/SKILL.md index b45f7306..c596b9be 100644 --- a/skills/m365-agents-ts/SKILL.md +++ b/skills/m365-agents-ts/SKILL.md @@ -2,7 +2,7 @@ name: m365-agents-ts description: | Microsoft 365 Agents SDK for TypeScript/Node.js. Build multichannel agents for Teams/M365/Copilot Studio with AgentApplication routing, Express hosting, streaming responses, and Copilot Studio client integration. Triggers: "Microsoft 365 Agents SDK", "@microsoft/agents-hosting", "AgentApplication", "startServer", "streamingResponse", "Copilot Studio client", "@microsoft/agents-copilotstudio-client". -package: @microsoft/agents-hosting, @microsoft/agents-hosting-express, @microsoft/agents-activity, @microsoft/agents-copilotstudio-client +package: "@microsoft/agents-hosting, @microsoft/agents-hosting-express, @microsoft/agents-activity, @microsoft/agents-copilotstudio-client" --- # Microsoft 365 Agents SDK (TypeScript)