🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

mcp-udacity-commit

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mcp-udacity-commit - npm Package Compare versions

Comparing version
1.2.0
to
1.2.1
+17
-17
build/index.js

@@ -6,3 +6,3 @@ #!/usr/bin/env node

import { STYLE_GUIDE, BRANCH_GUIDE, validate, formatMessage, validateBranch } from "./lint.js";
const VERSION = "1.2.0";
const VERSION = "1.2.1";
export function createServer() {

@@ -31,12 +31,12 @@ const server = new McpServer({ name: "udacity-commit", version: VERSION });

}, async ({ message }) => {
const r = validate(message);
const report = validate(message);
const text = [
r.valid ? "✅ Compliant with the Udacity style guide." : "❌ Not compliant.",
...r.problems.map((p) => ` • ${p}`),
...r.warnings.map((w) => ` ⚠ ${w}`),
report.valid ? "✅ Compliant with the Udacity style guide." : "❌ Not compliant.",
...report.problems.map((problem) => ` • ${problem}`),
...report.warnings.map((warning) => ` ⚠ ${warning}`),
].join("\n");
const structuredContent = {
valid: r.valid,
problems: r.problems,
warnings: r.warnings,
valid: report.valid,
problems: report.problems,
warnings: report.warnings,
};

@@ -91,12 +91,12 @@ return { content: [{ type: "text", text }], structuredContent };

}, async ({ name }) => {
const r = validateBranch(name);
const report = validateBranch(name);
const text = [
r.valid ? "✅ Compliant branch name." : "❌ Not compliant.",
...r.problems.map((p) => ` • ${p}`),
...r.warnings.map((w) => ` ⚠ ${w}`),
report.valid ? "✅ Compliant branch name." : "❌ Not compliant.",
...report.problems.map((problem) => ` • ${problem}`),
...report.warnings.map((warning) => ` ⚠ ${warning}`),
].join("\n");
const structuredContent = {
valid: r.valid,
problems: r.problems,
warnings: r.warnings,
valid: report.valid,
problems: report.problems,
warnings: report.warnings,
};

@@ -111,5 +111,5 @@ return { content: [{ type: "text", text }], structuredContent };

}
main().catch((err) => {
console.error(err);
main().catch((error) => {
console.error(error);
process.exit(1);
});

@@ -81,3 +81,3 @@ /**

${Object.entries(TYPES)
.map(([t, d]) => `- **${t}**: ${d}`)
.map(([typeName, typeDescription]) => `- **${typeName}**: ${typeDescription}`)
.join("\n")}

@@ -130,10 +130,10 @@

/** Length in Unicode code points (not UTF-16 code units). */
export function width(s) {
return [...s].length;
export function width(text) {
return [...text].length;
}
/** Uppercase the first code point of a string (astral-safe). */
function capitalizeFirst(s) {
const chars = [...s];
function capitalizeFirst(text) {
const chars = [...text];
if (chars.length === 0)
return s;
return text;
return chars[0].toUpperCase() + chars.slice(1).join("");

@@ -192,19 +192,19 @@ }

const subject = rawSubject.replace(/\s+$/, "");
const m = subject.match(/^(\w+): (.*)$/);
if (!m) {
const subjectMatch = subject.match(/^(\w+): (.*)$/);
if (!subjectMatch) {
problems.push(`Subject must follow "type: Subject". Got: "${subject}".`);
}
else {
const [, type, rest] = m;
const [, type, subjectText] = subjectMatch;
if (!TYPES[type]) {
problems.push(`Unknown type "${type}". Use one of: ${Object.keys(TYPES).join(", ")}.`);
}
if (!rest) {
if (!subjectText) {
problems.push("Subject text is empty after the type.");
}
else {
if (/^\p{Ll}/u.test(rest)) {
problems.push(`Subject should begin with a capital letter (got "${[...rest][0]}").`);
if (/^\p{Ll}/u.test(subjectText)) {
problems.push(`Subject should begin with a capital letter (got "${[...subjectText][0]}").`);
}
const firstWord = rest.split(/\s+/)[0];
const firstWord = subjectText.split(/\s+/)[0];
if (NON_IMPERATIVE.has(firstWord.toLowerCase())) {

@@ -225,11 +225,11 @@ warnings.push(`"${firstWord}" looks past-tense/gerund — use the imperative mood ("Add", not "Added").`);

}
for (let i = 2; i < lines.length; i++) {
const line = lines[i];
for (let lineIndex = 2; lineIndex < lines.length; lineIndex++) {
const line = lines[lineIndex];
if (width(line) > BODY_WRAP) {
problems.push(`Line ${i + 1} is ${width(line)} chars; wrap body/footer at ${BODY_WRAP}.`);
problems.push(`Line ${lineIndex + 1} is ${width(line)} chars; wrap body/footer at ${BODY_WRAP}.`);
}
const fm = line.match(/^([A-Za-z][A-Za-z ]*?):\s*(.*)$/);
if (fm && FOOTER_KEYS.some((k) => k.toLowerCase() === fm[1].toLowerCase())) {
if (!/#\d+/.test(fm[2])) {
warnings.push(`Footer "${fm[1]}" should reference an issue, e.g. "${fm[1]}: #123".`);
const footerMatch = line.match(/^([A-Za-z][A-Za-z ]*?):\s*(.*)$/);
if (footerMatch && FOOTER_KEYS.some((footerKey) => footerKey.toLowerCase() === footerMatch[1].toLowerCase())) {
if (!/#\d+/.test(footerMatch[2])) {
warnings.push(`Footer "${footerMatch[1]}" should reference an issue, e.g. "${footerMatch[1]}: #123".`);
}

@@ -284,9 +284,9 @@ }

}
const slash = branch.indexOf("/");
if (slash === -1) {
const slashIndex = branch.indexOf("/");
if (slashIndex === -1) {
problems.push(`Branch must follow "type/description". Got: "${branch}".`);
return { valid: false, problems, warnings };
}
const type = branch.slice(0, slash);
const description = branch.slice(slash + 1);
const type = branch.slice(0, slashIndex);
const description = branch.slice(slashIndex + 1);
if (!BRANCH_TYPES.includes(type)) {

@@ -293,0 +293,0 @@ problems.push(`Unknown type "${type}". Use one of: ${BRANCH_TYPES.join(", ")}.`);

{
"name": "mcp-udacity-commit",
"version": "1.2.0",
"version": "1.2.1",
"description": "MCP server that validates and formats git commit messages per the Udacity Git Commit Message Style Guide.",

@@ -5,0 +5,0 @@ "type": "module",