From 4bb7de1bdcd15f5839f9b4c681286ba531c7a337 Mon Sep 17 00:00:00 2001 From: Zhongwei Li Date: Sat, 29 Nov 2025 18:52:42 +0800 Subject: [PATCH] Initial commit --- .claude-plugin/plugin.json | 15 + README.md | 3 + commands/manage-api-versions.md | 903 ++++++++++++++++++ plugin.lock.json | 101 ++ skills/skill-adapter/assets/README.md | 8 + .../assets/api_version_template.json | 106 ++ .../assets/compatibility_test_suite.json | 110 +++ .../skill-adapter/assets/config-template.json | 32 + .../assets/deprecation_notice_template.md | 105 ++ .../assets/migration_guide_template.md | 122 +++ skills/skill-adapter/assets/skill-schema.json | 28 + skills/skill-adapter/assets/test-data.json | 27 + skills/skill-adapter/references/README.md | 8 + .../references/best-practices.md | 69 ++ skills/skill-adapter/references/examples.md | 70 ++ skills/skill-adapter/scripts/README.md | 8 + .../skill-adapter/scripts/helper-template.sh | 42 + skills/skill-adapter/scripts/validation.sh | 32 + 18 files changed, 1789 insertions(+) create mode 100644 .claude-plugin/plugin.json create mode 100644 README.md create mode 100644 commands/manage-api-versions.md create mode 100644 plugin.lock.json create mode 100644 skills/skill-adapter/assets/README.md create mode 100644 skills/skill-adapter/assets/api_version_template.json create mode 100644 skills/skill-adapter/assets/compatibility_test_suite.json create mode 100644 skills/skill-adapter/assets/config-template.json create mode 100644 skills/skill-adapter/assets/deprecation_notice_template.md create mode 100644 skills/skill-adapter/assets/migration_guide_template.md create mode 100644 skills/skill-adapter/assets/skill-schema.json create mode 100644 skills/skill-adapter/assets/test-data.json create mode 100644 skills/skill-adapter/references/README.md create mode 100644 skills/skill-adapter/references/best-practices.md create mode 100644 skills/skill-adapter/references/examples.md create mode 100644 skills/skill-adapter/scripts/README.md create mode 100755 skills/skill-adapter/scripts/helper-template.sh create mode 100755 skills/skill-adapter/scripts/validation.sh diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..649d83d --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,15 @@ +{ + "name": "api-versioning-manager", + "description": "Manage API versions with migration strategies and backward compatibility", + "version": "1.0.0", + "author": { + "name": "Jeremy Longshore", + "email": "[email protected]" + }, + "skills": [ + "./skills" + ], + "commands": [ + "./commands" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d29f747 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# api-versioning-manager + +Manage API versions with migration strategies and backward compatibility diff --git a/commands/manage-api-versions.md b/commands/manage-api-versions.md new file mode 100644 index 0000000..38d4d5d --- /dev/null +++ b/commands/manage-api-versions.md @@ -0,0 +1,903 @@ +--- +description: Manage API versions with proper migration strategies +shortcut: apiver +--- + +# Manage API Versions + +Implement comprehensive API versioning strategies with backward compatibility, smooth migration paths, deprecation workflows, and automated compatibility testing to ensure seamless API evolution. + +## When to Use This Command + +Use `/manage-api-versions` when you need to: +- Introduce breaking changes without disrupting existing clients +- Support multiple API versions simultaneously +- Provide smooth migration paths for API consumers +- Implement deprecation strategies with clear timelines +- Maintain backward compatibility while innovating +- Comply with enterprise SLA requirements + +DON'T use this when: +- Building internal-only APIs with controlled clients (coordinate directly) +- API is in early beta with no production users (iterate freely) +- Changes are purely additive and backward compatible (versioning unnecessary) + +## Design Decisions + +This command implements **URL Path Versioning + Accept Header** as the primary approach because: +- Most intuitive for developers (visible in URL) +- Easy to route and cache at infrastructure level +- Clear version separation in code organization +- Accept headers provide fine-grained control +- Works well with API gateways and CDNs +- Industry standard for REST APIs + +**Alternative considered: Header-Only Versioning** +- Cleaner URLs +- More RESTful approach +- Harder to test and debug +- Recommended for purist REST APIs + +**Alternative considered: Query Parameter Versioning** +- Easy to implement +- Optional versioning support +- Can pollute URL structure +- Recommended for simple versioning needs + +## Prerequisites + +Before running this command: +1. Define versioning strategy and policy +2. Identify breaking vs. non-breaking changes +3. Plan deprecation timeline (typically 6-12 months) +4. Set up monitoring for version usage +5. Prepare migration documentation + +## Implementation Process + +### Step 1: Choose Versioning Strategy +Select and implement the appropriate versioning mechanism for your API architecture. + +### Step 2: Create Version Infrastructure +Set up routing, middleware, and transformers for multi-version support. + +### Step 3: Implement Compatibility Layer +Build backward compatibility adapters and response transformers. + +### Step 4: Add Deprecation Workflow +Implement deprecation notices, sunset headers, and migration tools. + +### Step 5: Set Up Version Testing +Create comprehensive test suites covering all supported versions. + +## Output Format + +The command generates: +- `api/v1/` - Version 1 implementation +- `api/v2/` - Version 2 implementation +- `middleware/version-router.js` - Version routing logic +- `transformers/` - Version-specific data transformers +- `tests/compatibility/` - Cross-version compatibility tests +- `docs/migration-guide.md` - Version migration documentation + +## Code Examples + +### Example 1: Comprehensive URL Path Versioning System + +```javascript +// middleware/version-router.js +const express = require('express'); +const semver = require('semver'); + +class APIVersionManager { + constructor(options = {}) { + this.versions = new Map(); + this.defaultVersion = options.defaultVersion || 'v1'; + this.deprecationPolicy = options.deprecationPolicy || { + warningPeriod: 90, // days before sunset + sunsetPeriod: 180 // days until removal + }; + this.versionInfo = new Map(); + } + + registerVersion(version, router, metadata = {}) { + this.versions.set(version, router); + this.versionInfo.set(version, { + releaseDate: metadata.releaseDate || new Date(), + deprecatedDate: metadata.deprecatedDate, + sunsetDate: metadata.sunsetDate, + changes: metadata.changes || [], + status: metadata.status || 'active' // active, deprecated, sunset + }); + } + + createVersionMiddleware() { + return (req, res, next) => { + // Extract version from URL path + const pathMatch = req.path.match(/^\/v(\d+(?:\.\d+)?)/); + const version = pathMatch ? `v${pathMatch[1]}` : null; + + // Check Accept header for version preference + const acceptHeader = req.headers.accept || ''; + const headerMatch = acceptHeader.match(/application\/vnd\.api\.v(\d+)/); + const headerVersion = headerMatch ? `v${headerMatch[1]}` : null; + + // Determine final version (path takes precedence) + const requestedVersion = version || headerVersion || this.defaultVersion; + + // Validate version exists + if (!this.versions.has(requestedVersion)) { + return res.status(400).json({ + error: 'Invalid API version', + message: `Version ${requestedVersion} is not supported`, + supportedVersions: Array.from(this.versions.keys()), + latestVersion: this.getLatestVersion() + }); + } + + // Check if version is deprecated or sunset + const versionMeta = this.versionInfo.get(requestedVersion); + + if (versionMeta.status === 'sunset') { + return res.status(410).json({ + error: 'API version sunset', + message: `Version ${requestedVersion} is no longer available`, + sunsetDate: versionMeta.sunsetDate, + alternatives: this.getActiveVersions(), + migrationGuide: `/docs/migration/${requestedVersion}` + }); + } + + // Add version headers + res.set({ + 'API-Version': requestedVersion, + 'X-API-Version': requestedVersion + }); + + // Add deprecation headers if applicable + if (versionMeta.status === 'deprecated') { + const sunsetDate = versionMeta.sunsetDate || this.calculateSunsetDate(versionMeta.deprecatedDate); + + res.set({ + 'Deprecation': 'true', + 'Sunset': sunsetDate.toUTCString(), + 'Link': `; rel="deprecation"`, + 'Warning': `299 - "Version ${requestedVersion} is deprecated and will be removed on ${sunsetDate.toDateString()}"` + }); + + // Add deprecation notice to response + res.on('finish', () => { + console.log(`Deprecated API version ${requestedVersion} called by ${req.ip}`); + }); + } + + // Store version info in request + req.apiVersion = requestedVersion; + req.apiVersionInfo = versionMeta; + + // Route to version-specific handler + const versionRouter = this.versions.get(requestedVersion); + versionRouter(req, res, next); + }; + } + + getLatestVersion() { + const versions = Array.from(this.versions.keys()); + return versions.sort((a, b) => semver.rcompare(a.slice(1), b.slice(1)))[0]; + } + + getActiveVersions() { + return Array.from(this.versionInfo.entries()) + .filter(([_, info]) => info.status === 'active') + .map(([version, _]) => version); + } + + calculateSunsetDate(deprecatedDate) { + const sunset = new Date(deprecatedDate); + sunset.setDate(sunset.getDate() + this.deprecationPolicy.sunsetPeriod); + return sunset; + } + + generateVersionReport() { + const report = { + current: this.getLatestVersion(), + supported: [], + deprecated: [], + sunset: [] + }; + + for (const [version, info] of this.versionInfo) { + const versionData = { + version, + releaseDate: info.releaseDate, + status: info.status + }; + + switch (info.status) { + case 'active': + report.supported.push(versionData); + break; + case 'deprecated': + report.deprecated.push({ + ...versionData, + sunsetDate: info.sunsetDate + }); + break; + case 'sunset': + report.sunset.push({ + ...versionData, + sunsetDate: info.sunsetDate + }); + break; + } + } + + return report; + } +} + +// api/v1/routes.js - Version 1 Implementation +const v1Router = express.Router(); + +v1Router.get('/users', async (req, res) => { + const users = await getUsersV1(); + + // V1 response format + res.json({ + data: users.map(user => ({ + id: user.id, + name: user.name, + email: user.email + // V1 doesn't include profile field + })) + }); +}); + +v1Router.get('/users/:id', async (req, res) => { + const user = await getUserByIdV1(req.params.id); + + res.json({ + data: { + id: user.id, + name: user.name, + email: user.email + } + }); +}); + +// api/v2/routes.js - Version 2 Implementation +const v2Router = express.Router(); + +v2Router.get('/users', async (req, res) => { + const users = await getUsersV2(); + + // V2 response format with additional fields + res.json({ + data: users.map(user => ({ + id: user.id, + displayName: user.name, // Field renamed + email: user.email, + profile: { // New nested object + avatar: user.avatar, + bio: user.bio, + createdAt: user.createdAt + } + })), + meta: { // New metadata section + total: users.length, + version: 'v2' + } + }); +}); + +// transformers/v1-to-v2.js - Backward Compatibility Transformer +class V1ToV2Transformer { + transformUserResponse(v2Response) { + // Transform V2 response to V1 format + if (Array.isArray(v2Response.data)) { + return { + data: v2Response.data.map(user => ({ + id: user.id, + name: user.displayName, // Map back to old field name + email: user.email + // Omit profile field for V1 + })) + }; + } + + return { + data: { + id: v2Response.data.id, + name: v2Response.data.displayName, + email: v2Response.data.email + } + }; + } + + transformUserRequest(v1Request) { + // Transform V1 request to V2 format + return { + ...v1Request, + displayName: v1Request.name, + profile: { + // Set defaults for new required fields + avatar: null, + bio: '', + createdAt: new Date().toISOString() + } + }; + } +} + +// Usage +const versionManager = new APIVersionManager({ + defaultVersion: 'v2', + deprecationPolicy: { + warningPeriod: 90, + sunsetPeriod: 180 + } +}); + +// Register versions +versionManager.registerVersion('v1', v1Router, { + releaseDate: new Date('2023-01-01'), + deprecatedDate: new Date('2024-06-01'), + status: 'deprecated', + changes: ['Initial API release'] +}); + +versionManager.registerVersion('v2', v2Router, { + releaseDate: new Date('2024-01-01'), + status: 'active', + changes: [ + 'Renamed user.name to user.displayName', + 'Added user.profile nested object', + 'Added metadata to list responses' + ] +}); + +// Apply versioning middleware +app.use('/api', versionManager.createVersionMiddleware()); + +// Version discovery endpoint +app.get('/api/versions', (req, res) => { + res.json(versionManager.generateVersionReport()); +}); +``` + +### Example 2: Advanced Content Negotiation Versioning + +```javascript +// middleware/content-negotiation.js +const accepts = require('accepts'); + +class ContentNegotiationVersioning { + constructor() { + this.handlers = new Map(); + this.transformers = new Map(); + } + + register(version, mediaType, handler, transformer = null) { + const key = `${version}:${mediaType}`; + this.handlers.set(key, handler); + + if (transformer) { + this.transformers.set(key, transformer); + } + } + + negotiate() { + return async (req, res, next) => { + const accept = accepts(req); + + // Define supported media types with versions + const supportedTypes = [ + 'application/vnd.api.v3+json', + 'application/vnd.api.v2+json', + 'application/vnd.api.v1+json', + 'application/json' // Default fallback + ]; + + const acceptedType = accept.type(supportedTypes); + + if (!acceptedType) { + return res.status(406).json({ + error: 'Not Acceptable', + message: 'None of the requested media types are supported', + supported: supportedTypes + }); + } + + // Extract version from media type + let version = 'v2'; // Default version + let format = 'json'; + + const versionMatch = acceptedType.match(/v(\d+)/); + if (versionMatch) { + version = `v${versionMatch[1]}`; + } + + const formatMatch = acceptedType.match(/\+(\w+)$/); + if (formatMatch) { + format = formatMatch[1]; + } + + // Set request properties + req.apiVersion = version; + req.responseFormat = format; + + // Override res.json to apply version transformations + const originalJson = res.json.bind(res); + + res.json = function(data) { + // Apply version-specific transformations + const transformerKey = `${version}:${format}`; + const transformer = this.transformers.get(transformerKey); + + if (transformer) { + data = transformer(data, req); + } + + // Set content type header + res.type(acceptedType); + + // Add version headers + res.set({ + 'Content-Type': acceptedType, + 'API-Version': version, + 'Vary': 'Accept' // Important for caching + }); + + return originalJson(data); + }.bind(this); + + next(); + }; + } +} + +// services/version-compatibility.js +class VersionCompatibilityService { + constructor() { + this.breakingChanges = new Map(); + this.migrationStrategies = new Map(); + } + + registerBreakingChange(fromVersion, toVersion, change) { + const key = `${fromVersion}->${toVersion}`; + + if (!this.breakingChanges.has(key)) { + this.breakingChanges.set(key, []); + } + + this.breakingChanges.get(key).push(change); + } + + registerMigrationStrategy(fromVersion, toVersion, strategy) { + const key = `${fromVersion}->${toVersion}`; + this.migrationStrategies.set(key, strategy); + } + + analyzeCompatibility(fromVersion, toVersion, data) { + const key = `${fromVersion}->${toVersion}`; + const changes = this.breakingChanges.get(key) || []; + + const issues = []; + + for (const change of changes) { + if (change.detector(data)) { + issues.push({ + type: change.type, + field: change.field, + description: change.description, + severity: change.severity, + migration: change.migration + }); + } + } + + return { + compatible: issues.length === 0, + issues, + canAutoMigrate: issues.every(i => i.migration !== null) + }; + } + + migrate(fromVersion, toVersion, data) { + const key = `${fromVersion}->${toVersion}`; + const strategy = this.migrationStrategies.get(key); + + if (!strategy) { + throw new Error(`No migration strategy from ${fromVersion} to ${toVersion}`); + } + + return strategy(data); + } +} + +// Example breaking changes registration +const compatibilityService = new VersionCompatibilityService(); + +compatibilityService.registerBreakingChange('v1', 'v2', { + type: 'field_renamed', + field: 'name', + description: 'Field "name" renamed to "displayName"', + severity: 'major', + detector: (data) => data.hasOwnProperty('name'), + migration: (data) => { + data.displayName = data.name; + delete data.name; + return data; + } +}); + +compatibilityService.registerBreakingChange('v1', 'v2', { + type: 'field_added_required', + field: 'profile', + description: 'Required field "profile" added', + severity: 'major', + detector: (data) => !data.hasOwnProperty('profile'), + migration: (data) => { + data.profile = { + avatar: null, + bio: '', + createdAt: new Date().toISOString() + }; + return data; + } +}); + +// Migration strategy for v1 to v2 +compatibilityService.registerMigrationStrategy('v1', 'v2', (data) => { + // Full migration logic + const migrated = { ...data }; + + // Rename fields + if (migrated.name) { + migrated.displayName = migrated.name; + delete migrated.name; + } + + // Add new required fields + if (!migrated.profile) { + migrated.profile = { + avatar: null, + bio: '', + createdAt: new Date().toISOString() + }; + } + + // Transform nested structures + if (migrated.addresses && Array.isArray(migrated.addresses)) { + migrated.locations = migrated.addresses.map(addr => ({ + type: addr.type || 'home', + address: addr, + isPrimary: addr.primary || false + })); + delete migrated.addresses; + } + + return migrated; +}); +``` + +### Example 3: Automated Version Testing and Documentation + +```javascript +// tests/version-compatibility.test.js +const request = require('supertest'); +const app = require('../app'); + +class VersionCompatibilityTester { + constructor(app) { + this.app = app; + this.versions = ['v1', 'v2', 'v3']; + this.endpoints = []; + this.results = []; + } + + addEndpoint(method, path, testCases) { + this.endpoints.push({ method, path, testCases }); + } + + async runCompatibilityTests() { + console.log('Running API version compatibility tests...\n'); + + for (const endpoint of this.endpoints) { + for (const version of this.versions) { + for (const testCase of endpoint.testCases) { + const result = await this.testEndpoint( + version, + endpoint.method, + endpoint.path, + testCase + ); + + this.results.push(result); + + // Log result + const status = result.passed ? '✓' : '✗'; + console.log( + `${status} ${version} ${endpoint.method} ${endpoint.path} - ${testCase.name}` + ); + } + } + } + + return this.generateReport(); + } + + async testEndpoint(version, method, path, testCase) { + const url = `/api/${version}${path}`; + + try { + const response = await request(this.app) + [method.toLowerCase()](url) + .send(testCase.payload || {}) + .set('Accept', `application/vnd.api.${version}+json`) + .expect(testCase.expectedStatus || 200); + + // Validate response structure + const validation = this.validateResponse( + version, + response.body, + testCase.expectedSchema + ); + + return { + version, + endpoint: `${method} ${path}`, + testCase: testCase.name, + passed: validation.valid, + errors: validation.errors, + response: response.body + }; + } catch (error) { + return { + version, + endpoint: `${method} ${path}`, + testCase: testCase.name, + passed: false, + errors: [error.message], + response: null + }; + } + } + + validateResponse(version, response, expectedSchema) { + // Version-specific validation logic + const errors = []; + + // Check required fields + for (const field of expectedSchema.required || []) { + if (!response.hasOwnProperty(field)) { + errors.push(`Missing required field: ${field}`); + } + } + + // Check field types + for (const [field, type] of Object.entries(expectedSchema.properties || {})) { + if (response[field] !== undefined && typeof response[field] !== type) { + errors.push(`Invalid type for ${field}: expected ${type}`); + } + } + + return { + valid: errors.length === 0, + errors + }; + } + + generateReport() { + const report = { + timestamp: new Date().toISOString(), + summary: { + total: this.results.length, + passed: this.results.filter(r => r.passed).length, + failed: this.results.filter(r => !r.passed).length + }, + versionMatrix: this.generateVersionMatrix(), + failures: this.results.filter(r => !r.passed), + recommendations: this.generateRecommendations() + }; + + // Save report + require('fs').writeFileSync( + 'version-compatibility-report.json', + JSON.stringify(report, null, 2) + ); + + return report; + } + + generateVersionMatrix() { + const matrix = {}; + + for (const version of this.versions) { + matrix[version] = { + endpoints: {}, + compatibility: 0 + }; + + for (const endpoint of this.endpoints) { + const key = `${endpoint.method} ${endpoint.path}`; + const results = this.results.filter( + r => r.version === version && r.endpoint === key + ); + + matrix[version].endpoints[key] = { + total: results.length, + passed: results.filter(r => r.passed).length + }; + } + + // Calculate compatibility percentage + const versionResults = this.results.filter(r => r.version === version); + matrix[version].compatibility = ( + (versionResults.filter(r => r.passed).length / versionResults.length) * 100 + ).toFixed(2); + } + + return matrix; + } + + generateRecommendations() { + const recommendations = []; + + // Check for consistent failures across versions + const failurePatterns = {}; + + for (const failure of this.results.filter(r => !r.passed)) { + const key = failure.endpoint; + + if (!failurePatterns[key]) { + failurePatterns[key] = new Set(); + } + + failurePatterns[key].add(failure.version); + } + + for (const [endpoint, versions] of Object.entries(failurePatterns)) { + if (versions.size > 1) { + recommendations.push({ + type: 'cross_version_failure', + endpoint, + affectedVersions: Array.from(versions), + recommendation: 'Review endpoint implementation for version-agnostic issues' + }); + } + } + + return recommendations; + } +} + +// Usage +const tester = new VersionCompatibilityTester(app); + +// Add test cases +tester.addEndpoint('GET', '/users', [ + { + name: 'List users', + expectedStatus: 200, + expectedSchema: { + required: ['data'], + properties: { + data: 'object' + } + } + } +]); + +tester.addEndpoint('POST', '/users', [ + { + name: 'Create user with v1 format', + payload: { + name: 'John Doe', + email: 'john@example.com' + }, + expectedStatus: 201 + }, + { + name: 'Create user with v2 format', + payload: { + displayName: 'John Doe', + email: 'john@example.com', + profile: { + bio: 'Developer' + } + }, + expectedStatus: 201 + } +]); + +// Run tests +tester.runCompatibilityTests() + .then(report => { + console.log('\nCompatibility Report Generated'); + console.log(`Total Tests: ${report.summary.total}`); + console.log(`Passed: ${report.summary.passed}`); + console.log(`Failed: ${report.summary.failed}`); + }); +``` + +## Error Handling + +| Error | Cause | Solution | +|-------|-------|----------| +| "Invalid API version" | Unsupported version requested | Return list of supported versions | +| "Version sunset" | Version no longer available | Provide migration guide and alternatives | +| "Incompatible request" | Breaking changes detected | Apply automatic migration if possible | +| "Deprecation warning ignored" | Client using deprecated version | Send stronger warnings, contact client | +| "Version routing conflict" | Overlapping route definitions | Review route precedence rules | + +## Configuration Options + +**Versioning Strategies** +- `url-path`: Version in URL path (/v1/) +- `header`: Version in Accept header +- `query`: Version in query parameter +- `subdomain`: Version in subdomain (v1.api.example.com) + +**Deprecation Policies** +- `aggressive`: 3-month deprecation cycle +- `standard`: 6-month deprecation cycle +- `conservative`: 12-month deprecation cycle +- `enterprise`: Custom per-client agreements + +## Best Practices + +DO: +- Support at least 2 major versions simultaneously +- Provide clear deprecation timelines +- Version your database schemas +- Maintain comprehensive migration documentation +- Use semantic versioning +- Monitor version usage analytics + +DON'T: +- Remove versions without notice +- Make breaking changes in minor versions +- Ignore backward compatibility +- Version too granularly +- Mix versioning strategies + +## Performance Considerations + +- Cache responses per version +- Lazy-load version-specific code +- Use CDN with version-aware caching +- Monitor performance per version +- Optimize hot migration paths + +## Monitoring and Analytics + +```javascript +// Track version usage +const versionMetrics = { + requests: new Map(), + deprecated: new Map(), + errors: new Map() +}; + +app.use((req, res, next) => { + const version = req.apiVersion || 'unknown'; + versionMetrics.requests.set( + version, + (versionMetrics.requests.get(version) || 0) + 1 + ); + next(); +}); +``` + +## Related Commands + +- `/api-documentation-generator` - Generate version-specific docs +- `/api-sdk-generator` - Create versioned SDKs +- `/api-testing-framework` - Test version compatibility +- `/api-migration-tool` - Automate version migrations + +## Version History + +- v1.0.0 (2024-10): Initial implementation with URL path versioning +- Planned v1.1.0: Add GraphQL schema versioning support \ No newline at end of file diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..bee1016 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,101 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:jeremylongshore/claude-code-plugins-plus:plugins/api-development/api-versioning-manager", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "7952beaf67cf8ccc31956dad68a31d0f540c6531", + "treeHash": "934f4081edd46f10b13869423c687bf9720be3d71aa30ba9e7052821ad36e8cd", + "generatedAt": "2025-11-28T10:18:09.495675Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "api-versioning-manager", + "description": "Manage API versions with migration strategies and backward compatibility", + "version": "1.0.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "622940b006d88239796386f89c3cecc40452110b7dfe5fd1e47f64d7d9a0ccdf" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "47453bc5b5bc4c6afcb2c9b2f2466fb46037c61553d6688a4507234557479883" + }, + { + "path": "commands/manage-api-versions.md", + "sha256": "e785cd0af3c24250522c92dd2f3d3194235d4743084543c8722b0d0641575b50" + }, + { + "path": "skills/skill-adapter/references/examples.md", + "sha256": "922bbc3c4ebf38b76f515b5c1998ebde6bf902233e00e2c5a0e9176f975a7572" + }, + { + "path": "skills/skill-adapter/references/best-practices.md", + "sha256": "c8f32b3566252f50daacd346d7045a1060c718ef5cfb07c55a0f2dec5f1fb39e" + }, + { + "path": "skills/skill-adapter/references/README.md", + "sha256": "0a6a63a31bfb06b15b46abc677ca34df8127203656d28400570aad3879177885" + }, + { + "path": "skills/skill-adapter/scripts/helper-template.sh", + "sha256": "0881d5660a8a7045550d09ae0acc15642c24b70de6f08808120f47f86ccdf077" + }, + { + "path": "skills/skill-adapter/scripts/validation.sh", + "sha256": "92551a29a7f512d2036e4f1fb46c2a3dc6bff0f7dde4a9f699533e446db48502" + }, + { + "path": "skills/skill-adapter/scripts/README.md", + "sha256": "b9aa7f31c592dc377694188ef22d84da54a5b507b25010798d1b019145b60a4e" + }, + { + "path": "skills/skill-adapter/assets/compatibility_test_suite.json", + "sha256": "abee1177037fdb883d5c2a967134d73447c33bb413be4d6a8d0cd2da80dce96a" + }, + { + "path": "skills/skill-adapter/assets/migration_guide_template.md", + "sha256": "4577ba6eac2409ad93762c8e228363a88d13cd2adb2f8543a0a87e79ddb3aed3" + }, + { + "path": "skills/skill-adapter/assets/test-data.json", + "sha256": "ac17dca3d6e253a5f39f2a2f1b388e5146043756b05d9ce7ac53a0042eee139d" + }, + { + "path": "skills/skill-adapter/assets/README.md", + "sha256": "11a80caf18e60aaa0b6c19556fa79c923e1a455beaaf243d20c38c725e177eab" + }, + { + "path": "skills/skill-adapter/assets/api_version_template.json", + "sha256": "060ab71061443f0253be1e964654eb3b20c4b854c36918495fd86ad4b0b414f0" + }, + { + "path": "skills/skill-adapter/assets/deprecation_notice_template.md", + "sha256": "3b3c20287e437660e8f58e1fcf6b328927663196d578d2d36aa3319b2a8cac96" + }, + { + "path": "skills/skill-adapter/assets/skill-schema.json", + "sha256": "f5639ba823a24c9ac4fb21444c0717b7aefde1a4993682897f5bf544f863c2cd" + }, + { + "path": "skills/skill-adapter/assets/config-template.json", + "sha256": "0c2ba33d2d3c5ccb266c0848fc43caa68a2aa6a80ff315d4b378352711f83e1c" + } + ], + "dirSha256": "934f4081edd46f10b13869423c687bf9720be3d71aa30ba9e7052821ad36e8cd" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/skill-adapter/assets/README.md b/skills/skill-adapter/assets/README.md new file mode 100644 index 0000000..26f8004 --- /dev/null +++ b/skills/skill-adapter/assets/README.md @@ -0,0 +1,8 @@ +# Assets + +Bundled resources for api-versioning-manager skill + +- [ ] api_version_template.json: Template for API version configuration files. +- [ ] deprecation_notice_template.md: Template for deprecation notices. +- [ ] compatibility_test_suite.json: Example compatibility test suite. +- [ ] migration_guide_template.md: Template for migration guides. diff --git a/skills/skill-adapter/assets/api_version_template.json b/skills/skill-adapter/assets/api_version_template.json new file mode 100644 index 0000000..a07e3a9 --- /dev/null +++ b/skills/skill-adapter/assets/api_version_template.json @@ -0,0 +1,106 @@ +{ + "_comment": "API Version Configuration Template", + "apiName": "MyAwesomeAPI", + "versions": [ + { + "version": "v1", + "_comment": "Initial version of the API", + "status": "active", + "releaseDate": "2023-01-15", + "deprecationDate": null, + "sunsetDate": null, + "migrationGuide": null, + "backwardCompatible": true, + "endpoints": { + "/users": { + "method": "GET", + "description": "Retrieve all users", + "fields": ["id", "name", "email"] + }, + "/users/{id}": { + "method": "GET", + "description": "Retrieve a specific user", + "fields": ["id", "name", "email"] + } + } + }, + { + "version": "v2", + "_comment": "Second version of the API with enhanced features", + "status": "active", + "releaseDate": "2023-07-20", + "deprecationDate": "2024-01-15", + "sunsetDate": "2024-07-20", + "migrationGuide": "https://example.com/migration-v1-to-v2", + "backwardCompatible": false, + "endpoints": { + "/users": { + "method": "GET", + "description": "Retrieve all users with pagination and filtering", + "fields": ["id", "name", "email", "createdAt", "updatedAt"], + "parameters": ["page", "limit", "filter"] + }, + "/users/{id}": { + "method": "GET", + "description": "Retrieve a specific user with extended profile information", + "fields": ["id", "name", "email", "createdAt", "updatedAt", "profile"] + }, + "/users/{id}/orders": { + "method": "GET", + "description": "Retrieve orders for a specific user", + "fields": ["orderId", "orderDate", "total"] + } + } + }, + { + "version": "v3", + "_comment": "Third version of the API - current version", + "status": "active", + "releaseDate": "2024-02-01", + "deprecationDate": null, + "sunsetDate": null, + "migrationGuide": null, + "backwardCompatible": true, + "endpoints": { + "/users": { + "method": "GET", + "description": "Retrieve all users with improved pagination and filtering", + "fields": ["id", "name", "email", "createdAt", "updatedAt"], + "parameters": ["page", "limit", "filter", "sort"] + }, + "/users/{id}": { + "method": "GET", + "description": "Retrieve a specific user with extended profile information and address", + "fields": ["id", "name", "email", "createdAt", "updatedAt", "profile", "address"] + }, + "/users/{id}/orders": { + "method": "GET", + "description": "Retrieve orders for a specific user with detailed order information", + "fields": ["orderId", "orderDate", "total", "items"] + } + } + }, + { + "version": "v0", + "_comment": "Deprecated version of the API", + "status": "deprecated", + "releaseDate": "2022-01-01", + "deprecationDate": "2023-01-01", + "sunsetDate": "2023-07-01", + "migrationGuide": "https://example.com/migration-v0-to-v1", + "backwardCompatible": false, + "endpoints": { + "/users": { + "method": "GET", + "description": "Retrieve all users (DEPRECATED)", + "fields": ["id", "name"] + }, + "/users/{id}": { + "method": "GET", + "description": "Retrieve a specific user (DEPRECATED)", + "fields": ["id", "name"] + } + } + } + ] +} \ No newline at end of file diff --git a/skills/skill-adapter/assets/compatibility_test_suite.json b/skills/skill-adapter/assets/compatibility_test_suite.json new file mode 100644 index 0000000..9b10011 --- /dev/null +++ b/skills/skill-adapter/assets/compatibility_test_suite.json @@ -0,0 +1,110 @@ +{ + "_comment": "Compatibility Test Suite for API Versioning Manager", + "api_name": "User Management API", + "tests": [ + { + "_comment": "Test case for retrieving user details in version 1", + "test_name": "Get User Details v1", + "api_version": "1", + "endpoint": "/users/123", + "method": "GET", + "request_headers": { + "Accept": "application/json" + }, + "expected_status_code": 200, + "expected_response_body": { + "id": 123, + "name": "John Doe", + "email": "john.doe@example.com" + }, + "backward_compatible_versions": [] + }, + { + "_comment": "Test case for retrieving user details in version 2", + "test_name": "Get User Details v2", + "api_version": "2", + "endpoint": "/v2/users/123", + "method": "GET", + "request_headers": { + "Accept": "application/json" + }, + "expected_status_code": 200, + "expected_response_body": { + "user_id": 123, + "full_name": "John Doe", + "contact_email": "john.doe@example.com", + "profile_details": { + "created_at": "2023-10-26T10:00:00Z" + } + }, + "backward_compatible_versions": ["1"] + }, + { + "_comment": "Test case for creating a user in version 1", + "test_name": "Create User v1", + "api_version": "1", + "endpoint": "/users", + "method": "POST", + "request_headers": { + "Content-Type": "application/json" + }, + "request_body": { + "name": "Jane Smith", + "email": "jane.smith@example.com" + }, + "expected_status_code": 201, + "expected_response_body": { + "id": 456, + "name": "Jane Smith", + "email": "jane.smith@example.com" + }, + "backward_compatible_versions": [] + }, + { + "_comment": "Test case for creating a user in version 2", + "test_name": "Create User v2", + "api_version": "2", + "endpoint": "/v2/users", + "method": "POST", + "request_headers": { + "Content-Type": "application/json" + }, + "request_body": { + "full_name": "Jane Smith", + "contact_email": "jane.smith@example.com" + }, + "expected_status_code": 201, + "expected_response_body": { + "user_id": 456, + "full_name": "Jane Smith", + "contact_email": "jane.smith@example.com" + }, + "backward_compatible_versions": ["1"] + }, + { + "_comment": "Test case for deleting a user in version 1 (deprecated)", + "test_name": "Delete User v1 (Deprecated)", + "api_version": "1", + "endpoint": "/users/123", + "method": "DELETE", + "request_headers": {}, + "expected_status_code": 410, + "expected_response_body": { + "error": "This endpoint is deprecated. Please use /v2/users/123/deactivate." + }, + "backward_compatible_versions": [], + "deprecation_message": "This endpoint is deprecated. Please use /v2/users/123/deactivate." + }, + { + "_comment": "Test case for deactivating a user in version 2", + "test_name": "Deactivate User v2", + "api_version": "2", + "endpoint": "/v2/users/123/deactivate", + "method": "POST", + "request_headers": {}, + "expected_status_code": 204, + "expected_response_body": null, + "backward_compatible_versions": [] + } + ] +} \ No newline at end of file diff --git a/skills/skill-adapter/assets/config-template.json b/skills/skill-adapter/assets/config-template.json new file mode 100644 index 0000000..16f1712 --- /dev/null +++ b/skills/skill-adapter/assets/config-template.json @@ -0,0 +1,32 @@ +{ + "skill": { + "name": "skill-name", + "version": "1.0.0", + "enabled": true, + "settings": { + "verbose": false, + "autoActivate": true, + "toolRestrictions": true + } + }, + "triggers": { + "keywords": [ + "example-trigger-1", + "example-trigger-2" + ], + "patterns": [] + }, + "tools": { + "allowed": [ + "Read", + "Grep", + "Bash" + ], + "restricted": [] + }, + "metadata": { + "author": "Plugin Author", + "category": "general", + "tags": [] + } +} diff --git a/skills/skill-adapter/assets/deprecation_notice_template.md b/skills/skill-adapter/assets/deprecation_notice_template.md new file mode 100644 index 0000000..1428dac --- /dev/null +++ b/skills/skill-adapter/assets/deprecation_notice_template.md @@ -0,0 +1,105 @@ +# Deprecation Notice Template + +This template provides a structure for creating clear and informative deprecation notices for your API endpoints. Use this template to communicate upcoming changes to your users and guide them through the migration process. + +## 1. Endpoint Identification + +Clearly identify the API endpoint being deprecated. Provide the full URL, the HTTP method, and a brief description. + +**Example:** + +* **Endpoint:** `GET /users/{user_id}` +* **Description:** Retrieves user information by ID. + +## 2. Deprecation Date + +Specify the exact date when the endpoint will be officially deprecated. This date should be clearly visible and easily understandable. + +**Example:** + +* **Deprecation Date:** 2024-12-31 + +## 3. Sunset Date (Removal Date) + +State the date when the deprecated endpoint will be completely removed and no longer functional. This is crucial for users to plan their migration. + +**Example:** + +* **Sunset Date:** 2025-06-30 + +## 4. Reason for Deprecation + +Explain the reason behind the deprecation. Be transparent and provide context. This helps users understand the need for the change. + +**Examples:** + +* "This endpoint is being deprecated in favor of the new `GET /v2/users/{user_id}` endpoint, which offers improved performance and security." +* "This endpoint relies on outdated technology and is being replaced with a more modern and scalable solution." +* "This endpoint is being deprecated due to low usage and maintenance costs." + +## 5. Recommended Alternative + +Provide a clear and specific alternative to the deprecated endpoint. Include the full URL, HTTP method, and a description of its functionality. + +**Example:** + +* **Alternative Endpoint:** `GET /v2/users/{user_id}` +* **Description:** Retrieves user information by ID using a more efficient data structure. + +## 6. Migration Guide + +Provide detailed instructions on how to migrate from the deprecated endpoint to the recommended alternative. This should include code examples, data mapping information, and any other relevant details. + +**Example:** + +To migrate to the new endpoint, please follow these steps: + +1. Replace all instances of `GET /users/{user_id}` with `GET /v2/users/{user_id}`. +2. The response format for the new endpoint is slightly different. The `name` field has been split into `firstName` and `lastName` fields. Update your code accordingly. + * **Old:** `{"id": 123, "name": "John Doe"}` + * **New:** `{"id": 123, "firstName": "John", "lastName": "Doe"}` +3. Ensure you are handling any potential errors returned by the new endpoint. + +## 7. Impact of Deprecation + +Explain the potential impact of the deprecation on users who continue to use the deprecated endpoint after the deprecation date. + +**Examples:** + +* "After the deprecation date, this endpoint will continue to function but will no longer receive updates or bug fixes." +* "After the sunset date, this endpoint will return a `410 Gone` error." + +## 8. Support and Contact Information + +Provide contact information for users who have questions or need assistance with the migration process. + +**Example:** + +If you have any questions or require assistance with the migration, please contact our support team at [support@example.com](mailto:support@example.com) or visit our documentation at [https://example.com/docs/api-migration](https://example.com/docs/api-migration). + +## 9. Versioning Information (Optional) + +If your API uses versioning, include information about the API version being deprecated. + +**Example:** + +* **Affected API Version(s):** v1 + +## Example Complete Notice + +--- + +**Endpoint:** `POST /orders` +**Description:** Creates a new order. +**Deprecation Date:** 2024-11-15 +**Sunset Date:** 2025-05-15 +**Reason for Deprecation:** This endpoint is being deprecated due to security vulnerabilities. +**Recommended Alternative:** `POST /v2/orders` +**Description:** Creates a new order using a more secure authentication method. +**Migration Guide:** Please update your code to use the `POST /v2/orders` endpoint. The request body format is the same. You will need to update your authentication headers to use the new API key provided in your account settings. +**Impact of Deprecation:** After 2025-05-15, `POST /orders` will return a `403 Forbidden` error. +**Support and Contact Information:** Contact support@example.com for assistance. + +--- + +**Remember to replace the placeholder information with your specific details.** \ No newline at end of file diff --git a/skills/skill-adapter/assets/migration_guide_template.md b/skills/skill-adapter/assets/migration_guide_template.md new file mode 100644 index 0000000..0879286 --- /dev/null +++ b/skills/skill-adapter/assets/migration_guide_template.md @@ -0,0 +1,122 @@ +# API Migration Guide: [API Name] - Version [Old Version] to Version [New Version] + +This document outlines the necessary steps to migrate your application from version [Old Version] to version [New Version] of the [API Name] API. Carefully review these instructions to ensure a smooth and successful transition. + +## Introduction + +This migration guide provides a detailed overview of the changes introduced in version [New Version] of the [API Name] API and offers step-by-step instructions on how to adapt your application accordingly. We strive to minimize disruption during the upgrade process while introducing new features and improvements. + +**Key Changes in Version [New Version]:** + +* [Briefly describe key change 1, e.g., New authentication method using OAuth 2.0] +* [Briefly describe key change 2, e.g., Updated response format for the `/users` endpoint] +* [Briefly describe key change 3, e.g., Removal of the `/legacy-endpoint` endpoint] + +**Impact:** + +[Summarize the overall impact of the changes on existing applications. Will it require significant code changes? Is it mostly additive?] + +## Deprecation Notices + +The following features or endpoints have been deprecated in version [New Version]: + +* **Endpoint:** `/legacy-endpoint` - Use `/new-endpoint` instead. (See "Migration Steps" below) +* **Parameter:** `old_parameter` in `/resource` - Use `new_parameter` instead. This parameter will be removed in version [Future Version]. + +We strongly recommend migrating away from these deprecated features as soon as possible to avoid future compatibility issues. + +## Migration Steps + +This section provides detailed instructions on migrating your application to the new version. Follow these steps in order to ensure a successful upgrade. + +**1. Update API Client:** + +* If you're using a specific API client library, update it to the latest version compatible with version [New Version]. Refer to the client library's documentation for specific upgrade instructions. + +**2. Authentication Changes (if applicable):** + +* **Old Method:** [Describe the old authentication method, e.g., API keys] +* **New Method:** [Describe the new authentication method, e.g., OAuth 2.0] +* **Action Required:** [Explain how to implement the new authentication method. Include example code snippets if possible. For example: + ``` + // Old: Using API Key + const apiKey = "[YOUR_API_KEY]"; + const response = await fetch("/api/users", { + headers: { "X-API-Key": apiKey } + }); + + // New: Using OAuth 2.0 Token + const accessToken = await getAccessToken(); // Function to obtain access token + const response = await fetch("/api/users", { + headers: { "Authorization": `Bearer ${accessToken}` } + }); + ``` + ] + +**3. Endpoint Changes:** + +* **`/legacy-endpoint` to `/new-endpoint`:** + * **Old Endpoint:** `/legacy-endpoint` + * **New Endpoint:** `/new-endpoint` + * **Reason for Change:** [Explain why the endpoint was changed, e.g., Improved performance, better data model] + * **Action Required:** Update all calls to `/legacy-endpoint` to use `/new-endpoint`. Note that the response format may have changed. See the "Response Format Changes" section below. + +**4. Request Parameter Changes:** + +* **`old_parameter` to `new_parameter` in `/resource`:** + * **Old Parameter:** `old_parameter` (Description: [Brief description of the old parameter]) + * **New Parameter:** `new_parameter` (Description: [Brief description of the new parameter]) + * **Action Required:** Replace all instances of `old_parameter` with `new_parameter`. Ensure the data type is compatible. [Explain any data type conversions needed.] + +**5. Response Format Changes:** + +* **`/users` Endpoint:** + * **Old Response Format:** + ```json + { + "user_id": "123", + "user_name": "John Doe" + } + ``` + * **New Response Format:** + ```json + { + "id": "123", + "name": "John Doe", + "email": "john.doe@example.com" + } + ``` + * **Action Required:** Update your application to handle the new response format. Specifically, replace references to `user_id` with `id` and `user_name` with `name`. Also, consider utilizing the new `email` field. + +**6. Error Handling:** + +* The error codes and messages may have changed in version [New Version]. Consult the API documentation for a complete list of error codes and their meanings. [Provide examples of common error code changes]. + +**7. Testing:** + +* Thoroughly test your application after migrating to version [New Version] to ensure that all functionality is working as expected. Pay particular attention to the areas affected by the changes outlined in this guide. Consider using automated testing tools to verify the compatibility of your application with the new API version. + +## Backward Compatibility + +While we strive to maintain backward compatibility whenever possible, some changes were necessary in version [New Version]. The following aspects are **not** backward compatible: + +* [List specific non-backward-compatible aspects, e.g., Authentication method] +* [List specific non-backward-compatible aspects, e.g., The `/legacy-endpoint` endpoint has been completely removed] + +## Support and Resources + +If you encounter any issues during the migration process, please consult the following resources: + +* **API Documentation:** [Link to API documentation] +* **Support Forum:** [Link to support forum] +* **Contact Us:** [Email address or contact form link] + +We are committed to providing you with the support you need to successfully migrate to version [New Version] of the [API Name] API. + +## Versioning Policy + +[Describe the API versioning policy - how long are old versions supported? How are deprecation notices handled? What is the upgrade schedule? Example: We support the current version and the previous two major versions. Deprecated features are announced at least 6 months prior to removal.] + +## Conclusion + +Migrating to version [New Version] of the [API Name] API will enable you to take advantage of the latest features and improvements. By following the steps outlined in this guide, you can ensure a smooth and successful transition. Thank you for using our API! \ No newline at end of file diff --git a/skills/skill-adapter/assets/skill-schema.json b/skills/skill-adapter/assets/skill-schema.json new file mode 100644 index 0000000..8dc154c --- /dev/null +++ b/skills/skill-adapter/assets/skill-schema.json @@ -0,0 +1,28 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Claude Skill Configuration", + "type": "object", + "required": ["name", "description"], + "properties": { + "name": { + "type": "string", + "pattern": "^[a-z0-9-]+$", + "maxLength": 64, + "description": "Skill identifier (lowercase, hyphens only)" + }, + "description": { + "type": "string", + "maxLength": 1024, + "description": "What the skill does and when to use it" + }, + "allowed-tools": { + "type": "string", + "description": "Comma-separated list of allowed tools" + }, + "version": { + "type": "string", + "pattern": "^\\d+\\.\\d+\\.\\d+$", + "description": "Semantic version (x.y.z)" + } + } +} diff --git a/skills/skill-adapter/assets/test-data.json b/skills/skill-adapter/assets/test-data.json new file mode 100644 index 0000000..f0cd871 --- /dev/null +++ b/skills/skill-adapter/assets/test-data.json @@ -0,0 +1,27 @@ +{ + "testCases": [ + { + "name": "Basic activation test", + "input": "trigger phrase example", + "expected": { + "activated": true, + "toolsUsed": ["Read", "Grep"], + "success": true + } + }, + { + "name": "Complex workflow test", + "input": "multi-step trigger example", + "expected": { + "activated": true, + "steps": 3, + "toolsUsed": ["Read", "Write", "Bash"], + "success": true + } + } + ], + "fixtures": { + "sampleInput": "example data", + "expectedOutput": "processed result" + } +} diff --git a/skills/skill-adapter/references/README.md b/skills/skill-adapter/references/README.md new file mode 100644 index 0000000..d539a18 --- /dev/null +++ b/skills/skill-adapter/references/README.md @@ -0,0 +1,8 @@ +# References + +Bundled resources for api-versioning-manager skill + +- [ ] api_versioning_strategies.md: Detailed explanation of different API versioning strategies (e.g., URI versioning, header versioning). +- [ ] deprecation_best_practices.md: Best practices for managing API deprecation, including communication strategies. +- [ ] backward_compatibility_guidelines.md: Guidelines for ensuring backward compatibility in API changes. +- [ ] semantic_versioning_spec.md: A copy of the semantic versioning specification for reference. diff --git a/skills/skill-adapter/references/best-practices.md b/skills/skill-adapter/references/best-practices.md new file mode 100644 index 0000000..3505048 --- /dev/null +++ b/skills/skill-adapter/references/best-practices.md @@ -0,0 +1,69 @@ +# Skill Best Practices + +Guidelines for optimal skill usage and development. + +## For Users + +### Activation Best Practices + +1. **Use Clear Trigger Phrases** + - Match phrases from skill description + - Be specific about intent + - Provide necessary context + +2. **Provide Sufficient Context** + - Include relevant file paths + - Specify scope of analysis + - Mention any constraints + +3. **Understand Tool Permissions** + - Check allowed-tools in frontmatter + - Know what the skill can/cannot do + - Request appropriate actions + +### Workflow Optimization + +- Start with simple requests +- Build up to complex workflows +- Verify each step before proceeding +- Use skill consistently for related tasks + +## For Developers + +### Skill Development Guidelines + +1. **Clear Descriptions** + - Include explicit trigger phrases + - Document all capabilities + - Specify limitations + +2. **Proper Tool Permissions** + - Use minimal necessary tools + - Document security implications + - Test with restricted tools + +3. **Comprehensive Documentation** + - Provide usage examples + - Document common pitfalls + - Include troubleshooting guide + +### Maintenance + +- Keep version updated +- Test after tool updates +- Monitor user feedback +- Iterate on descriptions + +## Performance Tips + +- Scope skills to specific domains +- Avoid overlapping trigger phrases +- Keep descriptions under 1024 chars +- Test activation reliability + +## Security Considerations + +- Never include secrets in skill files +- Validate all inputs +- Use read-only tools when possible +- Document security requirements diff --git a/skills/skill-adapter/references/examples.md b/skills/skill-adapter/references/examples.md new file mode 100644 index 0000000..b1d8bd2 --- /dev/null +++ b/skills/skill-adapter/references/examples.md @@ -0,0 +1,70 @@ +# Skill Usage Examples + +This document provides practical examples of how to use this skill effectively. + +## Basic Usage + +### Example 1: Simple Activation + +**User Request:** +``` +[Describe trigger phrase here] +``` + +**Skill Response:** +1. Analyzes the request +2. Performs the required action +3. Returns results + +### Example 2: Complex Workflow + +**User Request:** +``` +[Describe complex scenario] +``` + +**Workflow:** +1. Step 1: Initial analysis +2. Step 2: Data processing +3. Step 3: Result generation +4. Step 4: Validation + +## Advanced Patterns + +### Pattern 1: Chaining Operations + +Combine this skill with other tools: +``` +Step 1: Use this skill for [purpose] +Step 2: Chain with [other tool] +Step 3: Finalize with [action] +``` + +### Pattern 2: Error Handling + +If issues occur: +- Check trigger phrase matches +- Verify context is available +- Review allowed-tools permissions + +## Tips & Best Practices + +- ✅ Be specific with trigger phrases +- ✅ Provide necessary context +- ✅ Check tool permissions match needs +- ❌ Avoid vague requests +- ❌ Don't mix unrelated tasks + +## Common Issues + +**Issue:** Skill doesn't activate +**Solution:** Use exact trigger phrases from description + +**Issue:** Unexpected results +**Solution:** Check input format and context + +## See Also + +- Main SKILL.md for full documentation +- scripts/ for automation helpers +- assets/ for configuration examples diff --git a/skills/skill-adapter/scripts/README.md b/skills/skill-adapter/scripts/README.md new file mode 100644 index 0000000..a545a43 --- /dev/null +++ b/skills/skill-adapter/scripts/README.md @@ -0,0 +1,8 @@ +# Scripts + +Bundled resources for api-versioning-manager skill + +- [ ] api_version_bump.py: Automates the process of incrementing API versions in configuration files. +- [ ] deprecation_notice_generator.py: Generates deprecation notices in various formats (e.g., Markdown, JSON). +- [ ] compatibility_test_runner.sh: Executes compatibility tests against different API versions. +- [ ] migration_guide_generator.py: Generates migration guides from one API version to another. diff --git a/skills/skill-adapter/scripts/helper-template.sh b/skills/skill-adapter/scripts/helper-template.sh new file mode 100755 index 0000000..c4aae90 --- /dev/null +++ b/skills/skill-adapter/scripts/helper-template.sh @@ -0,0 +1,42 @@ +#!/bin/bash +# Helper script template for skill automation +# Customize this for your skill's specific needs + +set -e + +function show_usage() { + echo "Usage: $0 [options]" + echo "" + echo "Options:" + echo " -h, --help Show this help message" + echo " -v, --verbose Enable verbose output" + echo "" +} + +# Parse arguments +VERBOSE=false + +while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + show_usage + exit 0 + ;; + -v|--verbose) + VERBOSE=true + shift + ;; + *) + echo "Unknown option: $1" + show_usage + exit 1 + ;; + esac +done + +# Your skill logic here +if [ "$VERBOSE" = true ]; then + echo "Running skill automation..." +fi + +echo "✅ Complete" diff --git a/skills/skill-adapter/scripts/validation.sh b/skills/skill-adapter/scripts/validation.sh new file mode 100755 index 0000000..590af58 --- /dev/null +++ b/skills/skill-adapter/scripts/validation.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Skill validation helper +# Validates skill activation and functionality + +set -e + +echo "🔍 Validating skill..." + +# Check if SKILL.md exists +if [ ! -f "../SKILL.md" ]; then + echo "❌ Error: SKILL.md not found" + exit 1 +fi + +# Validate frontmatter +if ! grep -q "^---$" "../SKILL.md"; then + echo "❌ Error: No frontmatter found" + exit 1 +fi + +# Check required fields +if ! grep -q "^name:" "../SKILL.md"; then + echo "❌ Error: Missing 'name' field" + exit 1 +fi + +if ! grep -q "^description:" "../SKILL.md"; then + echo "❌ Error: Missing 'description' field" + exit 1 +fi + +echo "✅ Skill validation passed"