import { z } from "zod";
/**
* Communication Tools - Automate documentation and git messaging
*/
// ============================================
// Generate Commit Message
// ============================================
export const generateCommitMessageSchema = {
name: "generate_commit_message",
description: "Generates a semantic commit message based on changes",
inputSchema: z.object({
type: z.enum(["feat", "fix", "docs", "style", "refactor", "test", "chore", "perf", "ci", "build", "revert"]).describe("Commit type"),
scope: z.string().optional().describe("Scope of the change (e.g. 'auth', 'api')"),
description: z.string().describe("Short description of what changed"),
breaking: z.boolean().optional().describe("Is this a breaking change?"),
details: z.string().optional().describe("Detailed explanation (body)")
})
};
export function generateCommitMessageHandler(args: { type: string; scope?: string; description: string; breaking?: boolean; details?: string }) {
const { type, scope, description, breaking, details } = args;
const scopeStr = scope ? `(${scope})` : "";
const breakingMark = breaking ? "!" : "";
let message = `${type}${scopeStr}${breakingMark}: ${description}`;
if (details || breaking) {
message += "\n\n";
if (breaking) {
message += "BREAKING CHANGE: " + (details || description) + "\n";
}
if (details) {
message += details;
}
}
return {
content: [{
type: "text",
text: `# Generated Commit Message\n\n\`\`\`text\n${message}\n\`\`\`\n\n**To verify:**\n1. Check if type '${type}' is correct.\n2. Ensure description is imperative ("add" not "added").`
}]
};
}
// ============================================
// Generate PR Description
// ============================================
export const generatePRDescriptionSchema = {
name: "generate_pr_description",
description: "Generates a comprehensive Pull Request description",
inputSchema: z.object({
title: z.string().describe("PR Title"),
type: z.enum(["feature", "bugfix", "refactor", "docs", "maintenance"]).describe("Type of PR"),
summary: z.string().describe("High-level summary of changes"),
changes: z.array(z.string()).describe("List of specific changes"),
testing: z.string().optional().describe("How to test these changes"),
relatedIssues: z.array(z.string()).optional().describe("Linked issue numbers")
})
};
export function generatePRDescriptionHandler(args: { title: string; type: string; summary: string; changes: string[]; testing?: string; relatedIssues?: string[] }) {
const { title, type, summary, changes, testing, relatedIssues = [] } = args;
const labels: Record<string, string> = {
feature: "β¨ Feature",
bugfix: "π Bug Fix",
refactor: "β»οΈ Refactor",
docs: "π Documentation",
maintenance: "π§ Maintenance"
};
const md = `# ${title}
## Type of Change
- [${type === 'feature' ? 'x' : ' '}] β¨ New feature
- [${type === 'bugfix' ? 'x' : ' '}] π Bug fix
- [${type === 'refactor' ? 'x' : ' '}] β»οΈ Refactoring
- [${type === 'docs' ? 'x' : ' '}] π Documentation
- [${type === 'maintenance' ? 'x' : ' '}] π§ Maintenance
## Summary
${summary}
## π Key Changes
${changes.map(c => `- ${c}`).join('\n')}
## π§ͺ Testing Plan
${testing || "N/A"}
## π Related Issues
${relatedIssues.length ? relatedIssues.map(i => `- Closes #${i}`).join('\n') : "None"}
## β
Checklist
- [ ] Code follows project style guidelines
- [ ] Tests passed locally
- [ ] Documentation updated
`;
return {
content: [{
type: "text",
text: `# PR Description\n\n\`\`\`markdown\n${md}\n\`\`\``
}]
};
}
// ============================================
// Update Changelog
// ============================================
export const updateChangelogSchema = {
name: "update_changelog",
description: "Generates a changelog entry following 'Keep a Changelog' format",
inputSchema: z.object({
version: z.string().describe("New version number (e.g. 1.2.0)"),
date: z.string().optional().default(new Date().toISOString().split('T')[0]),
added: z.array(z.string()).optional(),
changed: z.array(z.string()).optional(),
deprecated: z.array(z.string()).optional(),
removed: z.array(z.string()).optional(),
fixed: z.array(z.string()).optional(),
security: z.array(z.string()).optional()
})
};
export function updateChangelogHandler(args: { version: string; date?: string; added?: string[]; changed?: string[]; deprecated?: string[]; removed?: string[]; fixed?: string[]; security?: string[] }) {
const { version, date, added, changed, deprecated, removed, fixed, security } = args;
let content = `## [${version}] - ${date}\n`;
const sections = [
{ title: "Added", items: added },
{ title: "Changed", items: changed },
{ title: "Deprecated", items: deprecated },
{ title: "Removed", items: removed },
{ title: "Fixed", fixed },
{ title: "Security", items: security }
];
sections.forEach(sec => {
if (sec.items && sec.items.length > 0) {
content += `\n### ${sec.title}\n${sec.items.map(i => `- ${i}`).join('\n')}`;
}
});
return {
content: [{
type: "text",
text: `# Changelog Entry\n\n\`\`\`markdown\n${content}\n\`\`\`\n\nπ **Action**: Prepend this to your \`CHANGELOG.md\`.`
}]
};
}
// Export all
export const communicationTools = {
generateCommitMessageSchema, generateCommitMessageHandler,
generatePRDescriptionSchema, generatePRDescriptionHandler,
updateChangelogSchema, updateChangelogHandler
};