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", items: 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,
};