@daghis/teamcity-mcp 1.10.9 → 1.11.0
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/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +7 -0
- package/dist/index.js +417 -304
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/index.js
CHANGED
|
@@ -34,21 +34,21 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
34
34
|
));
|
|
35
35
|
|
|
36
36
|
// src/teamcity/errors.ts
|
|
37
|
-
function isRetryableError(
|
|
38
|
-
if (
|
|
39
|
-
if (
|
|
37
|
+
function isRetryableError(error3) {
|
|
38
|
+
if (error3 instanceof TeamCityAPIError) {
|
|
39
|
+
if (error3 instanceof TeamCityNetworkError) {
|
|
40
40
|
return true;
|
|
41
41
|
}
|
|
42
|
-
if (
|
|
42
|
+
if (error3 instanceof TeamCityTimeoutError) {
|
|
43
43
|
return true;
|
|
44
44
|
}
|
|
45
|
-
if (
|
|
45
|
+
if (error3 instanceof TeamCityServerError) {
|
|
46
46
|
return true;
|
|
47
47
|
}
|
|
48
|
-
if (
|
|
48
|
+
if (error3 instanceof TeamCityRateLimitError) {
|
|
49
49
|
return true;
|
|
50
50
|
}
|
|
51
|
-
if (
|
|
51
|
+
if (error3.statusCode === 503) {
|
|
52
52
|
return true;
|
|
53
53
|
}
|
|
54
54
|
}
|
|
@@ -78,21 +78,21 @@ var init_errors = __esm({
|
|
|
78
78
|
/**
|
|
79
79
|
* Create from Axios error
|
|
80
80
|
*/
|
|
81
|
-
static fromAxiosError(
|
|
82
|
-
if (
|
|
83
|
-
const data =
|
|
81
|
+
static fromAxiosError(error3, requestId) {
|
|
82
|
+
if (error3.response) {
|
|
83
|
+
const data = error3.response.data;
|
|
84
84
|
return new _TeamCityAPIError(
|
|
85
|
-
(typeof data?.["message"] === "string" ? data["message"] : null) ??
|
|
86
|
-
(typeof data?.["code"] === "string" ? data["code"] : null) ?? `HTTP_${
|
|
87
|
-
|
|
85
|
+
(typeof data?.["message"] === "string" ? data["message"] : null) ?? error3.message,
|
|
86
|
+
(typeof data?.["code"] === "string" ? data["code"] : null) ?? `HTTP_${error3.response.status}`,
|
|
87
|
+
error3.response.status,
|
|
88
88
|
data,
|
|
89
89
|
requestId,
|
|
90
|
-
|
|
90
|
+
error3
|
|
91
91
|
);
|
|
92
|
-
} else if (
|
|
93
|
-
return new TeamCityNetworkError(
|
|
92
|
+
} else if (error3.request !== null && error3.request !== void 0) {
|
|
93
|
+
return new TeamCityNetworkError(error3.message, requestId, error3);
|
|
94
94
|
} else {
|
|
95
|
-
return new TeamCityRequestError(
|
|
95
|
+
return new TeamCityRequestError(error3.message, requestId, error3);
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
toJSON() {
|
|
@@ -212,7 +212,7 @@ var require_is_retry_allowed = __commonJS({
|
|
|
212
212
|
"CERT_REJECTED",
|
|
213
213
|
"HOSTNAME_MISMATCH"
|
|
214
214
|
]);
|
|
215
|
-
module2.exports = (
|
|
215
|
+
module2.exports = (error3) => !denyList.has(error3 && error3.code);
|
|
216
216
|
}
|
|
217
217
|
});
|
|
218
218
|
|
|
@@ -275,16 +275,16 @@ var init_build_status_manager = __esm({
|
|
|
275
275
|
this.setCachedResult(cacheKey, result);
|
|
276
276
|
}
|
|
277
277
|
return result;
|
|
278
|
-
} catch (
|
|
279
|
-
if (
|
|
278
|
+
} catch (error3) {
|
|
279
|
+
if (error3 != null && typeof error3 === "object" && "response" in error3 && error3.response?.status === 404) {
|
|
280
280
|
throw new BuildNotFoundError(`Build not found: ${options.buildId ?? options.buildNumber}`);
|
|
281
281
|
}
|
|
282
|
-
if (
|
|
282
|
+
if (error3 != null && typeof error3 === "object" && "response" in error3 && error3.response?.status === 403) {
|
|
283
283
|
throw new BuildAccessDeniedError(
|
|
284
284
|
`Access denied to build: ${options.buildId ?? options.buildNumber}`
|
|
285
285
|
);
|
|
286
286
|
}
|
|
287
|
-
throw
|
|
287
|
+
throw error3;
|
|
288
288
|
}
|
|
289
289
|
}
|
|
290
290
|
/**
|
|
@@ -305,11 +305,11 @@ var init_build_status_manager = __esm({
|
|
|
305
305
|
throw new BuildNotFoundError(`No builds found for locator: ${locator}`);
|
|
306
306
|
}
|
|
307
307
|
return this.transformBuildResponse(firstBuild, {});
|
|
308
|
-
} catch (
|
|
309
|
-
if (
|
|
308
|
+
} catch (error3) {
|
|
309
|
+
if (error3 != null && typeof error3 === "object" && "response" in error3 && error3.response?.status === 404) {
|
|
310
310
|
throw new BuildNotFoundError(`No builds found for locator: ${locator}`);
|
|
311
311
|
}
|
|
312
|
-
throw
|
|
312
|
+
throw error3;
|
|
313
313
|
}
|
|
314
314
|
}
|
|
315
315
|
/**
|
|
@@ -659,7 +659,7 @@ async function startServerLifecycle(server, transport) {
|
|
|
659
659
|
};
|
|
660
660
|
server.onerror = (rawError) => {
|
|
661
661
|
previousOnError?.(rawError);
|
|
662
|
-
const
|
|
662
|
+
const error3 = rawError instanceof Error ? rawError : new Error(String(rawError));
|
|
663
663
|
const closeTransport = () => {
|
|
664
664
|
if (!transport.close) {
|
|
665
665
|
return Promise.resolve();
|
|
@@ -673,7 +673,7 @@ async function startServerLifecycle(server, transport) {
|
|
|
673
673
|
void closeTransport().catch(() => {
|
|
674
674
|
}).finally(() => {
|
|
675
675
|
cleanup();
|
|
676
|
-
reject(
|
|
676
|
+
reject(error3);
|
|
677
677
|
});
|
|
678
678
|
};
|
|
679
679
|
});
|
|
@@ -736,7 +736,8 @@ var TeamCityLogger = class _TeamCityLogger {
|
|
|
736
736
|
if (enableConsole) {
|
|
737
737
|
transports.push(
|
|
738
738
|
new import_winston.default.transports.Console({
|
|
739
|
-
format: isProduction ? prodFormat : devFormat
|
|
739
|
+
format: isProduction ? prodFormat : devFormat,
|
|
740
|
+
stderrLevels: ["error", "warn", "info", "http", "verbose", "debug", "silly"]
|
|
740
741
|
})
|
|
741
742
|
);
|
|
742
743
|
}
|
|
@@ -791,8 +792,8 @@ var TeamCityLogger = class _TeamCityLogger {
|
|
|
791
792
|
if ((0, import_node_fs.existsSync)(directory) === false) {
|
|
792
793
|
(0, import_node_fs.mkdirSync)(directory, { recursive: true });
|
|
793
794
|
}
|
|
794
|
-
} catch (
|
|
795
|
-
this.winston?.warn?.("Failed to create log directory, using current directory", { error:
|
|
795
|
+
} catch (error3) {
|
|
796
|
+
this.winston?.warn?.("Failed to create log directory, using current directory", { error: error3 });
|
|
796
797
|
}
|
|
797
798
|
}
|
|
798
799
|
/**
|
|
@@ -839,13 +840,13 @@ var TeamCityLogger = class _TeamCityLogger {
|
|
|
839
840
|
/**
|
|
840
841
|
* Error level logging with optional error object
|
|
841
842
|
*/
|
|
842
|
-
error(message,
|
|
843
|
+
error(message, error3, context = {}) {
|
|
843
844
|
const errorContext = { ...context };
|
|
844
|
-
if (
|
|
845
|
-
errorContext["error"] =
|
|
846
|
-
errorContext["stack"] =
|
|
847
|
-
} else if (
|
|
848
|
-
errorContext["error"] = String(
|
|
845
|
+
if (error3 instanceof Error) {
|
|
846
|
+
errorContext["error"] = error3.message;
|
|
847
|
+
errorContext["stack"] = error3.stack;
|
|
848
|
+
} else if (error3 != null) {
|
|
849
|
+
errorContext["error"] = String(error3);
|
|
849
850
|
}
|
|
850
851
|
this.winston.error(message, errorContext);
|
|
851
852
|
}
|
|
@@ -928,27 +929,139 @@ var logger = {
|
|
|
928
929
|
debug: (message, context) => getLogger().debug(message, context),
|
|
929
930
|
info: (message, context) => getLogger().info(message, context),
|
|
930
931
|
warn: (message, context) => getLogger().warn(message, context),
|
|
931
|
-
error: (message,
|
|
932
|
+
error: (message, error3, context) => getLogger().error(message, error3, context),
|
|
932
933
|
child: (context) => getLogger().child(context),
|
|
933
934
|
logToolExecution: (toolName, args, result, duration, context) => getLogger().logToolExecution(toolName, args, result, duration, context),
|
|
934
935
|
logTeamCityRequest: (method, url, status, duration, context) => getLogger().logTeamCityRequest(method, url, status, duration, context),
|
|
935
936
|
logLifecycle: (event, details) => getLogger().logLifecycle(event, details)
|
|
936
937
|
};
|
|
938
|
+
var { debug, info, warn, error, child } = logger;
|
|
937
939
|
|
|
938
940
|
// src/utils/logger.ts
|
|
939
|
-
function
|
|
941
|
+
function info2(message, meta) {
|
|
940
942
|
logger.info(message, meta);
|
|
941
943
|
}
|
|
942
|
-
function
|
|
944
|
+
function error2(message, err, meta) {
|
|
943
945
|
logger.error(message, err, meta);
|
|
944
946
|
}
|
|
945
|
-
function
|
|
947
|
+
function warn2(message, meta) {
|
|
946
948
|
logger.warn(message, meta);
|
|
947
949
|
}
|
|
948
|
-
function
|
|
950
|
+
function debug2(message, meta) {
|
|
949
951
|
logger.debug(message, meta);
|
|
950
952
|
}
|
|
951
953
|
|
|
954
|
+
// package.json
|
|
955
|
+
var package_default = {
|
|
956
|
+
name: "@daghis/teamcity-mcp",
|
|
957
|
+
version: "1.11.0",
|
|
958
|
+
description: "Model Control Protocol server for TeamCity CI/CD integration with AI coding assistants",
|
|
959
|
+
mcpName: "io.github.daghis/teamcity",
|
|
960
|
+
main: "dist/index.js",
|
|
961
|
+
types: "dist/index.d.ts",
|
|
962
|
+
bin: {
|
|
963
|
+
"teamcity-mcp": "dist/index.js"
|
|
964
|
+
},
|
|
965
|
+
engines: {
|
|
966
|
+
node: ">=20.10.0 <21"
|
|
967
|
+
},
|
|
968
|
+
scripts: {
|
|
969
|
+
dev: "node ./node_modules/tsx/dist/cli.mjs watch src/index.ts",
|
|
970
|
+
"dev:interactive": "bash scripts/interact.sh",
|
|
971
|
+
build: "node scripts/build.cjs",
|
|
972
|
+
"build:bundle": "CODECOV_BUNDLE=true npm run build",
|
|
973
|
+
"build:tsc": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
|
974
|
+
start: "node dist/index.js",
|
|
975
|
+
test: "jest",
|
|
976
|
+
"test:watch": "jest --watch",
|
|
977
|
+
"test:coverage": "jest --coverage --runInBand",
|
|
978
|
+
"test:coverage:ci": "jest -c jest.ci.config.js --coverage --runInBand",
|
|
979
|
+
"test:unit": "jest tests/unit",
|
|
980
|
+
"test:integration": "node scripts/verify-integration-env.cjs && jest tests/integration",
|
|
981
|
+
"test:ci": "jest --coverage --ci --reporters=default --reporters=jest-junit",
|
|
982
|
+
lint: `sh -c "node ./node_modules/eslint/bin/eslint.js 'src/**/*.{ts,tsx}' 'tests/**/*.test.{ts,tsx,js}' --fix --no-error-on-unmatched-pattern"`,
|
|
983
|
+
"lint:check": "node ./node_modules/eslint/bin/eslint.js 'src/**/*.{ts,tsx}' 'tests/**/*.test.{ts,tsx,js}' --no-error-on-unmatched-pattern",
|
|
984
|
+
format: "node ./node_modules/prettier/bin/prettier.cjs --write 'src/**/*.{ts,tsx,json,md}' 'tests/**/*.{ts,tsx,js,json,md}'",
|
|
985
|
+
"format:check": "node ./node_modules/prettier/bin/prettier.cjs --check 'src/**/*.{ts,tsx,json,md}' 'tests/**/*.{ts,tsx,js,json,md}'",
|
|
986
|
+
typecheck: "node ./node_modules/typescript/bin/tsc --noEmit -p tsconfig.build.json",
|
|
987
|
+
"typecheck:all": "node ./node_modules/typescript/bin/tsc --noEmit",
|
|
988
|
+
check: "npm run typecheck && npm run lint:check && npm run format:check",
|
|
989
|
+
clean: "rm -rf dist coverage",
|
|
990
|
+
"fetch:swagger": "node ./node_modules/tsx/dist/cli.mjs scripts/fetch-swagger-spec.ts",
|
|
991
|
+
"generate:client": "npm exec -y @openapitools/openapi-generator-cli@2.23.1 -- generate -c openapi-generator-config.json",
|
|
992
|
+
"update:client": "npm run fetch:swagger -- --force && npm run generate:client",
|
|
993
|
+
e2e: "node ./node_modules/tsx/dist/cli.mjs tests/e2e/index.ts",
|
|
994
|
+
"e2e:build": "npm run build && node dist/e2e/index.js",
|
|
995
|
+
"e2e:setup": "node ./node_modules/tsx/dist/cli.mjs tests/e2e/setup-playground.ts",
|
|
996
|
+
"e2e:cleanup": "node ./node_modules/tsx/dist/cli.mjs tests/e2e/cleanup.ts",
|
|
997
|
+
"generate:notices": "node scripts/generate-third-party-notices.cjs"
|
|
998
|
+
},
|
|
999
|
+
keywords: [
|
|
1000
|
+
"mcp",
|
|
1001
|
+
"teamcity",
|
|
1002
|
+
"ci",
|
|
1003
|
+
"cd",
|
|
1004
|
+
"ai",
|
|
1005
|
+
"claude",
|
|
1006
|
+
"cursor",
|
|
1007
|
+
"windsurf",
|
|
1008
|
+
"devops"
|
|
1009
|
+
],
|
|
1010
|
+
author: "",
|
|
1011
|
+
license: "MIT",
|
|
1012
|
+
repository: {
|
|
1013
|
+
type: "git",
|
|
1014
|
+
url: "https://github.com/Daghis/teamcity-mcp.git"
|
|
1015
|
+
},
|
|
1016
|
+
dependencies: {
|
|
1017
|
+
"@modelcontextprotocol/sdk": "^1.18.0",
|
|
1018
|
+
ajv: "^8.17.1",
|
|
1019
|
+
"ajv-formats": "^3.0.1",
|
|
1020
|
+
axios: "^1.12.1",
|
|
1021
|
+
dotenv: "^17.2.2",
|
|
1022
|
+
express: "^5.1.0",
|
|
1023
|
+
inversify: "^7.9.1",
|
|
1024
|
+
morgan: "^1.10.0",
|
|
1025
|
+
"reflect-metadata": "^0.2.2",
|
|
1026
|
+
tslib: "^2.8.1",
|
|
1027
|
+
winston: "^3.11.0",
|
|
1028
|
+
zod: "^4.1.11"
|
|
1029
|
+
},
|
|
1030
|
+
devDependencies: {
|
|
1031
|
+
"@codecov/bundler-plugin-core": "^1.9.1",
|
|
1032
|
+
"@eslint/compat": "^1.4.0",
|
|
1033
|
+
"@esbuild-plugins/tsconfig-paths": "^0.1.2",
|
|
1034
|
+
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
|
1035
|
+
"@types/ajv": "^1.0.4",
|
|
1036
|
+
"@types/express": "^5.0.3",
|
|
1037
|
+
"@types/jest": "^30.0.0",
|
|
1038
|
+
"@types/js-yaml": "^4.0.9",
|
|
1039
|
+
"@types/morgan": "^1.9.9",
|
|
1040
|
+
"@types/node": "^24.3.1",
|
|
1041
|
+
"@typescript-eslint/eslint-plugin": "^8.44.1",
|
|
1042
|
+
"@typescript-eslint/parser": "^8.44.1",
|
|
1043
|
+
"axios-retry": "^4.5.0",
|
|
1044
|
+
esbuild: "^0.25.9",
|
|
1045
|
+
eslint: "^9.36.0",
|
|
1046
|
+
"eslint-config-prettier": "^10.1.8",
|
|
1047
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
1048
|
+
"eslint-plugin-import": "^2.32.0",
|
|
1049
|
+
"eslint-plugin-prettier": "^5.0.1",
|
|
1050
|
+
jest: "^30.1.3",
|
|
1051
|
+
"jest-junit": "^16.0.0",
|
|
1052
|
+
"js-yaml": "^4.1.0",
|
|
1053
|
+
prettier: "^3.1.0",
|
|
1054
|
+
"ts-jest": "^29.4.1",
|
|
1055
|
+
"tsc-alias": "^1.8.8",
|
|
1056
|
+
"tsconfig-paths": "^4.2.0",
|
|
1057
|
+
tsx: "^4.6.0",
|
|
1058
|
+
typescript: "^5.3.2"
|
|
1059
|
+
},
|
|
1060
|
+
overrides: {
|
|
1061
|
+
axios: "^1.12.1"
|
|
1062
|
+
}
|
|
1063
|
+
};
|
|
1064
|
+
|
|
952
1065
|
// src/tools.ts
|
|
953
1066
|
var import_node_crypto = require("node:crypto");
|
|
954
1067
|
var import_node_fs2 = require("node:fs");
|
|
@@ -1074,11 +1187,11 @@ var AgentRequirementsManager = class {
|
|
|
1074
1187
|
JSON_GET_HEADERS
|
|
1075
1188
|
);
|
|
1076
1189
|
return response.data;
|
|
1077
|
-
} catch (
|
|
1078
|
-
if (typeof
|
|
1190
|
+
} catch (error3) {
|
|
1191
|
+
if (typeof error3 === "object" && error3 !== null && "response" in error3 && error3.response?.status === 404) {
|
|
1079
1192
|
return null;
|
|
1080
1193
|
}
|
|
1081
|
-
throw
|
|
1194
|
+
throw error3;
|
|
1082
1195
|
}
|
|
1083
1196
|
}
|
|
1084
1197
|
buildPayload(existing, input) {
|
|
@@ -1155,15 +1268,15 @@ var ArtifactManager = class _ArtifactManager {
|
|
|
1155
1268
|
}
|
|
1156
1269
|
this.cacheResult(cacheKey, artifacts);
|
|
1157
1270
|
return artifacts;
|
|
1158
|
-
} catch (
|
|
1159
|
-
const err =
|
|
1271
|
+
} catch (error3) {
|
|
1272
|
+
const err = error3;
|
|
1160
1273
|
if (err.response?.status === 401) {
|
|
1161
1274
|
throw new Error("Authentication failed: Invalid TeamCity token");
|
|
1162
1275
|
}
|
|
1163
1276
|
if (err.response?.status === 404) {
|
|
1164
1277
|
throw new Error(`Build not found: ${buildId}`);
|
|
1165
1278
|
}
|
|
1166
|
-
const errMsg = err.message ?? String(
|
|
1279
|
+
const errMsg = err.message ?? String(error3);
|
|
1167
1280
|
throw new Error(`Failed to fetch artifacts: ${errMsg}`);
|
|
1168
1281
|
}
|
|
1169
1282
|
}
|
|
@@ -1175,7 +1288,7 @@ var ArtifactManager = class _ArtifactManager {
|
|
|
1175
1288
|
for (let attempt = 1; attempt <= _ArtifactManager.artifactRetryAttempts; attempt += 1) {
|
|
1176
1289
|
const artifacts = await this.listArtifacts(buildId, { forceRefresh: attempt > 1 });
|
|
1177
1290
|
const listSample = artifacts.slice(0, 5).map((entry) => entry.path);
|
|
1178
|
-
|
|
1291
|
+
debug2("artifact-manager.downloadArtifact.list", {
|
|
1179
1292
|
buildId,
|
|
1180
1293
|
requested: artifactPath,
|
|
1181
1294
|
availableCount: artifacts.length,
|
|
@@ -1190,7 +1303,7 @@ var ArtifactManager = class _ArtifactManager {
|
|
|
1190
1303
|
forceRefresh: true
|
|
1191
1304
|
});
|
|
1192
1305
|
const nestedSample = nestedArtifacts.slice(0, 5).map((entry) => entry.path);
|
|
1193
|
-
|
|
1306
|
+
debug2("artifact-manager.downloadArtifact.listNested", {
|
|
1194
1307
|
buildId,
|
|
1195
1308
|
requested: artifactPath,
|
|
1196
1309
|
availableCount: nestedArtifacts.length,
|
|
@@ -1207,7 +1320,7 @@ var ArtifactManager = class _ArtifactManager {
|
|
|
1207
1320
|
}
|
|
1208
1321
|
}
|
|
1209
1322
|
if (!artifact) {
|
|
1210
|
-
|
|
1323
|
+
debug2("artifact-manager.downloadArtifact.miss", {
|
|
1211
1324
|
buildId,
|
|
1212
1325
|
requested: artifactPath,
|
|
1213
1326
|
attempts: _ArtifactManager.artifactRetryAttempts
|
|
@@ -1285,11 +1398,11 @@ var ArtifactManager = class _ArtifactManager {
|
|
|
1285
1398
|
content,
|
|
1286
1399
|
mimeType: typeof axiosResponse.headers?.["content-type"] === "string" ? axiosResponse.headers["content-type"] : void 0
|
|
1287
1400
|
};
|
|
1288
|
-
} catch (
|
|
1401
|
+
} catch (error3) {
|
|
1289
1402
|
let errMsg;
|
|
1290
|
-
if ((0, import_axios.isAxiosError)(
|
|
1291
|
-
const status =
|
|
1292
|
-
const data =
|
|
1403
|
+
if ((0, import_axios.isAxiosError)(error3)) {
|
|
1404
|
+
const status = error3.response?.status;
|
|
1405
|
+
const data = error3.response?.data;
|
|
1293
1406
|
let detail;
|
|
1294
1407
|
if (typeof data === "string") {
|
|
1295
1408
|
detail = data;
|
|
@@ -1302,7 +1415,7 @@ var ArtifactManager = class _ArtifactManager {
|
|
|
1302
1415
|
}
|
|
1303
1416
|
errMsg = `HTTP ${status ?? "unknown"}${detail ? `: ${detail}` : ""}`;
|
|
1304
1417
|
} else {
|
|
1305
|
-
errMsg =
|
|
1418
|
+
errMsg = error3 instanceof Error ? error3.message : "Unknown error";
|
|
1306
1419
|
}
|
|
1307
1420
|
throw new Error(`Failed to download artifact: ${errMsg}`);
|
|
1308
1421
|
}
|
|
@@ -1320,11 +1433,11 @@ var ArtifactManager = class _ArtifactManager {
|
|
|
1320
1433
|
try {
|
|
1321
1434
|
const artifact = await this.downloadArtifact(buildId, path, downloadOptions);
|
|
1322
1435
|
results.push(artifact);
|
|
1323
|
-
} catch (
|
|
1324
|
-
const reason =
|
|
1436
|
+
} catch (error3) {
|
|
1437
|
+
const reason = error3;
|
|
1325
1438
|
const message = reason instanceof Error ? reason.message : typeof reason === "object" && reason?.message ? String(reason.message) : String(reason ?? "Unknown error");
|
|
1326
1439
|
const fallbackName = path ?? "unknown";
|
|
1327
|
-
|
|
1440
|
+
debug2("artifact-manager.downloadMultipleArtifacts.error", {
|
|
1328
1441
|
buildId,
|
|
1329
1442
|
requested: fallbackName,
|
|
1330
1443
|
encoding: downloadOptions.encoding,
|
|
@@ -1625,7 +1738,7 @@ var BuildConfigurationCloneManager = class {
|
|
|
1625
1738
|
} catch (err) {
|
|
1626
1739
|
const axiosError = err;
|
|
1627
1740
|
if (axiosError.response?.status === 404) {
|
|
1628
|
-
|
|
1741
|
+
debug2("Build configuration not found", { configId });
|
|
1629
1742
|
return null;
|
|
1630
1743
|
}
|
|
1631
1744
|
if (axiosError.response?.status === 403) {
|
|
@@ -1649,11 +1762,11 @@ var BuildConfigurationCloneManager = class {
|
|
|
1649
1762
|
} catch (err) {
|
|
1650
1763
|
const axiosError = err;
|
|
1651
1764
|
if (axiosError.response?.status === 404) {
|
|
1652
|
-
|
|
1765
|
+
debug2("Target project not found", { projectId });
|
|
1653
1766
|
return null;
|
|
1654
1767
|
}
|
|
1655
1768
|
if (axiosError.response?.status === 403) {
|
|
1656
|
-
|
|
1769
|
+
debug2("No permission to access target project", { projectId });
|
|
1657
1770
|
return null;
|
|
1658
1771
|
}
|
|
1659
1772
|
throw err;
|
|
@@ -1702,7 +1815,7 @@ var BuildConfigurationCloneManager = class {
|
|
|
1702
1815
|
}
|
|
1703
1816
|
return { id: newId, name: newName };
|
|
1704
1817
|
} catch (err) {
|
|
1705
|
-
|
|
1818
|
+
error2("Failed to clone VCS root", err);
|
|
1706
1819
|
throw new Error(`Failed to clone VCS root: ${err.message}`);
|
|
1707
1820
|
}
|
|
1708
1821
|
}
|
|
@@ -1824,29 +1937,29 @@ var BuildConfigurationCloneManager = class {
|
|
|
1824
1937
|
parameters: options.parameters,
|
|
1825
1938
|
url: `${teamcityUrl}/viewType.html?buildTypeId=${id}`
|
|
1826
1939
|
};
|
|
1827
|
-
|
|
1940
|
+
info2("Build configuration cloned", {
|
|
1828
1941
|
id: result.id,
|
|
1829
1942
|
name: result.name,
|
|
1830
1943
|
sourceId: source.id
|
|
1831
1944
|
});
|
|
1832
1945
|
return result;
|
|
1833
1946
|
} catch (err) {
|
|
1834
|
-
const
|
|
1835
|
-
if (
|
|
1947
|
+
const error3 = err;
|
|
1948
|
+
if (error3.response?.status === 409) {
|
|
1836
1949
|
throw new Error(`Build configuration already exists with ID: ${configId}`);
|
|
1837
1950
|
}
|
|
1838
|
-
if (
|
|
1951
|
+
if (error3.response?.status === 403) {
|
|
1839
1952
|
throw new Error("Permission denied: You need project edit permissions");
|
|
1840
1953
|
}
|
|
1841
|
-
if (
|
|
1842
|
-
const message =
|
|
1954
|
+
if (error3.response?.status === 400) {
|
|
1955
|
+
const message = error3.response?.data?.message ?? "Invalid configuration";
|
|
1843
1956
|
throw new Error(`Invalid configuration: ${message}`);
|
|
1844
1957
|
}
|
|
1845
|
-
|
|
1958
|
+
error2(
|
|
1846
1959
|
"Failed to clone build configuration",
|
|
1847
|
-
|
|
1960
|
+
error3 instanceof Error ? error3 : new Error(String(error3))
|
|
1848
1961
|
);
|
|
1849
|
-
throw
|
|
1962
|
+
throw error3;
|
|
1850
1963
|
}
|
|
1851
1964
|
}
|
|
1852
1965
|
/**
|
|
@@ -1928,10 +2041,10 @@ var BuildConfigurationCloneManager = class {
|
|
|
1928
2041
|
// src/teamcity/build-configuration-update-manager.ts
|
|
1929
2042
|
var ARTIFACT_RULES_SETTINGS_FIELD = "settings/artifactRules";
|
|
1930
2043
|
var ARTIFACT_RULES_LEGACY_FIELD = "artifactRules";
|
|
1931
|
-
var isArtifactRulesRetryableError = (
|
|
1932
|
-
if (
|
|
1933
|
-
if (!("response" in
|
|
1934
|
-
const response =
|
|
2044
|
+
var isArtifactRulesRetryableError = (error3) => {
|
|
2045
|
+
if (error3 == null || typeof error3 !== "object") return false;
|
|
2046
|
+
if (!("response" in error3)) return false;
|
|
2047
|
+
const response = error3.response;
|
|
1935
2048
|
const status = response?.status;
|
|
1936
2049
|
return status === 400 || status === 404;
|
|
1937
2050
|
};
|
|
@@ -1943,14 +2056,14 @@ var setArtifactRulesWithFallback = async (api, buildTypeId, artifactRules) => {
|
|
|
1943
2056
|
throw err;
|
|
1944
2057
|
}
|
|
1945
2058
|
const status = err.response?.status;
|
|
1946
|
-
|
|
2059
|
+
debug2("Retrying artifact rules update via legacy field", {
|
|
1947
2060
|
buildTypeId,
|
|
1948
2061
|
status
|
|
1949
2062
|
});
|
|
1950
2063
|
try {
|
|
1951
2064
|
await api.setBuildTypeField(buildTypeId, ARTIFACT_RULES_LEGACY_FIELD, artifactRules);
|
|
1952
2065
|
} catch (fallbackError) {
|
|
1953
|
-
|
|
2066
|
+
debug2("Legacy artifact rules update failed", {
|
|
1954
2067
|
buildTypeId,
|
|
1955
2068
|
status: fallbackError.response?.status
|
|
1956
2069
|
});
|
|
@@ -2018,7 +2131,7 @@ var BuildConfigurationUpdateManager = class {
|
|
|
2018
2131
|
};
|
|
2019
2132
|
} catch (err) {
|
|
2020
2133
|
if (err != null && typeof err === "object" && "response" in err && err.response?.status === 404) {
|
|
2021
|
-
|
|
2134
|
+
debug2("Build configuration not found", { configId });
|
|
2022
2135
|
return null;
|
|
2023
2136
|
}
|
|
2024
2137
|
if (err != null && typeof err === "object" && "response" in err && err.response?.status === 403) {
|
|
@@ -2031,7 +2144,7 @@ var BuildConfigurationUpdateManager = class {
|
|
|
2031
2144
|
* Validate updates before applying
|
|
2032
2145
|
*/
|
|
2033
2146
|
async validateUpdates(currentConfig, updates) {
|
|
2034
|
-
|
|
2147
|
+
debug2("Validating updates", {
|
|
2035
2148
|
configId: currentConfig.id,
|
|
2036
2149
|
updateFields: Object.keys(updates)
|
|
2037
2150
|
});
|
|
@@ -2080,7 +2193,7 @@ var BuildConfigurationUpdateManager = class {
|
|
|
2080
2193
|
* Apply updates to configuration
|
|
2081
2194
|
*/
|
|
2082
2195
|
async applyUpdates(currentConfig, updates) {
|
|
2083
|
-
|
|
2196
|
+
info2("Applying updates to build configuration", {
|
|
2084
2197
|
id: currentConfig.id,
|
|
2085
2198
|
updateCount: Object.keys(updates).length
|
|
2086
2199
|
});
|
|
@@ -2146,7 +2259,7 @@ var BuildConfigurationUpdateManager = class {
|
|
|
2146
2259
|
};
|
|
2147
2260
|
}
|
|
2148
2261
|
if (updates.agentRequirements) {
|
|
2149
|
-
|
|
2262
|
+
debug2("Agent requirements update requested", updates.agentRequirements);
|
|
2150
2263
|
}
|
|
2151
2264
|
try {
|
|
2152
2265
|
if (updates.name !== void 0 || updates.description !== void 0) {
|
|
@@ -2190,7 +2303,7 @@ var BuildConfigurationUpdateManager = class {
|
|
|
2190
2303
|
currentConfig.id
|
|
2191
2304
|
);
|
|
2192
2305
|
} catch (err) {
|
|
2193
|
-
|
|
2306
|
+
debug2(`Failed to remove parameter ${paramName}`, err);
|
|
2194
2307
|
}
|
|
2195
2308
|
}
|
|
2196
2309
|
}
|
|
@@ -2207,24 +2320,24 @@ var BuildConfigurationUpdateManager = class {
|
|
|
2207
2320
|
if (!updatedConfig) {
|
|
2208
2321
|
throw new Error("Failed to retrieve updated configuration");
|
|
2209
2322
|
}
|
|
2210
|
-
|
|
2323
|
+
info2("Configuration updated successfully", {
|
|
2211
2324
|
id: updatedConfig.id,
|
|
2212
2325
|
name: updatedConfig.name
|
|
2213
2326
|
});
|
|
2214
2327
|
return updatedConfig;
|
|
2215
2328
|
} catch (err) {
|
|
2216
|
-
const
|
|
2217
|
-
if (
|
|
2329
|
+
const error3 = err;
|
|
2330
|
+
if (error3.response?.status === 409) {
|
|
2218
2331
|
throw new Error("Configuration was modified by another user");
|
|
2219
2332
|
}
|
|
2220
|
-
if (
|
|
2333
|
+
if (error3.response?.status === 403) {
|
|
2221
2334
|
throw new Error("Permission denied: You need project edit permissions");
|
|
2222
2335
|
}
|
|
2223
|
-
if (
|
|
2224
|
-
const message =
|
|
2336
|
+
if (error3.response?.status === 400) {
|
|
2337
|
+
const message = error3.response?.data?.message ?? "Invalid configuration";
|
|
2225
2338
|
throw new Error(`Invalid update: ${message}`);
|
|
2226
2339
|
}
|
|
2227
|
-
|
|
2340
|
+
error2("Failed to apply updates", error3);
|
|
2228
2341
|
throw new Error("Partial update failure");
|
|
2229
2342
|
}
|
|
2230
2343
|
}
|
|
@@ -2317,7 +2430,7 @@ var BuildConfigurationUpdateManager = class {
|
|
|
2317
2430
|
*/
|
|
2318
2431
|
async rollbackChanges(configId, originalConfig) {
|
|
2319
2432
|
try {
|
|
2320
|
-
|
|
2433
|
+
info2("Rolling back configuration changes", { configId });
|
|
2321
2434
|
await this.applyUpdates(originalConfig, {
|
|
2322
2435
|
name: originalConfig.name,
|
|
2323
2436
|
description: originalConfig.description,
|
|
@@ -2325,9 +2438,9 @@ var BuildConfigurationUpdateManager = class {
|
|
|
2325
2438
|
artifactRules: originalConfig.artifactRules,
|
|
2326
2439
|
parameters: originalConfig.parameters
|
|
2327
2440
|
});
|
|
2328
|
-
|
|
2441
|
+
info2("Rollback completed successfully", { configId });
|
|
2329
2442
|
} catch (err) {
|
|
2330
|
-
|
|
2443
|
+
error2("Failed to rollback changes", err);
|
|
2331
2444
|
throw new Error("Rollback failed: Manual intervention may be required");
|
|
2332
2445
|
}
|
|
2333
2446
|
}
|
|
@@ -2667,11 +2780,11 @@ var BuildDependencyManager = class {
|
|
|
2667
2780
|
JSON_GET_HEADERS2
|
|
2668
2781
|
);
|
|
2669
2782
|
return response.data;
|
|
2670
|
-
} catch (
|
|
2671
|
-
if (this.isNotFound(
|
|
2783
|
+
} catch (error3) {
|
|
2784
|
+
if (this.isNotFound(error3)) {
|
|
2672
2785
|
return null;
|
|
2673
2786
|
}
|
|
2674
|
-
throw
|
|
2787
|
+
throw error3;
|
|
2675
2788
|
}
|
|
2676
2789
|
}
|
|
2677
2790
|
buildPayload(dependencyType, existing, input) {
|
|
@@ -2740,9 +2853,9 @@ var BuildDependencyManager = class {
|
|
|
2740
2853
|
}
|
|
2741
2854
|
return payload;
|
|
2742
2855
|
}
|
|
2743
|
-
isNotFound(
|
|
2856
|
+
isNotFound(error3) {
|
|
2744
2857
|
return Boolean(
|
|
2745
|
-
typeof
|
|
2858
|
+
typeof error3 === "object" && error3 !== null && "response" in error3 && error3.response?.status === 404
|
|
2746
2859
|
);
|
|
2747
2860
|
}
|
|
2748
2861
|
};
|
|
@@ -2860,11 +2973,11 @@ var BuildFeatureManager = class {
|
|
|
2860
2973
|
JSON_GET_HEADERS3
|
|
2861
2974
|
);
|
|
2862
2975
|
return response.data;
|
|
2863
|
-
} catch (
|
|
2864
|
-
if (typeof
|
|
2976
|
+
} catch (error3) {
|
|
2977
|
+
if (typeof error3 === "object" && error3 !== null && "response" in error3 && error3.response?.status === 404) {
|
|
2865
2978
|
return null;
|
|
2866
2979
|
}
|
|
2867
|
-
throw
|
|
2980
|
+
throw error3;
|
|
2868
2981
|
}
|
|
2869
2982
|
}
|
|
2870
2983
|
buildPayload(existing, input) {
|
|
@@ -2961,28 +3074,28 @@ var BuildResultsManager = class _BuildResultsManager {
|
|
|
2961
3074
|
this.cacheResult(cacheKey, result);
|
|
2962
3075
|
}
|
|
2963
3076
|
return result;
|
|
2964
|
-
} catch (
|
|
2965
|
-
if (
|
|
2966
|
-
if (
|
|
2967
|
-
throw new TeamCityNotFoundError("Build", buildId,
|
|
3077
|
+
} catch (error3) {
|
|
3078
|
+
if (error3 instanceof TeamCityAPIError) {
|
|
3079
|
+
if (error3.statusCode === 404) {
|
|
3080
|
+
throw new TeamCityNotFoundError("Build", buildId, error3.requestId, error3);
|
|
2968
3081
|
}
|
|
2969
|
-
throw
|
|
3082
|
+
throw error3;
|
|
2970
3083
|
}
|
|
2971
|
-
if (this.isAxiosNotFound(
|
|
2972
|
-
const axiosError =
|
|
3084
|
+
if (this.isAxiosNotFound(error3)) {
|
|
3085
|
+
const axiosError = error3;
|
|
2973
3086
|
const apiError = TeamCityAPIError.fromAxiosError(axiosError);
|
|
2974
3087
|
if (apiError.statusCode === 404) {
|
|
2975
3088
|
throw new TeamCityNotFoundError("Build", buildId, apiError.requestId, apiError);
|
|
2976
3089
|
}
|
|
2977
3090
|
throw apiError;
|
|
2978
3091
|
}
|
|
2979
|
-
const message =
|
|
3092
|
+
const message = error3 instanceof Error ? error3.message : String(error3);
|
|
2980
3093
|
if (/not found/i.test(message)) {
|
|
2981
3094
|
throw new TeamCityNotFoundError(
|
|
2982
3095
|
"Build",
|
|
2983
3096
|
buildId,
|
|
2984
3097
|
void 0,
|
|
2985
|
-
|
|
3098
|
+
error3 instanceof Error ? error3 : void 0
|
|
2986
3099
|
);
|
|
2987
3100
|
}
|
|
2988
3101
|
throw new TeamCityAPIError(
|
|
@@ -2991,7 +3104,7 @@ var BuildResultsManager = class _BuildResultsManager {
|
|
|
2991
3104
|
void 0,
|
|
2992
3105
|
void 0,
|
|
2993
3106
|
void 0,
|
|
2994
|
-
|
|
3107
|
+
error3 instanceof Error ? error3 : void 0
|
|
2995
3108
|
);
|
|
2996
3109
|
}
|
|
2997
3110
|
}
|
|
@@ -3190,9 +3303,9 @@ var BuildResultsManager = class _BuildResultsManager {
|
|
|
3190
3303
|
})
|
|
3191
3304
|
);
|
|
3192
3305
|
return result;
|
|
3193
|
-
} catch (
|
|
3194
|
-
|
|
3195
|
-
error:
|
|
3306
|
+
} catch (error3) {
|
|
3307
|
+
warn2("Failed to fetch artifacts", {
|
|
3308
|
+
error: error3 instanceof Error ? error3.message : error3,
|
|
3196
3309
|
buildId,
|
|
3197
3310
|
expected: "file[]"
|
|
3198
3311
|
});
|
|
@@ -3378,9 +3491,9 @@ var BuildResultsManager = class _BuildResultsManager {
|
|
|
3378
3491
|
}
|
|
3379
3492
|
}
|
|
3380
3493
|
return stats;
|
|
3381
|
-
} catch (
|
|
3382
|
-
|
|
3383
|
-
error:
|
|
3494
|
+
} catch (error3) {
|
|
3495
|
+
warn2("Failed to fetch statistics", {
|
|
3496
|
+
error: error3 instanceof Error ? error3.message : error3,
|
|
3384
3497
|
buildId,
|
|
3385
3498
|
expected: "property[]"
|
|
3386
3499
|
});
|
|
@@ -3405,9 +3518,9 @@ var BuildResultsManager = class _BuildResultsManager {
|
|
|
3405
3518
|
changeType: file.changeType ?? "edited"
|
|
3406
3519
|
}))
|
|
3407
3520
|
}));
|
|
3408
|
-
} catch (
|
|
3409
|
-
|
|
3410
|
-
error:
|
|
3521
|
+
} catch (error3) {
|
|
3522
|
+
warn2("Failed to fetch changes", {
|
|
3523
|
+
error: error3 instanceof Error ? error3.message : error3,
|
|
3411
3524
|
buildId,
|
|
3412
3525
|
expected: "change[]"
|
|
3413
3526
|
});
|
|
@@ -3431,9 +3544,9 @@ var BuildResultsManager = class _BuildResultsManager {
|
|
|
3431
3544
|
buildTypeId: build.buildTypeId,
|
|
3432
3545
|
status: build.status
|
|
3433
3546
|
}));
|
|
3434
|
-
} catch (
|
|
3435
|
-
|
|
3436
|
-
error:
|
|
3547
|
+
} catch (error3) {
|
|
3548
|
+
warn2("Failed to fetch dependencies", {
|
|
3549
|
+
error: error3 instanceof Error ? error3.message : error3,
|
|
3437
3550
|
buildId,
|
|
3438
3551
|
expected: "build[]"
|
|
3439
3552
|
});
|
|
@@ -3504,8 +3617,8 @@ var BuildResultsManager = class _BuildResultsManager {
|
|
|
3504
3617
|
getCacheKey(buildId, options) {
|
|
3505
3618
|
return `${buildId}:${JSON.stringify(options)}`;
|
|
3506
3619
|
}
|
|
3507
|
-
isAxiosNotFound(
|
|
3508
|
-
const axiosError =
|
|
3620
|
+
isAxiosNotFound(error3) {
|
|
3621
|
+
const axiosError = error3;
|
|
3509
3622
|
return Boolean(axiosError?.response && axiosError.response.status === 404);
|
|
3510
3623
|
}
|
|
3511
3624
|
/**
|
|
@@ -3626,7 +3739,7 @@ function createAdapterFromTeamCityAPI(api, options = {}) {
|
|
|
3626
3739
|
}
|
|
3627
3740
|
};
|
|
3628
3741
|
if (fallbackBaseUrl === FALLBACK_BASE_URL && resolvedApiConfig.baseUrl === FALLBACK_BASE_URL) {
|
|
3629
|
-
|
|
3742
|
+
warn2("TeamCity adapter using fallback baseUrl placeholder", {
|
|
3630
3743
|
reason: "missing_base_url",
|
|
3631
3744
|
hasApiConfig: Boolean(options.apiConfig)
|
|
3632
3745
|
});
|
|
@@ -3778,7 +3891,7 @@ async function fetchAllPages(fetchFn, options = {}) {
|
|
|
3778
3891
|
let currentPage = 0;
|
|
3779
3892
|
const pageSize = options.pageSize ?? 100;
|
|
3780
3893
|
const maxPages = options.maxPages;
|
|
3781
|
-
|
|
3894
|
+
info2("Starting paginated fetch", { pageSize, maxPages });
|
|
3782
3895
|
while (hasMore && (!maxPages || currentPage < maxPages)) {
|
|
3783
3896
|
const start = currentPage * pageSize;
|
|
3784
3897
|
const response = await fetchFn({
|
|
@@ -3791,13 +3904,13 @@ async function fetchAllPages(fetchFn, options = {}) {
|
|
|
3791
3904
|
if (response.items.length < pageSize) {
|
|
3792
3905
|
hasMore = false;
|
|
3793
3906
|
}
|
|
3794
|
-
|
|
3907
|
+
info2(`Fetched page ${currentPage}`, {
|
|
3795
3908
|
itemsInPage: response.items.length,
|
|
3796
3909
|
totalItems: allItems.length,
|
|
3797
3910
|
hasMore
|
|
3798
3911
|
});
|
|
3799
3912
|
}
|
|
3800
|
-
|
|
3913
|
+
info2("Paginated fetch complete", {
|
|
3801
3914
|
totalPages: currentPage,
|
|
3802
3915
|
totalItems: allItems.length
|
|
3803
3916
|
});
|
|
@@ -3941,7 +4054,7 @@ var MCPRateLimitError = class extends MCPToolError {
|
|
|
3941
4054
|
};
|
|
3942
4055
|
function formatError(err, context) {
|
|
3943
4056
|
if (err instanceof MCPToolError) {
|
|
3944
|
-
|
|
4057
|
+
error2("MCP Tool Error", err, {
|
|
3945
4058
|
code: err.code,
|
|
3946
4059
|
statusCode: err.statusCode,
|
|
3947
4060
|
data: err.data,
|
|
@@ -3957,7 +4070,7 @@ function formatError(err, context) {
|
|
|
3957
4070
|
};
|
|
3958
4071
|
}
|
|
3959
4072
|
if (err instanceof import_zod2.z.ZodError) {
|
|
3960
|
-
|
|
4073
|
+
error2("Validation Error", err, {
|
|
3961
4074
|
errors: err.issues,
|
|
3962
4075
|
...context
|
|
3963
4076
|
});
|
|
@@ -3971,7 +4084,7 @@ function formatError(err, context) {
|
|
|
3971
4084
|
};
|
|
3972
4085
|
}
|
|
3973
4086
|
if (err instanceof Error) {
|
|
3974
|
-
|
|
4087
|
+
error2("Internal Error", err, context);
|
|
3975
4088
|
return {
|
|
3976
4089
|
success: false,
|
|
3977
4090
|
error: {
|
|
@@ -3980,7 +4093,7 @@ function formatError(err, context) {
|
|
|
3980
4093
|
}
|
|
3981
4094
|
};
|
|
3982
4095
|
}
|
|
3983
|
-
|
|
4096
|
+
error2("Unknown Error", new Error(String(err)), context);
|
|
3984
4097
|
return {
|
|
3985
4098
|
success: false,
|
|
3986
4099
|
error: {
|
|
@@ -4004,37 +4117,37 @@ var ErrorLogger = class _ErrorLogger {
|
|
|
4004
4117
|
/**
|
|
4005
4118
|
* Log error with structured context
|
|
4006
4119
|
*/
|
|
4007
|
-
logError(message,
|
|
4120
|
+
logError(message, error3, context) {
|
|
4008
4121
|
const loggedError = {
|
|
4009
4122
|
message,
|
|
4010
4123
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4011
4124
|
context
|
|
4012
4125
|
};
|
|
4013
|
-
if (
|
|
4014
|
-
loggedError.stack =
|
|
4015
|
-
if (
|
|
4016
|
-
loggedError.code =
|
|
4126
|
+
if (error3 instanceof Error) {
|
|
4127
|
+
loggedError.stack = error3.stack;
|
|
4128
|
+
if (error3 instanceof MCPToolError) {
|
|
4129
|
+
loggedError.code = error3.code;
|
|
4017
4130
|
loggedError.context = {
|
|
4018
4131
|
...context,
|
|
4019
|
-
statusCode:
|
|
4020
|
-
errorData:
|
|
4132
|
+
statusCode: error3.statusCode,
|
|
4133
|
+
errorData: error3.data
|
|
4021
4134
|
};
|
|
4022
4135
|
}
|
|
4023
4136
|
}
|
|
4024
|
-
|
|
4137
|
+
error2(message, error3 instanceof Error ? error3 : void 0, context);
|
|
4025
4138
|
return loggedError;
|
|
4026
4139
|
}
|
|
4027
4140
|
/**
|
|
4028
4141
|
* Log warning with context
|
|
4029
4142
|
*/
|
|
4030
4143
|
logWarning(message, context) {
|
|
4031
|
-
|
|
4144
|
+
warn2(message, context);
|
|
4032
4145
|
}
|
|
4033
4146
|
/**
|
|
4034
4147
|
* Log info with context
|
|
4035
4148
|
*/
|
|
4036
4149
|
logInfo(message, context) {
|
|
4037
|
-
|
|
4150
|
+
info2(message, context);
|
|
4038
4151
|
}
|
|
4039
4152
|
/**
|
|
4040
4153
|
* Create error logger for a specific component
|
|
@@ -4048,8 +4161,8 @@ var ComponentErrorLogger = class {
|
|
|
4048
4161
|
this.componentName = componentName;
|
|
4049
4162
|
this.errorLogger = errorLogger2;
|
|
4050
4163
|
}
|
|
4051
|
-
logError(message,
|
|
4052
|
-
return this.errorLogger.logError(message,
|
|
4164
|
+
logError(message, error3, context) {
|
|
4165
|
+
return this.errorLogger.logError(message, error3, {
|
|
4053
4166
|
...context,
|
|
4054
4167
|
component: this.componentName
|
|
4055
4168
|
});
|
|
@@ -4089,13 +4202,13 @@ var GlobalErrorHandler = class _GlobalErrorHandler {
|
|
|
4089
4202
|
/**
|
|
4090
4203
|
* Handle error from MCP tool execution
|
|
4091
4204
|
*/
|
|
4092
|
-
handleToolError(
|
|
4205
|
+
handleToolError(error3, toolName, context) {
|
|
4093
4206
|
const enhancedContext = {
|
|
4094
4207
|
...context,
|
|
4095
4208
|
operation: toolName,
|
|
4096
4209
|
component: "MCP_TOOL"
|
|
4097
4210
|
};
|
|
4098
|
-
const transformedError = this.transformError(
|
|
4211
|
+
const transformedError = this.transformError(error3, enhancedContext);
|
|
4099
4212
|
if (this.options.logErrors) {
|
|
4100
4213
|
errorLogger.logError(
|
|
4101
4214
|
`Error in tool '${toolName}'`,
|
|
@@ -4108,13 +4221,13 @@ var GlobalErrorHandler = class _GlobalErrorHandler {
|
|
|
4108
4221
|
/**
|
|
4109
4222
|
* Handle async operation errors
|
|
4110
4223
|
*/
|
|
4111
|
-
handleAsyncError(
|
|
4224
|
+
handleAsyncError(error3, operationName, context) {
|
|
4112
4225
|
const enhancedContext = {
|
|
4113
4226
|
...context,
|
|
4114
4227
|
operation: operationName,
|
|
4115
4228
|
component: "ASYNC_HANDLER"
|
|
4116
4229
|
};
|
|
4117
|
-
const transformedError = this.transformError(
|
|
4230
|
+
const transformedError = this.transformError(error3, enhancedContext);
|
|
4118
4231
|
if (this.options.logErrors) {
|
|
4119
4232
|
errorLogger.logError(
|
|
4120
4233
|
`Async error in '${operationName}'`,
|
|
@@ -4127,28 +4240,28 @@ var GlobalErrorHandler = class _GlobalErrorHandler {
|
|
|
4127
4240
|
/**
|
|
4128
4241
|
* Transform raw errors into structured MCP errors
|
|
4129
4242
|
*/
|
|
4130
|
-
transformError(
|
|
4131
|
-
if (
|
|
4243
|
+
transformError(error3, context) {
|
|
4244
|
+
if (error3 instanceof TeamCityAPIError) {
|
|
4132
4245
|
return new MCPTeamCityError(
|
|
4133
|
-
this.sanitizeErrorMessage(
|
|
4134
|
-
|
|
4135
|
-
|
|
4246
|
+
this.sanitizeErrorMessage(error3.message),
|
|
4247
|
+
error3.statusCode ?? 500,
|
|
4248
|
+
error3.code,
|
|
4136
4249
|
context.requestId
|
|
4137
4250
|
);
|
|
4138
4251
|
}
|
|
4139
|
-
if (
|
|
4252
|
+
if (error3 instanceof MCPToolError) {
|
|
4140
4253
|
if (this.options.sanitizeErrors) {
|
|
4141
|
-
const sanitizedMessage = this.sanitizeErrorMessage(
|
|
4142
|
-
return new MCPToolError(sanitizedMessage,
|
|
4254
|
+
const sanitizedMessage = this.sanitizeErrorMessage(error3.message);
|
|
4255
|
+
return new MCPToolError(sanitizedMessage, error3.code, error3.statusCode, error3.data);
|
|
4143
4256
|
}
|
|
4144
|
-
return
|
|
4257
|
+
return error3;
|
|
4145
4258
|
}
|
|
4146
|
-
if (
|
|
4147
|
-
return this.transformAxiosError(
|
|
4259
|
+
if (error3 instanceof import_axios3.AxiosError) {
|
|
4260
|
+
return this.transformAxiosError(error3, context);
|
|
4148
4261
|
}
|
|
4149
|
-
if (
|
|
4150
|
-
const sanitizedMessage = this.sanitizeErrorMessage(
|
|
4151
|
-
if (sanitizedMessage.includes("timeout") ||
|
|
4262
|
+
if (error3 instanceof Error) {
|
|
4263
|
+
const sanitizedMessage = this.sanitizeErrorMessage(error3.message);
|
|
4264
|
+
if (sanitizedMessage.includes("timeout") || error3.name === "TimeoutError") {
|
|
4152
4265
|
return new MCPTimeoutError(context.operation ?? "unknown", 3e4);
|
|
4153
4266
|
}
|
|
4154
4267
|
if (sanitizedMessage.includes("rate limit") || sanitizedMessage.includes("429")) {
|
|
@@ -4156,7 +4269,7 @@ var GlobalErrorHandler = class _GlobalErrorHandler {
|
|
|
4156
4269
|
}
|
|
4157
4270
|
return new Error(sanitizedMessage);
|
|
4158
4271
|
}
|
|
4159
|
-
return new Error(this.sanitizeErrorMessage(String(
|
|
4272
|
+
return new Error(this.sanitizeErrorMessage(String(error3)));
|
|
4160
4273
|
}
|
|
4161
4274
|
/**
|
|
4162
4275
|
* Transform Axios errors into MCPTeamCityError
|
|
@@ -4193,15 +4306,15 @@ var GlobalErrorHandler = class _GlobalErrorHandler {
|
|
|
4193
4306
|
/**
|
|
4194
4307
|
* Check if error should be retried
|
|
4195
4308
|
*/
|
|
4196
|
-
isRetryableError(
|
|
4197
|
-
if (
|
|
4198
|
-
return
|
|
4309
|
+
isRetryableError(error3) {
|
|
4310
|
+
if (error3 instanceof MCPTeamCityError) {
|
|
4311
|
+
return error3.statusCode >= 500 && error3.statusCode < 600;
|
|
4199
4312
|
}
|
|
4200
|
-
if (
|
|
4313
|
+
if (error3 instanceof MCPTimeoutError) {
|
|
4201
4314
|
return true;
|
|
4202
4315
|
}
|
|
4203
|
-
if (
|
|
4204
|
-
return !
|
|
4316
|
+
if (error3 instanceof import_axios3.AxiosError) {
|
|
4317
|
+
return !error3.response || error3.response.status >= 500 && error3.response.status < 600;
|
|
4205
4318
|
}
|
|
4206
4319
|
return false;
|
|
4207
4320
|
}
|
|
@@ -4263,41 +4376,41 @@ var import_axios35 = __toESM(require("axios"));
|
|
|
4263
4376
|
// node_modules/axios-retry/dist/esm/index.js
|
|
4264
4377
|
var import_is_retry_allowed = __toESM(require_is_retry_allowed(), 1);
|
|
4265
4378
|
var namespace = "axios-retry";
|
|
4266
|
-
function isNetworkError(
|
|
4379
|
+
function isNetworkError(error3) {
|
|
4267
4380
|
const CODE_EXCLUDE_LIST = ["ERR_CANCELED", "ECONNABORTED"];
|
|
4268
|
-
if (
|
|
4381
|
+
if (error3.response) {
|
|
4269
4382
|
return false;
|
|
4270
4383
|
}
|
|
4271
|
-
if (!
|
|
4384
|
+
if (!error3.code) {
|
|
4272
4385
|
return false;
|
|
4273
4386
|
}
|
|
4274
|
-
if (CODE_EXCLUDE_LIST.includes(
|
|
4387
|
+
if (CODE_EXCLUDE_LIST.includes(error3.code)) {
|
|
4275
4388
|
return false;
|
|
4276
4389
|
}
|
|
4277
|
-
return (0, import_is_retry_allowed.default)(
|
|
4390
|
+
return (0, import_is_retry_allowed.default)(error3);
|
|
4278
4391
|
}
|
|
4279
4392
|
var SAFE_HTTP_METHODS = ["get", "head", "options"];
|
|
4280
4393
|
var IDEMPOTENT_HTTP_METHODS = SAFE_HTTP_METHODS.concat(["put", "delete"]);
|
|
4281
|
-
function isRetryableError2(
|
|
4282
|
-
return
|
|
4394
|
+
function isRetryableError2(error3) {
|
|
4395
|
+
return error3.code !== "ECONNABORTED" && (!error3.response || error3.response.status === 429 || error3.response.status >= 500 && error3.response.status <= 599);
|
|
4283
4396
|
}
|
|
4284
|
-
function isSafeRequestError(
|
|
4285
|
-
if (!
|
|
4397
|
+
function isSafeRequestError(error3) {
|
|
4398
|
+
if (!error3.config?.method) {
|
|
4286
4399
|
return false;
|
|
4287
4400
|
}
|
|
4288
|
-
return isRetryableError2(
|
|
4401
|
+
return isRetryableError2(error3) && SAFE_HTTP_METHODS.indexOf(error3.config.method) !== -1;
|
|
4289
4402
|
}
|
|
4290
|
-
function isIdempotentRequestError(
|
|
4291
|
-
if (!
|
|
4403
|
+
function isIdempotentRequestError(error3) {
|
|
4404
|
+
if (!error3.config?.method) {
|
|
4292
4405
|
return false;
|
|
4293
4406
|
}
|
|
4294
|
-
return isRetryableError2(
|
|
4407
|
+
return isRetryableError2(error3) && IDEMPOTENT_HTTP_METHODS.indexOf(error3.config.method) !== -1;
|
|
4295
4408
|
}
|
|
4296
|
-
function isNetworkOrIdempotentRequestError(
|
|
4297
|
-
return isNetworkError(
|
|
4409
|
+
function isNetworkOrIdempotentRequestError(error3) {
|
|
4410
|
+
return isNetworkError(error3) || isIdempotentRequestError(error3);
|
|
4298
4411
|
}
|
|
4299
|
-
function retryAfter(
|
|
4300
|
-
const retryAfterHeader =
|
|
4412
|
+
function retryAfter(error3 = void 0) {
|
|
4413
|
+
const retryAfterHeader = error3?.response?.headers["retry-after"];
|
|
4301
4414
|
if (!retryAfterHeader) {
|
|
4302
4415
|
return 0;
|
|
4303
4416
|
}
|
|
@@ -4307,19 +4420,19 @@ function retryAfter(error2 = void 0) {
|
|
|
4307
4420
|
}
|
|
4308
4421
|
return Math.max(0, retryAfterMs);
|
|
4309
4422
|
}
|
|
4310
|
-
function noDelay(_retryNumber = 0,
|
|
4311
|
-
return Math.max(0, retryAfter(
|
|
4423
|
+
function noDelay(_retryNumber = 0, error3 = void 0) {
|
|
4424
|
+
return Math.max(0, retryAfter(error3));
|
|
4312
4425
|
}
|
|
4313
|
-
function exponentialDelay(retryNumber = 0,
|
|
4426
|
+
function exponentialDelay(retryNumber = 0, error3 = void 0, delayFactor = 100) {
|
|
4314
4427
|
const calculatedDelay = 2 ** retryNumber * delayFactor;
|
|
4315
|
-
const delay = Math.max(calculatedDelay, retryAfter(
|
|
4428
|
+
const delay = Math.max(calculatedDelay, retryAfter(error3));
|
|
4316
4429
|
const randomSum = delay * 0.2 * Math.random();
|
|
4317
4430
|
return delay + randomSum;
|
|
4318
4431
|
}
|
|
4319
4432
|
function linearDelay(delayFactor = 100) {
|
|
4320
|
-
return (retryNumber = 0,
|
|
4433
|
+
return (retryNumber = 0, error3 = void 0) => {
|
|
4321
4434
|
const delay = retryNumber * delayFactor;
|
|
4322
|
-
return Math.max(delay, retryAfter(
|
|
4435
|
+
return Math.max(delay, retryAfter(error3));
|
|
4323
4436
|
};
|
|
4324
4437
|
}
|
|
4325
4438
|
var DEFAULT_OPTIONS = {
|
|
@@ -4356,9 +4469,9 @@ function fixConfig(axiosInstance, config2) {
|
|
|
4356
4469
|
delete config2.httpsAgent;
|
|
4357
4470
|
}
|
|
4358
4471
|
}
|
|
4359
|
-
async function shouldRetry(currentState,
|
|
4472
|
+
async function shouldRetry(currentState, error3) {
|
|
4360
4473
|
const { retries, retryCondition } = currentState;
|
|
4361
|
-
const shouldRetryOrPromise = (currentState.retryCount || 0) < retries && retryCondition(
|
|
4474
|
+
const shouldRetryOrPromise = (currentState.retryCount || 0) < retries && retryCondition(error3);
|
|
4362
4475
|
if (typeof shouldRetryOrPromise === "object") {
|
|
4363
4476
|
try {
|
|
4364
4477
|
const shouldRetryPromiseResult = await shouldRetryOrPromise;
|
|
@@ -4369,21 +4482,21 @@ async function shouldRetry(currentState, error2) {
|
|
|
4369
4482
|
}
|
|
4370
4483
|
return shouldRetryOrPromise;
|
|
4371
4484
|
}
|
|
4372
|
-
async function handleRetry(axiosInstance, currentState,
|
|
4485
|
+
async function handleRetry(axiosInstance, currentState, error3, config2) {
|
|
4373
4486
|
currentState.retryCount += 1;
|
|
4374
4487
|
const { retryDelay, shouldResetTimeout, onRetry } = currentState;
|
|
4375
|
-
const delay = retryDelay(currentState.retryCount,
|
|
4488
|
+
const delay = retryDelay(currentState.retryCount, error3);
|
|
4376
4489
|
fixConfig(axiosInstance, config2);
|
|
4377
4490
|
if (!shouldResetTimeout && config2.timeout && currentState.lastRequestTime) {
|
|
4378
4491
|
const lastRequestDuration = Date.now() - currentState.lastRequestTime;
|
|
4379
4492
|
const timeout = config2.timeout - lastRequestDuration - delay;
|
|
4380
4493
|
if (timeout <= 0) {
|
|
4381
|
-
return Promise.reject(
|
|
4494
|
+
return Promise.reject(error3);
|
|
4382
4495
|
}
|
|
4383
4496
|
config2.timeout = timeout;
|
|
4384
4497
|
}
|
|
4385
4498
|
config2.transformRequest = [(data) => data];
|
|
4386
|
-
await onRetry(currentState.retryCount,
|
|
4499
|
+
await onRetry(currentState.retryCount, error3, config2);
|
|
4387
4500
|
if (config2.signal?.aborted) {
|
|
4388
4501
|
return Promise.resolve(axiosInstance(config2));
|
|
4389
4502
|
}
|
|
@@ -4403,9 +4516,9 @@ async function handleRetry(axiosInstance, currentState, error2, config2) {
|
|
|
4403
4516
|
}
|
|
4404
4517
|
});
|
|
4405
4518
|
}
|
|
4406
|
-
async function handleMaxRetryTimesExceeded(currentState,
|
|
4519
|
+
async function handleMaxRetryTimesExceeded(currentState, error3) {
|
|
4407
4520
|
if (currentState.retryCount >= currentState.retries)
|
|
4408
|
-
await currentState.onMaxRetryTimesExceeded(
|
|
4521
|
+
await currentState.onMaxRetryTimesExceeded(error3, currentState.retryCount);
|
|
4409
4522
|
}
|
|
4410
4523
|
var axiosRetry = (axiosInstance, defaultOptions) => {
|
|
4411
4524
|
const requestInterceptorId = axiosInstance.interceptors.request.use((config2) => {
|
|
@@ -4415,20 +4528,20 @@ var axiosRetry = (axiosInstance, defaultOptions) => {
|
|
|
4415
4528
|
}
|
|
4416
4529
|
return config2;
|
|
4417
4530
|
});
|
|
4418
|
-
const responseInterceptorId = axiosInstance.interceptors.response.use(null, async (
|
|
4419
|
-
const { config: config2 } =
|
|
4531
|
+
const responseInterceptorId = axiosInstance.interceptors.response.use(null, async (error3) => {
|
|
4532
|
+
const { config: config2 } = error3;
|
|
4420
4533
|
if (!config2) {
|
|
4421
|
-
return Promise.reject(
|
|
4534
|
+
return Promise.reject(error3);
|
|
4422
4535
|
}
|
|
4423
4536
|
const currentState = setCurrentState(config2, defaultOptions);
|
|
4424
|
-
if (
|
|
4425
|
-
return
|
|
4537
|
+
if (error3.response && currentState.validateResponse?.(error3.response)) {
|
|
4538
|
+
return error3.response;
|
|
4426
4539
|
}
|
|
4427
|
-
if (await shouldRetry(currentState,
|
|
4428
|
-
return handleRetry(axiosInstance, currentState,
|
|
4540
|
+
if (await shouldRetry(currentState, error3)) {
|
|
4541
|
+
return handleRetry(axiosInstance, currentState, error3, config2);
|
|
4429
4542
|
}
|
|
4430
|
-
await handleMaxRetryTimesExceeded(currentState,
|
|
4431
|
-
return Promise.reject(
|
|
4543
|
+
await handleMaxRetryTimesExceeded(currentState, error3);
|
|
4544
|
+
return Promise.reject(error3);
|
|
4432
4545
|
});
|
|
4433
4546
|
return { requestInterceptorId, responseInterceptorId };
|
|
4434
4547
|
};
|
|
@@ -4462,7 +4575,7 @@ function addRequestId(config2) {
|
|
|
4462
4575
|
if (metaContainer) {
|
|
4463
4576
|
metaContainer._tcMeta = { start: Date.now() };
|
|
4464
4577
|
}
|
|
4465
|
-
|
|
4578
|
+
info2("Starting TeamCity API request", {
|
|
4466
4579
|
requestId,
|
|
4467
4580
|
method: config2.method?.toUpperCase(),
|
|
4468
4581
|
url: config2.url,
|
|
@@ -4479,7 +4592,7 @@ function logResponse(response) {
|
|
|
4479
4592
|
const headers = response.headers;
|
|
4480
4593
|
const headerDuration = headers?.["x-response-time"] ?? headers?.["x-response-duration"];
|
|
4481
4594
|
const duration = headerDuration ?? (meta?.start ? Date.now() - meta.start : void 0);
|
|
4482
|
-
|
|
4595
|
+
info2("TeamCity API request completed", {
|
|
4483
4596
|
requestId,
|
|
4484
4597
|
method: response.config.method?.toUpperCase(),
|
|
4485
4598
|
url: response.config.url,
|
|
@@ -4488,10 +4601,10 @@ function logResponse(response) {
|
|
|
4488
4601
|
});
|
|
4489
4602
|
return response;
|
|
4490
4603
|
}
|
|
4491
|
-
function logAndTransformError(
|
|
4492
|
-
const requestId =
|
|
4493
|
-
const tcError = TeamCityAPIError.fromAxiosError(
|
|
4494
|
-
const meta = asTimingMetaContainer(
|
|
4604
|
+
function logAndTransformError(error3) {
|
|
4605
|
+
const requestId = error3.config?.requestId;
|
|
4606
|
+
const tcError = TeamCityAPIError.fromAxiosError(error3, requestId);
|
|
4607
|
+
const meta = asTimingMetaContainer(error3.config)?._tcMeta;
|
|
4495
4608
|
const duration = meta?.start ? Date.now() - meta.start : void 0;
|
|
4496
4609
|
const sanitize = (val) => {
|
|
4497
4610
|
const redact = (s) => s.replace(/(token[=:\s]*)[^\s&]+/gi, "$1***").replace(/(password[=:\s]*)[^\s&]+/gi, "$1***").replace(/(apikey[=:\s]*)[^\s&]+/gi, "$1***").replace(/(authorization[=:\s:]*)[^\s&]+/gi, "$1***");
|
|
@@ -4503,7 +4616,7 @@ function logAndTransformError(error2) {
|
|
|
4503
4616
|
return val;
|
|
4504
4617
|
}
|
|
4505
4618
|
};
|
|
4506
|
-
|
|
4619
|
+
error2("TeamCity API request failed", void 0, {
|
|
4507
4620
|
requestId: tcError.requestId,
|
|
4508
4621
|
code: tcError.code,
|
|
4509
4622
|
message: sanitize(tcError.message),
|
|
@@ -38084,15 +38197,15 @@ var TeamCityAPI = class _TeamCityAPI {
|
|
|
38084
38197
|
this.http = this.axiosInstance;
|
|
38085
38198
|
esm_default(this.axiosInstance, {
|
|
38086
38199
|
retries: 3,
|
|
38087
|
-
retryDelay: (retryCount,
|
|
38088
|
-
const reqId =
|
|
38089
|
-
const tcError = TeamCityAPIError.fromAxiosError(
|
|
38200
|
+
retryDelay: (retryCount, error3) => {
|
|
38201
|
+
const reqId = error3?.config?.requestId;
|
|
38202
|
+
const tcError = TeamCityAPIError.fromAxiosError(error3, reqId);
|
|
38090
38203
|
const retryAfter2 = extractRetryAfterMilliseconds(tcError);
|
|
38091
38204
|
return retryAfter2 ?? Math.min(1e3 * Math.pow(2, Math.max(0, retryCount - 1)), 8e3);
|
|
38092
38205
|
},
|
|
38093
|
-
retryCondition: (
|
|
38094
|
-
const reqId =
|
|
38095
|
-
const tcError = TeamCityAPIError.fromAxiosError(
|
|
38206
|
+
retryCondition: (error3) => {
|
|
38207
|
+
const reqId = error3?.config?.requestId;
|
|
38208
|
+
const tcError = TeamCityAPIError.fromAxiosError(error3, reqId);
|
|
38096
38209
|
return isRetryableError(tcError);
|
|
38097
38210
|
}
|
|
38098
38211
|
});
|
|
@@ -38171,7 +38284,7 @@ var TeamCityAPI = class _TeamCityAPI {
|
|
|
38171
38284
|
vcsRootInstances: this.vcsRootInstances,
|
|
38172
38285
|
versionedSettings: this.versionedSettings
|
|
38173
38286
|
});
|
|
38174
|
-
|
|
38287
|
+
info2("TeamCityAPI initialized", { baseUrl: basePath, timeout });
|
|
38175
38288
|
}
|
|
38176
38289
|
static getInstance(arg1, arg2) {
|
|
38177
38290
|
const requestedConfig = this.normalizeArgs(arg1, arg2);
|
|
@@ -38450,12 +38563,12 @@ var ensureUniquePath = async (candidate) => {
|
|
|
38450
38563
|
const handle = await import_node_fs2.promises.open(next, "wx");
|
|
38451
38564
|
await handle.close();
|
|
38452
38565
|
return next;
|
|
38453
|
-
} catch (
|
|
38454
|
-
const err =
|
|
38566
|
+
} catch (error3) {
|
|
38567
|
+
const err = error3;
|
|
38455
38568
|
if (err?.code === "EEXIST") {
|
|
38456
38569
|
return probe(attempt + 1);
|
|
38457
38570
|
}
|
|
38458
|
-
throw
|
|
38571
|
+
throw error3;
|
|
38459
38572
|
}
|
|
38460
38573
|
};
|
|
38461
38574
|
return probe(0);
|
|
@@ -38539,10 +38652,10 @@ var toNormalizedArtifactRequests = (inputs, defaultBuildId) => inputs.map((entry
|
|
|
38539
38652
|
downloadUrl: entry.downloadUrl?.trim()
|
|
38540
38653
|
};
|
|
38541
38654
|
});
|
|
38542
|
-
var getErrorMessage = (
|
|
38543
|
-
if ((0, import_axios36.isAxiosError)(
|
|
38544
|
-
const status =
|
|
38545
|
-
const data =
|
|
38655
|
+
var getErrorMessage = (error3) => {
|
|
38656
|
+
if ((0, import_axios36.isAxiosError)(error3)) {
|
|
38657
|
+
const status = error3.response?.status;
|
|
38658
|
+
const data = error3.response?.data;
|
|
38546
38659
|
let detail;
|
|
38547
38660
|
if (typeof data === "string") {
|
|
38548
38661
|
detail = data;
|
|
@@ -38555,13 +38668,13 @@ var getErrorMessage = (error2) => {
|
|
|
38555
38668
|
}
|
|
38556
38669
|
return `HTTP ${status ?? "unknown"}${detail ? `: ${detail}` : ""}`;
|
|
38557
38670
|
}
|
|
38558
|
-
if (
|
|
38559
|
-
return
|
|
38671
|
+
if (error3 instanceof Error) {
|
|
38672
|
+
return error3.message;
|
|
38560
38673
|
}
|
|
38561
|
-
if (typeof
|
|
38562
|
-
return String(
|
|
38674
|
+
if (typeof error3 === "object" && error3 !== null && "message" in error3) {
|
|
38675
|
+
return String(error3.message);
|
|
38563
38676
|
}
|
|
38564
|
-
return String(
|
|
38677
|
+
return String(error3 ?? "Unknown error");
|
|
38565
38678
|
};
|
|
38566
38679
|
var downloadArtifactByUrl = async (adapter, request, encoding, options) => {
|
|
38567
38680
|
const axios3 = adapter.getAxios();
|
|
@@ -38929,7 +39042,7 @@ var DEV_TOOLS = [
|
|
|
38929
39042
|
if (propertiesPayload) {
|
|
38930
39043
|
buildRequest.properties = propertiesPayload;
|
|
38931
39044
|
}
|
|
38932
|
-
const sendXmlFallback = async (
|
|
39045
|
+
const sendXmlFallback = async (error3) => {
|
|
38933
39046
|
const escapeXml2 = (value) => value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
38934
39047
|
const branchPart = branchName ? `<branchName>${escapeXml2(branchName)}</branchName>` : "";
|
|
38935
39048
|
const commentPart = commentText ? `<comment><text>${escapeXml2(commentText)}</text></comment>` : "";
|
|
@@ -38951,7 +39064,7 @@ var DEV_TOOLS = [
|
|
|
38951
39064
|
state: build.state ?? void 0,
|
|
38952
39065
|
status: build.status ?? void 0,
|
|
38953
39066
|
branchName: build.branchName ?? branchName,
|
|
38954
|
-
fallback: { mode: "xml", reason:
|
|
39067
|
+
fallback: { mode: "xml", reason: error3?.message }
|
|
38955
39068
|
});
|
|
38956
39069
|
};
|
|
38957
39070
|
try {
|
|
@@ -38971,8 +39084,8 @@ var DEV_TOOLS = [
|
|
|
38971
39084
|
status: build.status ?? void 0,
|
|
38972
39085
|
branchName: build.branchName ?? branchName
|
|
38973
39086
|
});
|
|
38974
|
-
} catch (
|
|
38975
|
-
return sendXmlFallback(
|
|
39087
|
+
} catch (error3) {
|
|
39088
|
+
return sendXmlFallback(error3);
|
|
38976
39089
|
}
|
|
38977
39090
|
},
|
|
38978
39091
|
args
|
|
@@ -39217,15 +39330,15 @@ var DEV_TOOLS = [
|
|
|
39217
39330
|
if (!effectiveBuildId) {
|
|
39218
39331
|
throw new Error("Failed to resolve buildId from inputs");
|
|
39219
39332
|
}
|
|
39220
|
-
const shouldRetry2 = (
|
|
39221
|
-
if (
|
|
39222
|
-
if (
|
|
39333
|
+
const shouldRetry2 = (error3) => {
|
|
39334
|
+
if (error3 instanceof TeamCityAPIError) {
|
|
39335
|
+
if (error3.code === "HTTP_404") {
|
|
39223
39336
|
return true;
|
|
39224
39337
|
}
|
|
39225
|
-
return isRetryableError(
|
|
39338
|
+
return isRetryableError(error3);
|
|
39226
39339
|
}
|
|
39227
|
-
if ((0, import_axios36.isAxiosError)(
|
|
39228
|
-
const status =
|
|
39340
|
+
if ((0, import_axios36.isAxiosError)(error3)) {
|
|
39341
|
+
const status = error3.response?.status;
|
|
39229
39342
|
if (status === 404) {
|
|
39230
39343
|
return true;
|
|
39231
39344
|
}
|
|
@@ -39238,17 +39351,17 @@ var DEV_TOOLS = [
|
|
|
39238
39351
|
}
|
|
39239
39352
|
return false;
|
|
39240
39353
|
};
|
|
39241
|
-
const normalizeError = (
|
|
39242
|
-
if ((0, import_axios36.isAxiosError)(
|
|
39243
|
-
const status =
|
|
39244
|
-
const statusText = (
|
|
39245
|
-
const base = status ? `${status}${statusText ? ` ${statusText}` : ""}` :
|
|
39354
|
+
const normalizeError = (error3) => {
|
|
39355
|
+
if ((0, import_axios36.isAxiosError)(error3)) {
|
|
39356
|
+
const status = error3.response?.status;
|
|
39357
|
+
const statusText = (error3.response?.statusText ?? "").trim();
|
|
39358
|
+
const base = status ? `${status}${statusText ? ` ${statusText}` : ""}` : error3.message;
|
|
39246
39359
|
return new Error(base || "Request failed");
|
|
39247
39360
|
}
|
|
39248
|
-
if (
|
|
39249
|
-
return
|
|
39361
|
+
if (error3 instanceof Error) {
|
|
39362
|
+
return error3;
|
|
39250
39363
|
}
|
|
39251
|
-
return new Error(String(
|
|
39364
|
+
return new Error(String(error3));
|
|
39252
39365
|
};
|
|
39253
39366
|
const wait = (ms) => new Promise((resolve2) => {
|
|
39254
39367
|
setTimeout(resolve2, ms);
|
|
@@ -39341,12 +39454,12 @@ var DEV_TOOLS = [
|
|
|
39341
39454
|
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
39342
39455
|
try {
|
|
39343
39456
|
return await (isStream ? attemptStream() : attemptBuffered());
|
|
39344
|
-
} catch (
|
|
39345
|
-
if (shouldRetry2(
|
|
39457
|
+
} catch (error3) {
|
|
39458
|
+
if (shouldRetry2(error3) && attempt < maxAttempts - 1) {
|
|
39346
39459
|
await wait(500 * (attempt + 1));
|
|
39347
39460
|
continue;
|
|
39348
39461
|
}
|
|
39349
|
-
throw normalizeError(
|
|
39462
|
+
throw normalizeError(error3);
|
|
39350
39463
|
}
|
|
39351
39464
|
}
|
|
39352
39465
|
throw new Error("Unable to fetch build log after retries");
|
|
@@ -39838,8 +39951,8 @@ var DEV_TOOLS = [
|
|
|
39838
39951
|
null,
|
|
39839
39952
|
async () => {
|
|
39840
39953
|
const adapter = createAdapterFromTeamCityAPI(TeamCityAPI.getInstance());
|
|
39841
|
-
const
|
|
39842
|
-
return json(
|
|
39954
|
+
const info3 = await adapter.modules.server.getServerInfo();
|
|
39955
|
+
return json(info3.data);
|
|
39843
39956
|
},
|
|
39844
39957
|
{}
|
|
39845
39958
|
);
|
|
@@ -40375,11 +40488,11 @@ var DEV_TOOLS = [
|
|
|
40375
40488
|
artifactEncoding: typed.artifactEncoding ?? "base64"
|
|
40376
40489
|
});
|
|
40377
40490
|
return json(result);
|
|
40378
|
-
} catch (
|
|
40379
|
-
if (
|
|
40380
|
-
throw new TeamCityNotFoundError("Build", friendlyIdentifier,
|
|
40491
|
+
} catch (error3) {
|
|
40492
|
+
if (error3 instanceof TeamCityNotFoundError) {
|
|
40493
|
+
throw new TeamCityNotFoundError("Build", friendlyIdentifier, error3.requestId, error3);
|
|
40381
40494
|
}
|
|
40382
|
-
throw
|
|
40495
|
+
throw error3;
|
|
40383
40496
|
}
|
|
40384
40497
|
},
|
|
40385
40498
|
args
|
|
@@ -40425,7 +40538,7 @@ var DEV_TOOLS = [
|
|
|
40425
40538
|
async (typed) => {
|
|
40426
40539
|
const encoding = typed.encoding ?? "base64";
|
|
40427
40540
|
const adapter = createAdapterFromTeamCityAPI(TeamCityAPI.getInstance());
|
|
40428
|
-
|
|
40541
|
+
debug2("tools.download_build_artifact.start", {
|
|
40429
40542
|
buildId: typed.buildId,
|
|
40430
40543
|
encoding,
|
|
40431
40544
|
artifactPath: typed.artifactPath,
|
|
@@ -40546,49 +40659,49 @@ var DEV_TOOLS = [
|
|
|
40546
40659
|
});
|
|
40547
40660
|
}
|
|
40548
40661
|
results.push({ ...payload, success: true });
|
|
40549
|
-
|
|
40662
|
+
debug2("tools.download_build_artifacts.success", {
|
|
40550
40663
|
path: request.path,
|
|
40551
40664
|
encoding: payload.encoding,
|
|
40552
40665
|
outputPath: payload.encoding === "stream" ? payload.outputPath : void 0
|
|
40553
40666
|
});
|
|
40554
40667
|
if (payload.encoding === "stream") {
|
|
40555
40668
|
const streamPayload = payload;
|
|
40556
|
-
|
|
40669
|
+
debug2("tools.download_build_artifacts.stream", {
|
|
40557
40670
|
path: request.path,
|
|
40558
40671
|
outputPath: streamPayload.outputPath,
|
|
40559
40672
|
bytesWritten: streamPayload.bytesWritten
|
|
40560
40673
|
});
|
|
40561
40674
|
} else {
|
|
40562
|
-
|
|
40675
|
+
debug2("tools.download_build_artifacts.buffered", {
|
|
40563
40676
|
path: request.path,
|
|
40564
40677
|
encoding: payload.encoding,
|
|
40565
40678
|
size: payload.size
|
|
40566
40679
|
});
|
|
40567
40680
|
}
|
|
40568
|
-
} catch (
|
|
40681
|
+
} catch (error3) {
|
|
40569
40682
|
results.push({
|
|
40570
40683
|
name: request.path,
|
|
40571
40684
|
path: request.path,
|
|
40572
40685
|
size: 0,
|
|
40573
40686
|
encoding,
|
|
40574
40687
|
success: false,
|
|
40575
|
-
error: getErrorMessage(
|
|
40688
|
+
error: getErrorMessage(error3)
|
|
40576
40689
|
});
|
|
40577
|
-
|
|
40690
|
+
debug2("tools.download_build_artifacts.failure", {
|
|
40578
40691
|
path: request.path,
|
|
40579
40692
|
encoding,
|
|
40580
|
-
error: getErrorMessage(
|
|
40693
|
+
error: getErrorMessage(error3),
|
|
40581
40694
|
downloadUrl: request.downloadUrl,
|
|
40582
40695
|
buildId: request.buildId
|
|
40583
40696
|
});
|
|
40584
40697
|
}
|
|
40585
40698
|
}
|
|
40586
|
-
|
|
40699
|
+
debug2("tools.download_build_artifacts.complete", {
|
|
40587
40700
|
buildId: typed.buildId,
|
|
40588
40701
|
successCount: results.filter((item) => item.success).length,
|
|
40589
40702
|
failureCount: results.filter((item) => !item.success).length
|
|
40590
40703
|
});
|
|
40591
|
-
|
|
40704
|
+
debug2("tools.download_build_artifacts.complete", {
|
|
40592
40705
|
buildId: typed.buildId,
|
|
40593
40706
|
successCount: results.filter((item) => item.success).length,
|
|
40594
40707
|
failureCount: results.filter((item) => !item.success).length
|
|
@@ -41254,12 +41367,12 @@ var DEV_TOOLS = [
|
|
|
41254
41367
|
const maybeChildren = project.projects?.project ?? [];
|
|
41255
41368
|
if (Array.isArray(maybeChildren)) {
|
|
41256
41369
|
for (const childRaw of maybeChildren) {
|
|
41257
|
-
const
|
|
41258
|
-
if (typeof
|
|
41259
|
-
const sub = await buildHierarchy(
|
|
41260
|
-
children.push({ id: sub.id ??
|
|
41261
|
-
} else if (typeof
|
|
41262
|
-
children.push({ id:
|
|
41370
|
+
const child2 = childRaw;
|
|
41371
|
+
if (typeof child2.id === "string" && depth < 3) {
|
|
41372
|
+
const sub = await buildHierarchy(child2.id, depth + 1);
|
|
41373
|
+
children.push({ id: sub.id ?? child2.id, name: sub.name });
|
|
41374
|
+
} else if (typeof child2.id === "string") {
|
|
41375
|
+
children.push({ id: child2.id, name: child2.name });
|
|
41263
41376
|
}
|
|
41264
41377
|
}
|
|
41265
41378
|
}
|
|
@@ -41364,7 +41477,7 @@ var FULL_MODE_TOOLS = [
|
|
|
41364
41477
|
schema,
|
|
41365
41478
|
async (typedArgs) => {
|
|
41366
41479
|
const adapter = createAdapterFromTeamCityAPI(TeamCityAPI.getInstance());
|
|
41367
|
-
|
|
41480
|
+
debug2("update_project_settings invoked", {
|
|
41368
41481
|
projectId: typedArgs.projectId,
|
|
41369
41482
|
// Only log which fields are present to reduce noise
|
|
41370
41483
|
requestedChanges: {
|
|
@@ -41374,7 +41487,7 @@ var FULL_MODE_TOOLS = [
|
|
|
41374
41487
|
}
|
|
41375
41488
|
});
|
|
41376
41489
|
if (typedArgs.name) {
|
|
41377
|
-
|
|
41490
|
+
debug2("Setting project field", {
|
|
41378
41491
|
projectId: typedArgs.projectId,
|
|
41379
41492
|
field: "name",
|
|
41380
41493
|
valuePreview: typedArgs.name
|
|
@@ -41386,7 +41499,7 @@ var FULL_MODE_TOOLS = [
|
|
|
41386
41499
|
);
|
|
41387
41500
|
}
|
|
41388
41501
|
if (typedArgs.description !== void 0) {
|
|
41389
|
-
|
|
41502
|
+
debug2("Setting project field", {
|
|
41390
41503
|
projectId: typedArgs.projectId,
|
|
41391
41504
|
field: "description",
|
|
41392
41505
|
valuePreview: typedArgs.description
|
|
@@ -41398,7 +41511,7 @@ var FULL_MODE_TOOLS = [
|
|
|
41398
41511
|
);
|
|
41399
41512
|
}
|
|
41400
41513
|
if (typedArgs.archived !== void 0) {
|
|
41401
|
-
|
|
41514
|
+
debug2("Setting project field", {
|
|
41402
41515
|
projectId: typedArgs.projectId,
|
|
41403
41516
|
field: "archived",
|
|
41404
41517
|
valuePreview: String(typedArgs.archived)
|
|
@@ -41409,7 +41522,7 @@ var FULL_MODE_TOOLS = [
|
|
|
41409
41522
|
String(typedArgs.archived)
|
|
41410
41523
|
);
|
|
41411
41524
|
}
|
|
41412
|
-
|
|
41525
|
+
debug2("Project settings updated", {
|
|
41413
41526
|
projectId: typedArgs.projectId,
|
|
41414
41527
|
appliedChanges: {
|
|
41415
41528
|
name: typedArgs.name ?? null,
|
|
@@ -41539,11 +41652,11 @@ var FULL_MODE_TOOLS = [
|
|
|
41539
41652
|
url: cloned.url,
|
|
41540
41653
|
description: cloned.description
|
|
41541
41654
|
});
|
|
41542
|
-
} catch (
|
|
41655
|
+
} catch (error3) {
|
|
41543
41656
|
return json({
|
|
41544
41657
|
success: false,
|
|
41545
41658
|
action: "clone_build_config",
|
|
41546
|
-
error:
|
|
41659
|
+
error: error3 instanceof Error ? error3.message : "Failed to clone build configuration."
|
|
41547
41660
|
});
|
|
41548
41661
|
}
|
|
41549
41662
|
},
|
|
@@ -43079,7 +43192,7 @@ function createSimpleServer() {
|
|
|
43079
43192
|
const server = new import_server.Server(
|
|
43080
43193
|
{
|
|
43081
43194
|
name: "teamcity-mcp",
|
|
43082
|
-
version:
|
|
43195
|
+
version: package_default.version
|
|
43083
43196
|
},
|
|
43084
43197
|
{
|
|
43085
43198
|
capabilities: {
|
|
@@ -43091,7 +43204,7 @@ function createSimpleServer() {
|
|
|
43091
43204
|
);
|
|
43092
43205
|
server.setRequestHandler(import_types.ListToolsRequestSchema, async () => {
|
|
43093
43206
|
const currentTools = getAvailableTools();
|
|
43094
|
-
|
|
43207
|
+
info2("MCP request: tools/list", { mode: getMCPMode2(), count: currentTools.length });
|
|
43095
43208
|
const response = {
|
|
43096
43209
|
tools: currentTools.map((tool) => ({
|
|
43097
43210
|
name: tool.name,
|
|
@@ -43099,17 +43212,17 @@ function createSimpleServer() {
|
|
|
43099
43212
|
inputSchema: tool.inputSchema
|
|
43100
43213
|
}))
|
|
43101
43214
|
};
|
|
43102
|
-
|
|
43215
|
+
debug2("MCP response: tools/list", { count: response.tools.length, success: true });
|
|
43103
43216
|
return response;
|
|
43104
43217
|
});
|
|
43105
43218
|
server.setRequestHandler(import_types.CallToolRequestSchema, async (request) => {
|
|
43106
43219
|
const { name, arguments: args } = request.params;
|
|
43107
43220
|
const started = Date.now();
|
|
43108
|
-
|
|
43221
|
+
info2("MCP request: tools/call", { tool: name, args });
|
|
43109
43222
|
const tool = getTool(name);
|
|
43110
43223
|
if (!tool) {
|
|
43111
43224
|
const availableTools = getAvailableTools();
|
|
43112
|
-
|
|
43225
|
+
error2("MCP error: unknown tool", void 0, {
|
|
43113
43226
|
tool: name,
|
|
43114
43227
|
available: availableTools.map((t) => t.name),
|
|
43115
43228
|
mode: getMCPMode2()
|
|
@@ -43128,28 +43241,28 @@ function createSimpleServer() {
|
|
|
43128
43241
|
};
|
|
43129
43242
|
const duration = Date.now() - started;
|
|
43130
43243
|
const success = result?.success !== false;
|
|
43131
|
-
|
|
43244
|
+
debug2("MCP response: tools/call", {
|
|
43132
43245
|
tool: name,
|
|
43133
43246
|
success,
|
|
43134
43247
|
duration,
|
|
43135
43248
|
contentTypes: response.content?.map((c) => c.type)
|
|
43136
43249
|
});
|
|
43137
43250
|
return response;
|
|
43138
|
-
} catch (
|
|
43139
|
-
if (
|
|
43251
|
+
} catch (error3) {
|
|
43252
|
+
if (error3 instanceof import_types.McpError) {
|
|
43140
43253
|
const duration2 = Date.now() - started;
|
|
43141
|
-
|
|
43142
|
-
throw
|
|
43254
|
+
error2("MCP error: tool call", error3, { tool: name, success: false, duration: duration2 });
|
|
43255
|
+
throw error3;
|
|
43143
43256
|
}
|
|
43144
43257
|
const duration = Date.now() - started;
|
|
43145
|
-
|
|
43258
|
+
error2("MCP error: tool call (unexpected)", error3, {
|
|
43146
43259
|
tool: name,
|
|
43147
43260
|
success: false,
|
|
43148
43261
|
duration
|
|
43149
43262
|
});
|
|
43150
43263
|
throw new import_types.McpError(
|
|
43151
43264
|
import_types.ErrorCode.InternalError,
|
|
43152
|
-
`Tool execution failed: ${
|
|
43265
|
+
`Tool execution failed: ${error3 instanceof Error ? error3.message : String(error3)}`
|
|
43153
43266
|
);
|
|
43154
43267
|
}
|
|
43155
43268
|
});
|
|
@@ -43157,7 +43270,7 @@ function createSimpleServer() {
|
|
|
43157
43270
|
}
|
|
43158
43271
|
|
|
43159
43272
|
// src/index.ts
|
|
43160
|
-
dotenv2.config();
|
|
43273
|
+
dotenv2.config({ quiet: true });
|
|
43161
43274
|
var activeServer = null;
|
|
43162
43275
|
var lifecyclePromise = null;
|
|
43163
43276
|
var shuttingDown = false;
|
|
@@ -43176,9 +43289,9 @@ async function shutdown(exitCode) {
|
|
|
43176
43289
|
const lifecycleToAwait = lifecyclePromise;
|
|
43177
43290
|
await serverToClose?.close();
|
|
43178
43291
|
await lifecycleToAwait;
|
|
43179
|
-
} catch (
|
|
43292
|
+
} catch (error3) {
|
|
43180
43293
|
process.stderr.write(
|
|
43181
|
-
`Error while closing server: ${
|
|
43294
|
+
`Error while closing server: ${error3 instanceof Error ? error3.message : String(error3)}
|
|
43182
43295
|
`
|
|
43183
43296
|
);
|
|
43184
43297
|
} finally {
|
|
@@ -43212,9 +43325,9 @@ async function main() {
|
|
|
43212
43325
|
await lifecycle;
|
|
43213
43326
|
clearServerState();
|
|
43214
43327
|
process.stderr.write("TeamCity MCP Server connection closed\n");
|
|
43215
|
-
} catch (
|
|
43328
|
+
} catch (error3) {
|
|
43216
43329
|
clearServerState();
|
|
43217
|
-
process.stderr.write(`Failed to start server: ${
|
|
43330
|
+
process.stderr.write(`Failed to start server: ${error3}
|
|
43218
43331
|
`);
|
|
43219
43332
|
process.exit(1);
|
|
43220
43333
|
}
|
|
@@ -43225,8 +43338,8 @@ process.on("SIGINT", () => {
|
|
|
43225
43338
|
process.on("SIGTERM", () => {
|
|
43226
43339
|
void shutdown(0);
|
|
43227
43340
|
});
|
|
43228
|
-
main().catch((
|
|
43229
|
-
process.stderr.write(`Unhandled error: ${
|
|
43341
|
+
main().catch((error3) => {
|
|
43342
|
+
process.stderr.write(`Unhandled error: ${error3}
|
|
43230
43343
|
`);
|
|
43231
43344
|
process.exit(1);
|
|
43232
43345
|
});
|