@daghis/teamcity-mcp 0.1.2 → 0.2.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/.commitlintrc.js +21 -0
- package/.commitlintrc.mjs +25 -0
- package/.github/dependabot.yml +38 -0
- package/.github/workflows/ci.yml +26 -22
- package/.github/workflows/codeql.yml +1 -1
- package/.github/workflows/commitlint.yml +3 -3
- package/.github/workflows/publish.yml +2 -2
- package/AGENTS.md +61 -0
- package/CHANGELOG.md +7 -0
- package/README.md +8 -0
- package/THIRD_PARTY_NOTICES.md +58 -0
- package/dist/index.js +303 -232
- package/dist/index.js.map +4 -4
- package/dist/src/teamcity-client/api/agent-api.d.ts +15 -15
- package/dist/src/teamcity-client/api/agent-pool-api.d.ts +14 -14
- package/dist/src/teamcity-client/api/agent-type-api.d.ts +1 -1
- package/dist/src/teamcity-client/api/audit-api.d.ts +2 -2
- package/dist/src/teamcity-client/api/avatar-api.d.ts +4 -4
- package/dist/src/teamcity-client/api/build-api.d.ts +57 -57
- package/dist/src/teamcity-client/api/build-queue-api.d.ts +14 -14
- package/dist/src/teamcity-client/api/build-type-api.d.ts +109 -109
- package/dist/src/teamcity-client/api/change-api.d.ts +10 -10
- package/dist/src/teamcity-client/api/cloud-instance-api.d.ts +10 -10
- package/dist/src/teamcity-client/api/deployment-dashboard-api.d.ts +9 -9
- package/dist/src/teamcity-client/api/global-server-settings-api.d.ts +2 -2
- package/dist/src/teamcity-client/api/group-api.d.ts +16 -16
- package/dist/src/teamcity-client/api/health-api.d.ts +4 -4
- package/dist/src/teamcity-client/api/investigation-api.d.ts +6 -6
- package/dist/src/teamcity-client/api/mute-api.d.ts +6 -6
- package/dist/src/teamcity-client/api/node-api.d.ts +6 -6
- package/dist/src/teamcity-client/api/problem-api.d.ts +2 -2
- package/dist/src/teamcity-client/api/problem-occurrence-api.d.ts +2 -2
- package/dist/src/teamcity-client/api/project-api.d.ts +48 -48
- package/dist/src/teamcity-client/api/role-api.d.ts +8 -8
- package/dist/src/teamcity-client/api/root-api.d.ts +4 -4
- package/dist/src/teamcity-client/api/server-api.d.ts +18 -18
- package/dist/src/teamcity-client/api/server-authentication-settings-api.d.ts +2 -2
- package/dist/src/teamcity-client/api/test-api.d.ts +2 -2
- package/dist/src/teamcity-client/api/test-occurrence-api.d.ts +2 -2
- package/dist/src/teamcity-client/api/user-api.d.ts +28 -28
- package/dist/src/teamcity-client/api/vcs-root-api.d.ts +14 -14
- package/dist/src/teamcity-client/api/vcs-root-instance-api.d.ts +17 -17
- package/dist/src/teamcity-client/api/versioned-settings-api.d.ts +15 -15
- package/package.json +14 -13
- package/scripts/build.cjs +25 -6
- package/scripts/generate-third-party-notices.cjs +71 -0
- package/src/teamcity/auth.ts +2 -2
- package/TODO.md +0 -80
|
@@ -70,19 +70,19 @@ export interface VcsRootApiInterface {
|
|
|
70
70
|
setVcsRootProperty(vcsRootLocator: string, name: string, body?: string, options?: RawAxiosRequestConfig): AxiosPromise<string>;
|
|
71
71
|
}
|
|
72
72
|
export declare class VcsRootApi extends BaseAPI implements VcsRootApiInterface {
|
|
73
|
-
addVcsRoot(fields?: string, body?: VcsRoot, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRoot, any>>;
|
|
74
|
-
deleteAllVcsRootProperties(vcsRootLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any>>;
|
|
75
|
-
deleteVcsRoot(vcsRootLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any>>;
|
|
76
|
-
deleteVcsRootProperty(vcsRootLocator: string, name: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any>>;
|
|
77
|
-
getAllVcsRootProperties(vcsRootLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Properties, any>>;
|
|
78
|
-
getAllVcsRoots(locator?: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRoots, any>>;
|
|
79
|
-
getRootEndpoints(vcsRootLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRoot, any>>;
|
|
80
|
-
getVcsRootField(vcsRootLocator: string, field: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any>>;
|
|
81
|
-
getVcsRootInstances(vcsRootLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRootInstances, any>>;
|
|
82
|
-
getVcsRootProperty(vcsRootLocator: string, name: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any>>;
|
|
83
|
-
getVcsRootSettingsFile(vcsRootLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any>>;
|
|
84
|
-
setVcsRootField(vcsRootLocator: string, field: string, body?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any>>;
|
|
85
|
-
setVcsRootProperties(vcsRootLocator: string, fields?: string, body?: Properties, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Properties, any>>;
|
|
86
|
-
setVcsRootProperty(vcsRootLocator: string, name: string, body?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any>>;
|
|
73
|
+
addVcsRoot(fields?: string, body?: VcsRoot, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRoot, any, {}>>;
|
|
74
|
+
deleteAllVcsRootProperties(vcsRootLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any, {}>>;
|
|
75
|
+
deleteVcsRoot(vcsRootLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any, {}>>;
|
|
76
|
+
deleteVcsRootProperty(vcsRootLocator: string, name: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any, {}>>;
|
|
77
|
+
getAllVcsRootProperties(vcsRootLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Properties, any, {}>>;
|
|
78
|
+
getAllVcsRoots(locator?: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRoots, any, {}>>;
|
|
79
|
+
getRootEndpoints(vcsRootLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRoot, any, {}>>;
|
|
80
|
+
getVcsRootField(vcsRootLocator: string, field: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any, {}>>;
|
|
81
|
+
getVcsRootInstances(vcsRootLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRootInstances, any, {}>>;
|
|
82
|
+
getVcsRootProperty(vcsRootLocator: string, name: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any, {}>>;
|
|
83
|
+
getVcsRootSettingsFile(vcsRootLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any, {}>>;
|
|
84
|
+
setVcsRootField(vcsRootLocator: string, field: string, body?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any, {}>>;
|
|
85
|
+
setVcsRootProperties(vcsRootLocator: string, fields?: string, body?: Properties, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Properties, any, {}>>;
|
|
86
|
+
setVcsRootProperty(vcsRootLocator: string, name: string, body?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any, {}>>;
|
|
87
87
|
}
|
|
88
88
|
//# sourceMappingURL=vcs-root-api.d.ts.map
|
|
@@ -83,22 +83,22 @@ export interface VcsRootInstanceApiInterface {
|
|
|
83
83
|
triggerCommitHookNotification(locator?: string, okOnNothingFound?: boolean, options?: RawAxiosRequestConfig): AxiosPromise<void>;
|
|
84
84
|
}
|
|
85
85
|
export declare class VcsRootInstanceApi extends BaseAPI implements VcsRootInstanceApiInterface {
|
|
86
|
-
deleteVcsRootInstanceField(vcsRootInstanceLocator: string, field: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any>>;
|
|
87
|
-
deleteVcsRootInstanceRepositoryState(vcsRootInstanceLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any>>;
|
|
88
|
-
downloadFile(path: string, vcsRootInstanceLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any>>;
|
|
89
|
-
getAllVcsRootInstances(locator?: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRootInstances, any>>;
|
|
90
|
-
getFileMetadata(path: string, vcsRootInstanceLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<any, any>>;
|
|
91
|
-
getFilesList(vcsRootInstanceLocator: string, basePath?: string, locator?: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Files, any>>;
|
|
92
|
-
getFilesListForSubpath(path: string, vcsRootInstanceLocator: string, basePath?: string, locator?: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Files, any>>;
|
|
93
|
-
getVcsRootInstance(vcsRootInstanceLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRootInstance, any>>;
|
|
94
|
-
getVcsRootInstanceCreationDate(vcsRootInstanceLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any>>;
|
|
95
|
-
getVcsRootInstanceField(vcsRootInstanceLocator: string, field: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any>>;
|
|
96
|
-
getVcsRootInstanceProperties(vcsRootInstanceLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Properties, any>>;
|
|
97
|
-
getVcsRootInstanceRepositoryState(vcsRootInstanceLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Entries, any>>;
|
|
98
|
-
getZippedFile(path: string, vcsRootInstanceLocator: string, basePath?: string, locator?: string, name?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any>>;
|
|
99
|
-
requestPendingChangesCheck(locator?: string, requestor?: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRootInstances, any>>;
|
|
100
|
-
setVcsRootInstanceField(vcsRootInstanceLocator: string, field: string, body?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any>>;
|
|
101
|
-
setVcsRootInstanceRepositoryState(vcsRootInstanceLocator: string, fields?: string, body?: Entries, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Entries, any>>;
|
|
102
|
-
triggerCommitHookNotification(locator?: string, okOnNothingFound?: boolean, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any>>;
|
|
86
|
+
deleteVcsRootInstanceField(vcsRootInstanceLocator: string, field: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any, {}>>;
|
|
87
|
+
deleteVcsRootInstanceRepositoryState(vcsRootInstanceLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any, {}>>;
|
|
88
|
+
downloadFile(path: string, vcsRootInstanceLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any, {}>>;
|
|
89
|
+
getAllVcsRootInstances(locator?: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRootInstances, any, {}>>;
|
|
90
|
+
getFileMetadata(path: string, vcsRootInstanceLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
91
|
+
getFilesList(vcsRootInstanceLocator: string, basePath?: string, locator?: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Files, any, {}>>;
|
|
92
|
+
getFilesListForSubpath(path: string, vcsRootInstanceLocator: string, basePath?: string, locator?: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Files, any, {}>>;
|
|
93
|
+
getVcsRootInstance(vcsRootInstanceLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRootInstance, any, {}>>;
|
|
94
|
+
getVcsRootInstanceCreationDate(vcsRootInstanceLocator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any, {}>>;
|
|
95
|
+
getVcsRootInstanceField(vcsRootInstanceLocator: string, field: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any, {}>>;
|
|
96
|
+
getVcsRootInstanceProperties(vcsRootInstanceLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Properties, any, {}>>;
|
|
97
|
+
getVcsRootInstanceRepositoryState(vcsRootInstanceLocator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Entries, any, {}>>;
|
|
98
|
+
getZippedFile(path: string, vcsRootInstanceLocator: string, basePath?: string, locator?: string, name?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any, {}>>;
|
|
99
|
+
requestPendingChangesCheck(locator?: string, requestor?: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VcsRootInstances, any, {}>>;
|
|
100
|
+
setVcsRootInstanceField(vcsRootInstanceLocator: string, field: string, body?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any, {}>>;
|
|
101
|
+
setVcsRootInstanceRepositoryState(vcsRootInstanceLocator: string, fields?: string, body?: Entries, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Entries, any, {}>>;
|
|
102
|
+
triggerCommitHookNotification(locator?: string, okOnNothingFound?: boolean, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any, {}>>;
|
|
103
103
|
}
|
|
104
104
|
//# sourceMappingURL=vcs-root-instance-api.d.ts.map
|
|
@@ -75,20 +75,20 @@ export interface VersionedSettingsApiInterface {
|
|
|
75
75
|
setVersionedSettingsContextParameters(locator: string, body?: VersionedSettingsContextParameters, options?: RawAxiosRequestConfig): AxiosPromise<VersionedSettingsContextParameters>;
|
|
76
76
|
}
|
|
77
77
|
export declare class VersionedSettingsApi extends BaseAPI implements VersionedSettingsApiInterface {
|
|
78
|
-
addVersionedSettingsTokens(locator: string, body?: VersionedSettingsTokens, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsTokens, any>>;
|
|
79
|
-
checkForVersionedSettingsChanges(locator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any>>;
|
|
80
|
-
commitCurrentSettings(locator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any>>;
|
|
81
|
-
deleteVersionedSettingsConfigParameter(locator: string, name: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any>>;
|
|
82
|
-
deleteVersionedSettingsTokens(locator: string, body?: VersionedSettingsTokens, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsTokens, any>>;
|
|
83
|
-
getVersionedSettingsConfig(locator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsConfig, any>>;
|
|
84
|
-
getVersionedSettingsConfigParameter(locator: string, name: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any>>;
|
|
85
|
-
getVersionedSettingsContextParameters(locator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsContextParameters, any>>;
|
|
86
|
-
getVersionedSettingsProjectsToLoad(locator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Projects, any>>;
|
|
87
|
-
getVersionedSettingsStatus(locator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsStatus, any>>;
|
|
88
|
-
getVersionedSettingsTokens(locator: string, status?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsTokens, any>>;
|
|
89
|
-
loadSettingsFromVCS(locator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Projects, any>>;
|
|
90
|
-
setVersionedSettingsConfig(locator: string, fields?: string, body?: VersionedSettingsConfig, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsConfig, any>>;
|
|
91
|
-
setVersionedSettingsConfigParameter(locator: string, name: string, body?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any>>;
|
|
92
|
-
setVersionedSettingsContextParameters(locator: string, body?: VersionedSettingsContextParameters, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsContextParameters, any>>;
|
|
78
|
+
addVersionedSettingsTokens(locator: string, body?: VersionedSettingsTokens, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsTokens, any, {}>>;
|
|
79
|
+
checkForVersionedSettingsChanges(locator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any, {}>>;
|
|
80
|
+
commitCurrentSettings(locator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any, {}>>;
|
|
81
|
+
deleteVersionedSettingsConfigParameter(locator: string, name: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<void, any, {}>>;
|
|
82
|
+
deleteVersionedSettingsTokens(locator: string, body?: VersionedSettingsTokens, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsTokens, any, {}>>;
|
|
83
|
+
getVersionedSettingsConfig(locator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsConfig, any, {}>>;
|
|
84
|
+
getVersionedSettingsConfigParameter(locator: string, name: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any, {}>>;
|
|
85
|
+
getVersionedSettingsContextParameters(locator: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsContextParameters, any, {}>>;
|
|
86
|
+
getVersionedSettingsProjectsToLoad(locator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Projects, any, {}>>;
|
|
87
|
+
getVersionedSettingsStatus(locator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsStatus, any, {}>>;
|
|
88
|
+
getVersionedSettingsTokens(locator: string, status?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsTokens, any, {}>>;
|
|
89
|
+
loadSettingsFromVCS(locator: string, fields?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<Projects, any, {}>>;
|
|
90
|
+
setVersionedSettingsConfig(locator: string, fields?: string, body?: VersionedSettingsConfig, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsConfig, any, {}>>;
|
|
91
|
+
setVersionedSettingsConfigParameter(locator: string, name: string, body?: string, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<string, any, {}>>;
|
|
92
|
+
setVersionedSettingsContextParameters(locator: string, body?: VersionedSettingsContextParameters, options?: RawAxiosRequestConfig): Promise<import("axios").AxiosResponse<VersionedSettingsContextParameters, any, {}>>;
|
|
93
93
|
}
|
|
94
94
|
//# sourceMappingURL=versioned-settings-api.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@daghis/teamcity-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Model Control Protocol server for TeamCity CI/CD integration with AI coding assistants",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"dev": "node ./node_modules/tsx/dist/cli.mjs watch src/index.ts",
|
|
12
12
|
"dev:interactive": "bash scripts/interact.sh",
|
|
13
13
|
"build": "node scripts/build.cjs",
|
|
14
|
+
"build:bundle": "CODECOV_BUNDLE=true npm run build",
|
|
14
15
|
"build:tsc": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
|
15
16
|
"start": "node dist/index.js",
|
|
16
17
|
"test": "jest",
|
|
@@ -34,7 +35,8 @@
|
|
|
34
35
|
"e2e": "node ./node_modules/tsx/dist/cli.mjs tests/e2e/index.ts",
|
|
35
36
|
"e2e:build": "npm run build && node dist/e2e/index.js",
|
|
36
37
|
"e2e:setup": "node ./node_modules/tsx/dist/cli.mjs tests/e2e/setup-playground.ts",
|
|
37
|
-
"e2e:cleanup": "node ./node_modules/tsx/dist/cli.mjs tests/e2e/cleanup.ts"
|
|
38
|
+
"e2e:cleanup": "node ./node_modules/tsx/dist/cli.mjs tests/e2e/cleanup.ts",
|
|
39
|
+
"generate:notices": "node scripts/generate-third-party-notices.cjs"
|
|
38
40
|
},
|
|
39
41
|
"keywords": [
|
|
40
42
|
"mcp",
|
|
@@ -54,41 +56,40 @@
|
|
|
54
56
|
"url": "https://github.com/Daghis/teamcity-mcp.git"
|
|
55
57
|
},
|
|
56
58
|
"dependencies": {
|
|
57
|
-
"@modelcontextprotocol/sdk": "^
|
|
59
|
+
"@modelcontextprotocol/sdk": "^1.18.0",
|
|
58
60
|
"ajv": "^8.17.1",
|
|
59
61
|
"ajv-formats": "^3.0.1",
|
|
60
62
|
"axios": "^1.11.0",
|
|
61
|
-
"dotenv": "^
|
|
62
|
-
"express": "^
|
|
63
|
+
"dotenv": "^17.2.2",
|
|
64
|
+
"express": "^5.1.0",
|
|
63
65
|
"inversify": "^7.9.1",
|
|
64
66
|
"morgan": "^1.10.0",
|
|
65
67
|
"reflect-metadata": "^0.2.2",
|
|
66
68
|
"tslib": "^2.8.1",
|
|
67
|
-
"uuid": "^11.1.0",
|
|
68
69
|
"winston": "^3.11.0",
|
|
69
70
|
"zod": "^3.22.4"
|
|
70
71
|
},
|
|
71
72
|
"devDependencies": {
|
|
73
|
+
"@codecov/bundler-plugin-core": "^1.9.1",
|
|
72
74
|
"@esbuild-plugins/tsconfig-paths": "^0.1.2",
|
|
73
75
|
"@openapitools/openapi-generator-cli": "^2.23.1",
|
|
74
76
|
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
|
75
|
-
"@types/ajv": "^
|
|
76
|
-
"@types/express": "^
|
|
77
|
-
"@types/jest": "^
|
|
77
|
+
"@types/ajv": "^1.0.4",
|
|
78
|
+
"@types/express": "^5.0.3",
|
|
79
|
+
"@types/jest": "^30.0.0",
|
|
78
80
|
"@types/js-yaml": "^4.0.9",
|
|
79
81
|
"@types/morgan": "^1.9.9",
|
|
80
|
-
"@types/node": "^
|
|
81
|
-
"@types/uuid": "^10.0.0",
|
|
82
|
+
"@types/node": "^24.3.1",
|
|
82
83
|
"@typescript-eslint/eslint-plugin": "^6.13.0",
|
|
83
84
|
"@typescript-eslint/parser": "^6.13.0",
|
|
84
85
|
"axios-retry": "^4.5.0",
|
|
85
86
|
"esbuild": "^0.25.9",
|
|
86
87
|
"eslint": "^8.54.0",
|
|
87
|
-
"eslint-config-prettier": "^
|
|
88
|
+
"eslint-config-prettier": "^10.1.8",
|
|
88
89
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
89
90
|
"eslint-plugin-import": "^2.32.0",
|
|
90
91
|
"eslint-plugin-prettier": "^5.0.1",
|
|
91
|
-
"jest": "^
|
|
92
|
+
"jest": "^30.1.3",
|
|
92
93
|
"jest-junit": "^16.0.0",
|
|
93
94
|
"js-yaml": "^4.1.0",
|
|
94
95
|
"prettier": "^3.1.0",
|
package/scripts/build.cjs
CHANGED
|
@@ -12,6 +12,29 @@ const path = require('path');
|
|
|
12
12
|
|
|
13
13
|
const isProduction = process.env.NODE_ENV === 'production';
|
|
14
14
|
|
|
15
|
+
const plugins = [
|
|
16
|
+
TsconfigPathsPlugin({
|
|
17
|
+
tsconfig: path.resolve(__dirname, '..', 'tsconfig.json')
|
|
18
|
+
})
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
if (process.env.CODECOV_BUNDLE) {
|
|
22
|
+
try {
|
|
23
|
+
// Attempt to load Codecov bundler plugin for esbuild. If unavailable,
|
|
24
|
+
// warn and continue; CI will conditionally upload only when bundles exist.
|
|
25
|
+
const { codecovEsbuildPlugin } = require('@codecov/bundler-plugin-esbuild');
|
|
26
|
+
plugins.push(
|
|
27
|
+
codecovEsbuildPlugin({
|
|
28
|
+
output: {
|
|
29
|
+
path: path.join(__dirname, '..', 'coverage', 'bundles')
|
|
30
|
+
}
|
|
31
|
+
})
|
|
32
|
+
);
|
|
33
|
+
} catch (err) {
|
|
34
|
+
console.warn('Codecov bundle plugin missing, skipping analysis');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
15
38
|
async function build() {
|
|
16
39
|
try {
|
|
17
40
|
console.log('🔨 Building TypeScript project with esbuild...');
|
|
@@ -37,11 +60,7 @@ async function build() {
|
|
|
37
60
|
sourcemap: !isProduction,
|
|
38
61
|
minify: isProduction,
|
|
39
62
|
treeShaking: true,
|
|
40
|
-
plugins
|
|
41
|
-
TsconfigPathsPlugin({
|
|
42
|
-
tsconfig: path.resolve(__dirname, '..', 'tsconfig.json')
|
|
43
|
-
})
|
|
44
|
-
],
|
|
63
|
+
plugins,
|
|
45
64
|
external: [
|
|
46
65
|
'@modelcontextprotocol/sdk',
|
|
47
66
|
'express',
|
|
@@ -84,4 +103,4 @@ async function build() {
|
|
|
84
103
|
}
|
|
85
104
|
|
|
86
105
|
// Run build
|
|
87
|
-
build();
|
|
106
|
+
build();
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/*
|
|
3
|
+
Generates THIRD_PARTY_NOTICES.md from installed packages.
|
|
4
|
+
Reads direct deps and devDeps from package.json and extracts
|
|
5
|
+
name, version, and license from node_modules/<pkg>/package.json.
|
|
6
|
+
*/
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
function readJSON(p) {
|
|
11
|
+
return JSON.parse(fs.readFileSync(p, 'utf8'));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function pkgInfo(name) {
|
|
15
|
+
try {
|
|
16
|
+
const p = path.join('node_modules', ...name.split('/'));
|
|
17
|
+
const data = readJSON(path.join(p, 'package.json'));
|
|
18
|
+
// Normalize license string
|
|
19
|
+
let license = 'UNKNOWN';
|
|
20
|
+
if (typeof data.license === 'string') license = data.license;
|
|
21
|
+
else if (data.license && typeof data.license.type === 'string') license = data.license.type;
|
|
22
|
+
else if (Array.isArray(data.licenses) && data.licenses.length && data.licenses[0].type)
|
|
23
|
+
license = data.licenses[0].type;
|
|
24
|
+
return { name, version: data.version || 'UNKNOWN', license };
|
|
25
|
+
} catch {
|
|
26
|
+
return { name, version: 'UNKNOWN', license: 'UNKNOWN' };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function generate() {
|
|
31
|
+
const pkg = readJSON(path.join(process.cwd(), 'package.json'));
|
|
32
|
+
const prod = Object.keys(pkg.dependencies || {}).sort().map(pkgInfo);
|
|
33
|
+
const dev = Object.keys(pkg.devDependencies || {}).sort().map(pkgInfo);
|
|
34
|
+
|
|
35
|
+
const lines = [];
|
|
36
|
+
lines.push('# Third-Party Notices');
|
|
37
|
+
lines.push('');
|
|
38
|
+
lines.push(
|
|
39
|
+
'This project includes third-party software. The following lists the direct dependencies and their licenses as resolved in this workspace. For full license texts, see each package’s own repository or the copies included in `node_modules/<package>/LICENSE` when present.'
|
|
40
|
+
);
|
|
41
|
+
lines.push('');
|
|
42
|
+
lines.push(
|
|
43
|
+
'If a dependency is not currently installed in `node_modules`, its version or license may be shown as UNKNOWN below; consult the package’s metadata for definitive terms.'
|
|
44
|
+
);
|
|
45
|
+
lines.push('');
|
|
46
|
+
const now = new Date();
|
|
47
|
+
const isoDate = now.toISOString().slice(0, 10);
|
|
48
|
+
lines.push(`Last updated: ${isoDate}`);
|
|
49
|
+
lines.push('');
|
|
50
|
+
|
|
51
|
+
lines.push('## Production Dependencies');
|
|
52
|
+
lines.push('');
|
|
53
|
+
for (const i of prod) lines.push(`- ${i.name} ${i.version} — ${i.license}`);
|
|
54
|
+
lines.push('');
|
|
55
|
+
|
|
56
|
+
lines.push('## Development Dependencies');
|
|
57
|
+
lines.push('');
|
|
58
|
+
for (const i of dev) lines.push(`- ${i.name} ${i.version} — ${i.license}`);
|
|
59
|
+
lines.push('');
|
|
60
|
+
lines.push('---');
|
|
61
|
+
lines.push('');
|
|
62
|
+
lines.push(
|
|
63
|
+
'Note: This document is provided for convenience and does not modify any license terms. All third-party packages remain the property of their respective copyright holders and are licensed under their own terms.'
|
|
64
|
+
);
|
|
65
|
+
lines.push('');
|
|
66
|
+
|
|
67
|
+
fs.writeFileSync('THIRD_PARTY_NOTICES.md', lines.join('\n'));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
generate();
|
|
71
|
+
|
package/src/teamcity/auth.ts
CHANGED
|
@@ -7,7 +7,7 @@ import type {
|
|
|
7
7
|
AxiosResponse,
|
|
8
8
|
InternalAxiosRequestConfig,
|
|
9
9
|
} from 'axios';
|
|
10
|
-
import {
|
|
10
|
+
import { randomUUID } from 'crypto';
|
|
11
11
|
|
|
12
12
|
import { info, error as logError } from '@/utils/logger';
|
|
13
13
|
|
|
@@ -15,7 +15,7 @@ import { info, error as logError } from '@/utils/logger';
|
|
|
15
15
|
* Generate a unique request ID for tracing
|
|
16
16
|
*/
|
|
17
17
|
export function generateRequestId(): string {
|
|
18
|
-
return
|
|
18
|
+
return randomUUID();
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
package/TODO.md
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
# OSS Launch TODO
|
|
2
|
-
|
|
3
|
-
High-level checklist to complete before publishing the repository to GitHub.
|
|
4
|
-
|
|
5
|
-
## Legal & Notices
|
|
6
|
-
- Create `THIRD_PARTY_NOTICES.md`:
|
|
7
|
-
- Note use of JetBrains TeamCity name/trademark; clarify no affiliation or endorsement.
|
|
8
|
-
- Mention TeamCity REST API usage and link to relevant terms.
|
|
9
|
-
- Acknowledge project crafting via Anthropic’s Claude Code and OpenAI Codex CLI.
|
|
10
|
-
- List notable third‑party deps/tools: `@modelcontextprotocol/sdk`, `axios`, `zod`, `jest`, `ts-jest`, `prettier`, `eslint`, OpenAPI generator.
|
|
11
|
-
- Verify LICENSE (MIT) is correct and reflected in README.
|
|
12
|
-
|
|
13
|
-
## TeamCity Self‑Integration
|
|
14
|
-
- Create a TeamCity project that builds this repo (self‑hosting example):
|
|
15
|
-
- Steps: install deps, `npm run lint`, `npm run typecheck`, `npm test`, `npm run build`.
|
|
16
|
-
- Parameterize Node version via `.nvmrc` (24.7.0) and agent requirements.
|
|
17
|
-
- Configure secure `TEAMCITY_URL`/`TEAMCITY_TOKEN` (dev‑mode, read‑only) as server/agent parameters.
|
|
18
|
-
- Add triggers on `main` and PR branches; publish build artifacts (e.g., coverage report) for docs.
|
|
19
|
-
- Optional: nightly job to run integration smoke tests against a sandbox TeamCity instance.
|
|
20
|
-
|
|
21
|
-
## GitHub Actions (CI/CD)
|
|
22
|
-
- Add workflows (defer until ready to enable CI):
|
|
23
|
-
- `ci.yml`: Node 24, cache `~/.npm`, run `lint:check`, `format:check`, `typecheck`, and `test:coverage` (enforce thresholds); optionally upload coverage to a badge service.
|
|
24
|
-
- `release.yml`: On tag, build and publish to npm (if publishing), generate changelog and GitHub Release.
|
|
25
|
-
- `codeql.yml`: Code scanning (JavaScript/TypeScript).
|
|
26
|
-
- Optional: `e2e.yml` gated by secrets for TeamCity sandbox.
|
|
27
|
-
- Configure required checks (branch protection) for `main` when CI is enabled.
|
|
28
|
-
|
|
29
|
-
## OSS Best Practices
|
|
30
|
-
- README badges: build status (GH Actions), coverage, npm version (if publishing), license, Node version, Prettier.
|
|
31
|
-
- Add Node 24 badge and update README references to Node 24.
|
|
32
|
-
- Governance docs:
|
|
33
|
-
- `CODE_OF_CONDUCT.md` (Contributor Covenant)
|
|
34
|
-
- `SECURITY.md` (reporting policy)
|
|
35
|
-
- Ensure `CONTRIBUTING.md` aligns with workflows and labels
|
|
36
|
-
- Issue/PR templates and labels (bug, feature, question, good‑first‑issue)
|
|
37
|
-
- Release hygiene:
|
|
38
|
-
- `CHANGELOG.md` (keep a human‑readable log or use release‑please)
|
|
39
|
-
- Semantic versioning policy documented in README
|
|
40
|
-
- Repository hygiene:
|
|
41
|
-
- `CODEOWNERS` for review routing
|
|
42
|
-
- Dependabot or Renovate for deps
|
|
43
|
-
- Stale bot policy (optional)
|
|
44
|
-
|
|
45
|
-
## Packaging & Publishing
|
|
46
|
-
- `package.json` metadata: `repository`, `homepage`, `bugs`, `license`, `engines`, `exports`/`bin` (if CLI), `files` whitelist.
|
|
47
|
-
- Add `.npmignore` (or use `files` field) to exclude tests, local scripts, and docs not needed for package.
|
|
48
|
-
- Verify build output under `dist/` matches exports and type definitions.
|
|
49
|
-
|
|
50
|
-
## Codebase Quality (Housekeeping)
|
|
51
|
-
- ESLint hygiene: keep `no-await-in-loop` disables narrowly scoped around intentional sequential logic (done in current codebase; verify on new contributions).
|
|
52
|
-
- Remove remaining legacy `getTool(...)!` usages by migrating to `getRequiredTool` where applicable.
|
|
53
|
-
- Centralize env var validation (zod) in `src/config` and use consistently.
|
|
54
|
-
- Silence ESLint multi-project hint by using `tsconfig.lint.json` or enabling `noWarnOnMultipleProjects`.
|
|
55
|
-
|
|
56
|
-
## Test Stability
|
|
57
|
-
- Avoid forced Jest exits; rely on natural shutdown. Ensure timers are cleared in `tests/setup.ts` (added) and prefer fake timers in new tests.
|
|
58
|
-
|
|
59
|
-
## Documentation
|
|
60
|
-
- README refinements:
|
|
61
|
-
- Add badges, succinct Quick Start, and a minimal “Dev vs Full mode” table.
|
|
62
|
-
- Link to `docs/` and `THIRD_PARTY_NOTICES.md`.
|
|
63
|
-
- Add a short “Security & Privacy” note about token redaction and not committing secrets.
|
|
64
|
-
- Docs site (optional): publish GitHub Pages or Docusaurus if scope grows.
|
|
65
|
-
- Provide minimal examples in `examples/` to demonstrate common tool calls and MCP client integration.
|
|
66
|
-
|
|
67
|
-
## Security & Compliance
|
|
68
|
-
- Enable GitHub secret scanning and push protection.
|
|
69
|
-
- Validate token redaction in logs; keep `.env.example` minimal and safe.
|
|
70
|
-
- Add threat‑model notes (read‑only defaults in `dev` mode; `full` mode cautions).
|
|
71
|
-
|
|
72
|
-
## Project Setup on GitHub
|
|
73
|
-
- Initialize repo, push baseline, add branch protections, enable Discussions (optional).
|
|
74
|
-
- Configure Actions permissions (workflows can create releases/tags if needed).
|
|
75
|
-
- Configure CI required checks and status badges.
|
|
76
|
-
|
|
77
|
-
## Nice‑to‑Haves (Post‑Launch)
|
|
78
|
-
- Benchmarks and performance notes for large TeamCity instances.
|
|
79
|
-
- Example TeamCity templates for self‑integration (YAML or screenshots).
|
|
80
|
-
- Automated docs generation (OpenAPI → client usage snippets) if we add an API facade.
|