@zereight/mcp-gitlab 2.2.1 → 2.2.3

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.
@@ -5,31 +5,116 @@ function shownEnvValue(rawValue) {
5
5
  }
6
6
  return `${singleLine.slice(0, 77)}...`;
7
7
  }
8
+ const REMOVAL_VERSION = "v3.0.0";
9
+ const DEPRECATION_NOTICE_URL = "https://github.com/zereight/gitlab-mcp/issues/815";
8
10
  // USE_PIPELINE exposes these two tools, but they live in the `ci` toolset, not `pipelines`.
9
11
  // Suggesting `ci` would also turn on catalog tools the flag does not expose.
10
12
  const LEGACY_TOOLS_OUTSIDE_NAMED_TOOLSET = {
11
13
  pipelines: "validate_ci_lint,validate_project_ci_lint",
12
14
  };
13
- function legacyToolsetReplacement(toolset) {
14
- const toolsets = `GITLAB_TOOLSETS=core,${toolset}`;
15
+ function explicitToolsets(raw) {
16
+ if (raw === undefined) {
17
+ return undefined;
18
+ }
19
+ const trimmed = raw.trim();
20
+ if (trimmed === "") {
21
+ return undefined;
22
+ }
23
+ return trimmed;
24
+ }
25
+ function isAllToolsets(raw) {
26
+ return raw.trim().toLowerCase() === "all";
27
+ }
28
+ function settingName(envName, cliFlag, fromCli) {
29
+ if (fromCli) {
30
+ return `\`--${cliFlag}\` (${envName})`;
31
+ }
32
+ return envName;
33
+ }
34
+ function gitlabToolsAssignment(extraTools, toolsRaw, toolsFromCli) {
35
+ const prefix = toolsFromCli ? "--tools=" : "GITLAB_TOOLS=";
36
+ const existing = explicitToolsets(toolsRaw);
37
+ if (existing === undefined) {
38
+ return `${prefix}${extraTools}`;
39
+ }
40
+ const names = existing
41
+ .split(",")
42
+ .map(part => part.trim())
43
+ .filter(part => part.length > 0);
44
+ const merged = extraTools.split(",").reduce((current, tool) => {
45
+ if (current.includes(tool)) {
46
+ return current;
47
+ }
48
+ return [...current, tool];
49
+ }, names);
50
+ return `${prefix}${merged.join(",")}`;
51
+ }
52
+ function legacyToolsetHint(toolset, toolsetsRaw, toolsetsFromCli, toolsRaw, toolsFromCli, optional) {
15
53
  const extraTools = LEGACY_TOOLS_OUTSIDE_NAMED_TOOLSET[toolset];
16
- if (extraTools === undefined) {
17
- return toolsets;
54
+ const toolsAssignment = extraTools === undefined
55
+ ? undefined
56
+ : gitlabToolsAssignment(extraTools, toolsRaw, toolsFromCli);
57
+ const listed = explicitToolsets(toolsetsRaw);
58
+ const toolsetsLabel = toolsetsFromCli && listed !== undefined ? "--toolsets" : "GITLAB_TOOLSETS";
59
+ if (listed !== undefined) {
60
+ const shown = shownEnvValue(listed);
61
+ // parseEnabledToolsets treats only the exact value "all" as every toolset.
62
+ // "all,pipelines" is not "all"; unknown token "all" is dropped and pipelines remains.
63
+ if (isAllToolsets(listed)) {
64
+ return `Keep the existing ${toolsetsLabel} value ("${shown}") and remove the deprecated setting`;
65
+ }
66
+ const extra = toolsAssignment === undefined ? "" : ` and set ${toolsAssignment}`;
67
+ if (optional) {
68
+ return (`Add \`${toolset}\` to the existing ${toolsetsLabel} list ("${shown}")${extra} ` +
69
+ "only if you want those tools");
70
+ }
71
+ return `Add \`${toolset}\` to the existing ${toolsetsLabel} list ("${shown}")${extra} instead`;
72
+ }
73
+ // An explicit toolset list replaces the default toolsets; it does not merge.
74
+ // Legacy USE_* flags add tools on top of defaults, so the hint must keep `core`
75
+ // only when the user has not set a toolset list.
76
+ const toolsets = `GITLAB_TOOLSETS=core,${toolset}`;
77
+ const replacement = toolsAssignment === undefined ? toolsets : `${toolsets} and ${toolsAssignment}`;
78
+ if (optional) {
79
+ return `Set ${replacement} only if you want those tools in addition to core`;
18
80
  }
19
- return `${toolsets} and GITLAB_TOOLS=${extraTools}`;
81
+ return `Use ${replacement} instead`;
20
82
  }
21
- function legacyToolsetWarning(envName, rawValue, toolset) {
22
- // An explicit GITLAB_TOOLSETS list replaces the default toolsets; it does not merge.
23
- // Legacy USE_* flags add tools on top of defaults, so the hint must keep `core`.
24
- const replacement = legacyToolsetReplacement(toolset);
83
+ function legacyToolsetWarning(envName, cliFlag, fromCli, rawValue, toolset, toolsetsRaw, toolsetsFromCli, toolsRaw, toolsFromCli) {
84
+ const name = settingName(envName, cliFlag, fromCli);
25
85
  if (rawValue === "true") {
26
- return (`${envName} is deprecated and will be removed in the next major version. ` +
27
- `Use ${replacement} instead.`);
86
+ return (`${name} is deprecated and will be removed in ${REMOVAL_VERSION}. ` +
87
+ `${legacyToolsetHint(toolset, toolsetsRaw, toolsetsFromCli, toolsRaw, toolsFromCli, false)}.`);
28
88
  }
29
89
  const shown = shownEnvValue(rawValue);
30
- return (`${envName} is set to "${shown}" and is deprecated. ` +
90
+ return (`${name} is set to "${shown}" and is deprecated and will be removed in ${REMOVAL_VERSION}. ` +
31
91
  `This value does not enable the ${toolset} toolset. Remove it. ` +
32
- `Set ${replacement} only if you want those tools in addition to core.`);
92
+ `${legacyToolsetHint(toolset, toolsetsRaw, toolsetsFromCli, toolsRaw, toolsFromCli, true)}.`);
93
+ }
94
+ function readOnlyRawValue(input) {
95
+ if (input.readOnlyRaw !== undefined && input.readOnlyRaw !== "") {
96
+ return input.readOnlyRaw;
97
+ }
98
+ if (input.readOnlyMode) {
99
+ return "true";
100
+ }
101
+ return undefined;
102
+ }
103
+ function readOnlyWarning(input) {
104
+ const raw = readOnlyRawValue(input);
105
+ if (raw === undefined) {
106
+ return undefined;
107
+ }
108
+ const name = settingName("GITLAB_READ_ONLY_MODE", "read-only", input.readOnlyFromCli === true);
109
+ if (raw === "true") {
110
+ const conflict = input.permissionModeRaw !== undefined && input.permissionModeRaw !== "readonly"
111
+ ? ` It OVERRIDES the configured permission mode "${input.permissionModeRaw}"; the server runs as "readonly".`
112
+ : "";
113
+ return (`${name} is deprecated and will be removed in ${REMOVAL_VERSION}. ` +
114
+ `Use GITLAB_PERMISSION_MODE=readonly or --permission-mode=readonly instead.${conflict}`);
115
+ }
116
+ return (`${name} is set to "${shownEnvValue(raw)}" and is deprecated and will be removed in ${REMOVAL_VERSION}. ` +
117
+ "This value does not enable legacy read-only mode. The effective permission mode comes from GITLAB_PERMISSION_MODE or --permission-mode. Remove it.");
33
118
  }
34
119
  /**
35
120
  * Builds startup warnings for deprecated env vars / CLI flags.
@@ -37,27 +122,72 @@ function legacyToolsetWarning(envName, rawValue, toolset) {
37
122
  */
38
123
  export function getDeprecatedEnvWarnings(input) {
39
124
  const warnings = [];
40
- if (input.readOnlyMode) {
41
- const conflict = input.permissionModeRaw !== undefined && input.permissionModeRaw !== "readonly"
42
- ? ` It OVERRIDES the configured permission mode "${input.permissionModeRaw}"; the server runs as "readonly".`
43
- : "";
44
- warnings.push("GITLAB_READ_ONLY_MODE is deprecated and will be removed in the next major version. " +
45
- `Use GITLAB_PERMISSION_MODE=readonly or --permission-mode=readonly instead.${conflict}`);
125
+ const readOnly = readOnlyWarning(input);
126
+ if (readOnly !== undefined) {
127
+ warnings.push(readOnly);
46
128
  }
47
129
  if (input.allowedGroupsRaw) {
130
+ const name = settingName("GITLAB_ALLOWED_GROUPS", "allowed-groups", input.allowedGroupsFromCli === true);
48
131
  warnings.push(input.oauthAllowedGroupsRaw
49
- ? "GITLAB_ALLOWED_GROUPS is deprecated and ignored because GITLAB_OAUTH_ALLOWED_GROUPS is set. Remove it."
50
- : "GITLAB_ALLOWED_GROUPS is deprecated and will be removed in the next major version. Use GITLAB_OAUTH_ALLOWED_GROUPS instead.");
132
+ ? `${name} is deprecated and ignored because GITLAB_OAUTH_ALLOWED_GROUPS is set. Remove it. It will be removed in ${REMOVAL_VERSION}.`
133
+ : `${name} is deprecated and will be removed in ${REMOVAL_VERSION}. Use GITLAB_OAUTH_ALLOWED_GROUPS instead.`);
51
134
  }
52
135
  const legacyToolsetFlags = [
53
- [input.useWikiRaw, "USE_GITLAB_WIKI", "wiki"],
54
- [input.useMilestoneRaw, "USE_MILESTONE", "milestones"],
55
- [input.usePipelineRaw, "USE_PIPELINE", "pipelines"],
136
+ {
137
+ rawValue: input.useWikiRaw,
138
+ envName: "USE_GITLAB_WIKI",
139
+ cliFlag: "use-wiki",
140
+ fromCli: input.useWikiFromCli === true,
141
+ toolset: "wiki",
142
+ },
143
+ {
144
+ rawValue: input.useMilestoneRaw,
145
+ envName: "USE_MILESTONE",
146
+ cliFlag: "use-milestone",
147
+ fromCli: input.useMilestoneFromCli === true,
148
+ toolset: "milestones",
149
+ },
150
+ {
151
+ rawValue: input.usePipelineRaw,
152
+ envName: "USE_PIPELINE",
153
+ cliFlag: "use-pipeline",
154
+ fromCli: input.usePipelineFromCli === true,
155
+ toolset: "pipelines",
156
+ },
56
157
  ];
57
- for (const [rawValue, envName, toolset] of legacyToolsetFlags) {
58
- if (rawValue !== undefined) {
59
- warnings.push(legacyToolsetWarning(envName, rawValue, toolset));
158
+ for (const flag of legacyToolsetFlags) {
159
+ if (flag.rawValue !== undefined) {
160
+ warnings.push(legacyToolsetWarning(flag.envName, flag.cliFlag, flag.fromCli, flag.rawValue, flag.toolset, input.toolsetsRaw, input.toolsetsFromCli === true, input.toolsRaw, input.toolsFromCli === true));
60
161
  }
61
162
  }
62
- return warnings;
163
+ return warnings.map(warning => `${warning} See ${DEPRECATION_NOTICE_URL} for migration details.`);
164
+ }
165
+ function readSuppliedSetting(parsedArgs, env, cliKey, envKey) {
166
+ return parsedArgs[cliKey] || env[envKey];
167
+ }
168
+ /**
169
+ * Warning snapshot for one command. CLI flags in `parsedArgs` win over `env`,
170
+ * matching getConfig, and neither source is read from the process globals.
171
+ */
172
+ export function deprecatedEnvInputFromSources(parsedArgs, env) {
173
+ const readOnlyRaw = readSuppliedSetting(parsedArgs, env, "read-only", "GITLAB_READ_ONLY_MODE");
174
+ return {
175
+ readOnlyMode: readOnlyRaw === "true",
176
+ readOnlyRaw,
177
+ readOnlyFromCli: Boolean(parsedArgs["read-only"]),
178
+ permissionModeRaw: readSuppliedSetting(parsedArgs, env, "permission-mode", "GITLAB_PERMISSION_MODE"),
179
+ allowedGroupsRaw: readSuppliedSetting(parsedArgs, env, "allowed-groups", "GITLAB_ALLOWED_GROUPS"),
180
+ allowedGroupsFromCli: Boolean(parsedArgs["allowed-groups"]),
181
+ oauthAllowedGroupsRaw: readSuppliedSetting(parsedArgs, env, "oauth-allowed-groups", "GITLAB_OAUTH_ALLOWED_GROUPS"),
182
+ useWikiRaw: readSuppliedSetting(parsedArgs, env, "use-wiki", "USE_GITLAB_WIKI"),
183
+ useWikiFromCli: Boolean(parsedArgs["use-wiki"]),
184
+ useMilestoneRaw: readSuppliedSetting(parsedArgs, env, "use-milestone", "USE_MILESTONE"),
185
+ useMilestoneFromCli: Boolean(parsedArgs["use-milestone"]),
186
+ usePipelineRaw: readSuppliedSetting(parsedArgs, env, "use-pipeline", "USE_PIPELINE"),
187
+ usePipelineFromCli: Boolean(parsedArgs["use-pipeline"]),
188
+ toolsetsRaw: readSuppliedSetting(parsedArgs, env, "toolsets", "GITLAB_TOOLSETS"),
189
+ toolsetsFromCli: Boolean(parsedArgs["toolsets"]),
190
+ toolsRaw: readSuppliedSetting(parsedArgs, env, "tools", "GITLAB_TOOLS"),
191
+ toolsFromCli: Boolean(parsedArgs["tools"]),
192
+ };
63
193
  }