@azure-devops/mcp 2.9.0-nightly.20260807 → 2.9.0-nightly.20260809
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tools/auth.js +10 -6
- package/dist/tools/work-items.js +34 -2
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/tools/auth.js
CHANGED
|
@@ -45,10 +45,7 @@ async function searchIdentities(identity, tokenProvider, connectionProvider, use
|
|
|
45
45
|
}
|
|
46
46
|
return await response.json();
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
* Gets the user ID from email or unique name using Azure DevOps Identity API
|
|
50
|
-
*/
|
|
51
|
-
async function getUserIdFromEmail(userEmail, tokenProvider, connectionProvider, userAgentProvider) {
|
|
48
|
+
async function getUserIdentityFromEmail(userEmail, tokenProvider, connectionProvider, userAgentProvider) {
|
|
52
49
|
const identities = await searchIdentities(userEmail, tokenProvider, connectionProvider, userAgentProvider);
|
|
53
50
|
if (!identities || identities.value?.length === 0) {
|
|
54
51
|
throw new Error(`No user found with email/unique name: ${userEmail}`);
|
|
@@ -57,6 +54,13 @@ async function getUserIdFromEmail(userEmail, tokenProvider, connectionProvider,
|
|
|
57
54
|
if (!firstIdentity.id) {
|
|
58
55
|
throw new Error(`No ID found for user with email/unique name: ${userEmail}`);
|
|
59
56
|
}
|
|
60
|
-
return firstIdentity.id;
|
|
57
|
+
return { id: firstIdentity.id, displayName: firstIdentity.providerDisplayName ?? userEmail };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Gets the user ID from email or unique name using Azure DevOps Identity API
|
|
61
|
+
*/
|
|
62
|
+
async function getUserIdFromEmail(userEmail, tokenProvider, connectionProvider, userAgentProvider) {
|
|
63
|
+
const identity = await getUserIdentityFromEmail(userEmail, tokenProvider, connectionProvider, userAgentProvider);
|
|
64
|
+
return identity.id;
|
|
61
65
|
}
|
|
62
|
-
export { getCurrentUserDetails, getUserIdFromEmail, searchIdentities };
|
|
66
|
+
export { getCurrentUserDetails, getUserIdFromEmail, getUserIdentityFromEmail, searchIdentities };
|
package/dist/tools/work-items.js
CHANGED
|
@@ -8,6 +8,7 @@ import { z } from "zod";
|
|
|
8
8
|
import { batchApiVersion, markdownCommentsApiVersion, getEnumKeys, safeEnumConvert, encodeFormattedValue } from "../utils.js";
|
|
9
9
|
import { elicitProject, elicitTeam } from "../shared/elicitations.js";
|
|
10
10
|
import { createExternalContentResponse } from "../shared/content-safety.js";
|
|
11
|
+
import { getUserIdentityFromEmail } from "./auth.js";
|
|
11
12
|
const WORKITEM_TOOLS = {
|
|
12
13
|
wit_work_item: "wit_work_item",
|
|
13
14
|
wit_query: "wit_query",
|
|
@@ -57,6 +58,36 @@ function getArtifactLinkAttributeName(linkType) {
|
|
|
57
58
|
return linkType;
|
|
58
59
|
}
|
|
59
60
|
}
|
|
61
|
+
function escapeHtml(value) {
|
|
62
|
+
const entities = {
|
|
63
|
+
"&": "&",
|
|
64
|
+
"<": "<",
|
|
65
|
+
">": ">",
|
|
66
|
+
'"': """,
|
|
67
|
+
"'": "'",
|
|
68
|
+
};
|
|
69
|
+
return value.replace(/[&<>"']/g, (character) => entities[character]);
|
|
70
|
+
}
|
|
71
|
+
async function resolveCommentMentions(text, format, tokenProvider, connectionProvider, userAgentProvider) {
|
|
72
|
+
const emailMatches = [...text.matchAll(/@<([^<>\s]+@[^<>\s]+)>/g)];
|
|
73
|
+
if (emailMatches.length === 0)
|
|
74
|
+
return text;
|
|
75
|
+
const identities = new Map();
|
|
76
|
+
for (const email of new Set(emailMatches.map((match) => match[1]))) {
|
|
77
|
+
try {
|
|
78
|
+
identities.set(email, await getUserIdentityFromEmail(email, tokenProvider, connectionProvider, userAgentProvider));
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Leave mentions unchanged when their identities cannot be resolved.
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return text.replace(/@<([^<>\s]+@[^<>\s]+)>/g, (mention, email) => {
|
|
85
|
+
const identity = identities.get(email);
|
|
86
|
+
if (!identity)
|
|
87
|
+
return escapeHtml(mention);
|
|
88
|
+
return format === "Markdown" || format === undefined ? `@<${identity.id}>` : `<a href="#" data-vss-mention="version:2.0,${identity.id}">@${escapeHtml(identity.displayName)}</a>`;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
60
91
|
function configureWorkItemTools(server, tokenProvider, connectionProvider, userAgentProvider) {
|
|
61
92
|
// --- wit_work_item ----------------------------------------------------------
|
|
62
93
|
server.tool(WORKITEM_TOOLS.wit_work_item, "Retrieve work item data for a project. Use the action parameter to specify the operation.", {
|
|
@@ -678,6 +709,7 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
678
709
|
const orgUrl = connection.serverUrl;
|
|
679
710
|
const accessToken = await tokenProvider();
|
|
680
711
|
const formatParameter = (format ?? "Markdown") === "Markdown" ? 0 : 1;
|
|
712
|
+
const resolvedText = await resolveCommentMentions(text, format, tokenProvider, connectionProvider, userAgentProvider);
|
|
681
713
|
if (action === "add") {
|
|
682
714
|
const response = await fetch(`${orgUrl}/${encodeURIComponent(resolvedProject)}/_apis/wit/workItems/${workItemId}/comments?format=${formatParameter}&api-version=${markdownCommentsApiVersion}`, {
|
|
683
715
|
method: "POST",
|
|
@@ -686,7 +718,7 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
686
718
|
"Content-Type": "application/json",
|
|
687
719
|
"User-Agent": userAgentProvider(),
|
|
688
720
|
},
|
|
689
|
-
body: JSON.stringify({ text }),
|
|
721
|
+
body: JSON.stringify({ text: resolvedText }),
|
|
690
722
|
});
|
|
691
723
|
if (!response.ok) {
|
|
692
724
|
throw new Error(`Failed to add a work item comment: ${response.statusText}`);
|
|
@@ -703,7 +735,7 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
703
735
|
"Content-Type": "application/json",
|
|
704
736
|
"User-Agent": userAgentProvider(),
|
|
705
737
|
},
|
|
706
|
-
body: JSON.stringify({ text }),
|
|
738
|
+
body: JSON.stringify({ text: resolvedText }),
|
|
707
739
|
});
|
|
708
740
|
if (!response.ok) {
|
|
709
741
|
throw new Error(`Failed to update work item comment: ${response.statusText}`);
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const packageVersion = "2.9.0-nightly.
|
|
1
|
+
export const packageVersion = "2.9.0-nightly.20260809";
|