@azure-devops/mcp 2.10.0-nightly.20261007 → 2.10.0-nightly.20261009
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/work-items.js +8 -2
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/tools/work-items.js
CHANGED
|
@@ -440,7 +440,7 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
440
440
|
return { content: [{ type: "text", text: "attachmentId is required for download" }], isError: true };
|
|
441
441
|
if (savePath) {
|
|
442
442
|
const localFileName = fileName ?? attachmentId;
|
|
443
|
-
if (localFileName.includes("\0") || path.posix.basename(localFileName) !== localFileName || path.win32.basename(localFileName) !== localFileName) {
|
|
443
|
+
if (!localFileName || localFileName.includes("\0") || path.posix.basename(localFileName) !== localFileName || path.win32.basename(localFileName) !== localFileName) {
|
|
444
444
|
throw new Error("Invalid fileName: path components are not allowed.");
|
|
445
445
|
}
|
|
446
446
|
}
|
|
@@ -455,6 +455,12 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
455
455
|
}
|
|
456
456
|
const workItemApi = await connection.getWorkItemTrackingApi();
|
|
457
457
|
const stream = await workItemApi.getAttachmentContent(attachmentId, fileName, resolvedProject);
|
|
458
|
+
const responseStream = stream;
|
|
459
|
+
if (responseStream.statusCode !== undefined && (responseStream.statusCode < 200 || responseStream.statusCode >= 300)) {
|
|
460
|
+
responseStream.resume();
|
|
461
|
+
const statusMessage = responseStream.statusMessage ? ` ${responseStream.statusMessage}` : "";
|
|
462
|
+
throw new Error(`Attachment download failed: HTTP ${responseStream.statusCode}${statusMessage}`);
|
|
463
|
+
}
|
|
458
464
|
const chunks = [];
|
|
459
465
|
await new Promise((resolve, reject) => {
|
|
460
466
|
stream.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
|
|
@@ -469,7 +475,7 @@ function configureWorkItemTools(server, tokenProvider, connectionProvider, userA
|
|
|
469
475
|
if (relativeDirectory === ".." || relativeDirectory.startsWith(`..${path.sep}`) || path.isAbsolute(relativeDirectory)) {
|
|
470
476
|
throw new Error("Invalid savePath: destination must remain inside the workspace.");
|
|
471
477
|
}
|
|
472
|
-
const localFilePath = path.
|
|
478
|
+
const localFilePath = path.resolve(resolvedDirectory, fileName ?? attachmentId);
|
|
473
479
|
// O_EXCL fails if the file (or a symlink) already exists, so there is no check-then-write race.
|
|
474
480
|
const file = await open(localFilePath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | (constants.O_NOFOLLOW ?? 0), 0o600);
|
|
475
481
|
try {
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const packageVersion = "2.10.0-nightly.
|
|
1
|
+
export const packageVersion = "2.10.0-nightly.20261009";
|
package/package.json
CHANGED