Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:52:42 +08:00
commit 4bb7de1bdc
18 changed files with 1789 additions and 0 deletions

View File

@@ -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"
]
}

3
README.md Normal file
View File

@@ -0,0 +1,3 @@
# api-versioning-manager
Manage API versions with migration strategies and backward compatibility

View File

@@ -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': `</docs/migration/${requestedVersion}>; 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

101
plugin.lock.json Normal file
View File

@@ -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": []
}
}

View File

@@ -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.

View File

@@ -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"]
}
}
}
]
}

View File

@@ -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": []
}
]
}

View File

@@ -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": []
}
}

View File

@@ -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.**

View File

@@ -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!

View File

@@ -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)"
}
}
}

View File

@@ -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"
}
}

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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"

View File

@@ -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"