@angular/cli 20.2.0-rc.1 → 20.2.1
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/package.json +15 -15
- package/src/command-builder/command-module.js +8 -2
- package/src/command-builder/schematics-command-module.js +7 -0
- package/src/command-builder/utilities/json-schema.d.ts +2 -1
- package/src/command-builder/utilities/json-schema.js +45 -20
- package/src/command-builder/utilities/schematic-engine-host.js +4 -6
- package/src/commands/mcp/cli.js +4 -0
- package/src/commands/mcp/mcp-server.d.ts +11 -0
- package/src/commands/mcp/mcp-server.js +3 -2
- package/src/commands/mcp/tools/doc-search.js +7 -8
- package/src/commands/mcp/tools/modernize.js +0 -10
- package/src/utilities/package-manager.js +1 -1
- package/src/utilities/version.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@angular/cli",
|
|
3
|
-
"version": "20.2.
|
|
3
|
+
"version": "20.2.1",
|
|
4
4
|
"description": "CLI tool for Angular",
|
|
5
5
|
"main": "lib/cli/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -25,13 +25,13 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://github.com/angular/angular-cli",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@angular-devkit/architect": "0.2002.
|
|
29
|
-
"@angular-devkit/core": "20.2.
|
|
30
|
-
"@angular-devkit/schematics": "20.2.
|
|
28
|
+
"@angular-devkit/architect": "0.2002.1",
|
|
29
|
+
"@angular-devkit/core": "20.2.1",
|
|
30
|
+
"@angular-devkit/schematics": "20.2.1",
|
|
31
31
|
"@inquirer/prompts": "7.8.2",
|
|
32
32
|
"@listr2/prompt-adapter-inquirer": "3.0.1",
|
|
33
|
-
"@modelcontextprotocol/sdk": "1.17.
|
|
34
|
-
"@schematics/angular": "20.2.
|
|
33
|
+
"@modelcontextprotocol/sdk": "1.17.3",
|
|
34
|
+
"@schematics/angular": "20.2.1",
|
|
35
35
|
"@yarnpkg/lockfile": "1.1.0",
|
|
36
36
|
"algoliasearch": "5.35.0",
|
|
37
37
|
"ini": "5.0.0",
|
|
@@ -47,17 +47,17 @@
|
|
|
47
47
|
"ng-update": {
|
|
48
48
|
"migrations": "@schematics/angular/migrations/migration-collection.json",
|
|
49
49
|
"packageGroup": {
|
|
50
|
-
"@angular/cli": "20.2.
|
|
51
|
-
"@angular/build": "20.2.
|
|
52
|
-
"@angular/ssr": "20.2.
|
|
53
|
-
"@angular-devkit/architect": "0.2002.
|
|
54
|
-
"@angular-devkit/build-angular": "20.2.
|
|
55
|
-
"@angular-devkit/build-webpack": "0.2002.
|
|
56
|
-
"@angular-devkit/core": "20.2.
|
|
57
|
-
"@angular-devkit/schematics": "20.2.
|
|
50
|
+
"@angular/cli": "20.2.1",
|
|
51
|
+
"@angular/build": "20.2.1",
|
|
52
|
+
"@angular/ssr": "20.2.1",
|
|
53
|
+
"@angular-devkit/architect": "0.2002.1",
|
|
54
|
+
"@angular-devkit/build-angular": "20.2.1",
|
|
55
|
+
"@angular-devkit/build-webpack": "0.2002.1",
|
|
56
|
+
"@angular-devkit/core": "20.2.1",
|
|
57
|
+
"@angular-devkit/schematics": "20.2.1"
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
|
-
"packageManager": "pnpm@10.
|
|
60
|
+
"packageManager": "pnpm@10.15.0",
|
|
61
61
|
"engines": {
|
|
62
62
|
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
|
|
63
63
|
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
|
|
@@ -218,11 +218,17 @@ let CommandModule = (() => {
|
|
|
218
218
|
...Object.values(analytics_parameters_1.EventCustomMetric),
|
|
219
219
|
]);
|
|
220
220
|
for (const [name, ua] of this.optionsWithAnalytics) {
|
|
221
|
+
if (!validEventCustomDimensionAndMetrics.has(ua)) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
221
224
|
const value = options[name];
|
|
222
|
-
if (
|
|
223
|
-
validEventCustomDimensionAndMetrics.has(ua)) {
|
|
225
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
224
226
|
parameters[ua] = value;
|
|
225
227
|
}
|
|
228
|
+
else if (Array.isArray(value)) {
|
|
229
|
+
// GA doesn't allow array as values.
|
|
230
|
+
parameters[ua] = value.sort().join(', ');
|
|
231
|
+
}
|
|
226
232
|
}
|
|
227
233
|
return parameters;
|
|
228
234
|
}
|
|
@@ -224,11 +224,18 @@ let SchematicsCommandModule = (() => {
|
|
|
224
224
|
? {
|
|
225
225
|
name: item,
|
|
226
226
|
value: item,
|
|
227
|
+
checked: definition.multiselect && Array.isArray(definition.default)
|
|
228
|
+
? definition.default?.includes(item)
|
|
229
|
+
: item === definition.default,
|
|
227
230
|
}
|
|
228
231
|
: {
|
|
229
232
|
...item,
|
|
230
233
|
name: item.label,
|
|
231
234
|
value: item.value,
|
|
235
|
+
checked: definition.multiselect && Array.isArray(definition.default)
|
|
236
|
+
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
237
|
+
definition.default?.includes(item.value)
|
|
238
|
+
: item.value === definition.default,
|
|
232
239
|
}),
|
|
233
240
|
});
|
|
234
241
|
break;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { json } from '@angular-devkit/core';
|
|
9
9
|
import type { Argv, Options as YargsOptions } from 'yargs';
|
|
10
|
+
import { EventCustomDimension } from '../../analytics/analytics-parameters';
|
|
10
11
|
/**
|
|
11
12
|
* An option description.
|
|
12
13
|
*/
|
|
@@ -48,4 +49,4 @@ export declare function parseJsonSchemaToOptions(registry: json.schema.SchemaReg
|
|
|
48
49
|
*
|
|
49
50
|
* @returns A map from option name to analytics configuration.
|
|
50
51
|
*/
|
|
51
|
-
export declare function addSchemaOptionsToCommand<T>(localYargs: Argv<T>, options: Option[], includeDefaultValues: boolean): Map<string,
|
|
52
|
+
export declare function addSchemaOptionsToCommand<T>(localYargs: Argv<T>, options: Option[], includeDefaultValues: boolean): Map<string, EventCustomDimension>;
|
|
@@ -10,7 +10,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.parseJsonSchemaToOptions = parseJsonSchemaToOptions;
|
|
11
11
|
exports.addSchemaOptionsToCommand = addSchemaOptionsToCommand;
|
|
12
12
|
const core_1 = require("@angular-devkit/core");
|
|
13
|
-
function
|
|
13
|
+
function checkStringMap(keyValuePairOptions, args) {
|
|
14
|
+
for (const key of keyValuePairOptions) {
|
|
15
|
+
const value = args[key];
|
|
16
|
+
if (!Array.isArray(value)) {
|
|
17
|
+
// Value has been parsed.
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
for (const pair of value) {
|
|
21
|
+
if (pair === undefined) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (!pair.includes('=')) {
|
|
25
|
+
throw new Error(`Invalid value for argument: ${key}, Given: '${pair}', Expected key=value pair`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
function coerceToStringMap(value) {
|
|
14
32
|
const stringMap = {};
|
|
15
33
|
for (const pair of value) {
|
|
16
34
|
// This happens when the flag isn't passed at all.
|
|
@@ -19,14 +37,11 @@ function coerceToStringMap(dashedName, value) {
|
|
|
19
37
|
}
|
|
20
38
|
const eqIdx = pair.indexOf('=');
|
|
21
39
|
if (eqIdx === -1) {
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
// errors with usage output.
|
|
25
|
-
return Promise.reject(new Error(`Invalid value for argument: ${dashedName}, Given: '${pair}', Expected key=value pair`));
|
|
40
|
+
// In the case it is not valid skip processing this option and handle the error in `checkStringMap`
|
|
41
|
+
return value;
|
|
26
42
|
}
|
|
27
43
|
const key = pair.slice(0, eqIdx);
|
|
28
|
-
|
|
29
|
-
stringMap[key] = value;
|
|
44
|
+
stringMap[key] = pair.slice(eqIdx + 1);
|
|
30
45
|
}
|
|
31
46
|
return stringMap;
|
|
32
47
|
}
|
|
@@ -79,7 +94,7 @@ async function parseJsonSchemaToOptions(registry, schema, interactive = true) {
|
|
|
79
94
|
// Only include arrays if they're boolean, string or number.
|
|
80
95
|
if (core_1.json.isJsonObject(current.items) &&
|
|
81
96
|
typeof current.items.type == 'string' &&
|
|
82
|
-
|
|
97
|
+
isValidTypeForEnum(current.items.type)) {
|
|
83
98
|
return true;
|
|
84
99
|
}
|
|
85
100
|
return false;
|
|
@@ -94,16 +109,13 @@ async function parseJsonSchemaToOptions(registry, schema, interactive = true) {
|
|
|
94
109
|
return;
|
|
95
110
|
}
|
|
96
111
|
// Only keep enum values we support (booleans, numbers and strings).
|
|
97
|
-
const enumValues = ((core_1.json.isJsonArray(current.enum) && current.enum) ||
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return false;
|
|
105
|
-
}
|
|
106
|
-
});
|
|
112
|
+
const enumValues = ((core_1.json.isJsonArray(current.enum) && current.enum) ||
|
|
113
|
+
(core_1.json.isJsonObject(current.items) &&
|
|
114
|
+
core_1.json.isJsonArray(current.items.enum) &&
|
|
115
|
+
current.items.enum) ||
|
|
116
|
+
[])
|
|
117
|
+
.filter((value) => isValidTypeForEnum(typeof value))
|
|
118
|
+
.sort();
|
|
107
119
|
let defaultValue = undefined;
|
|
108
120
|
if (current.default !== undefined) {
|
|
109
121
|
switch (types[0]) {
|
|
@@ -112,6 +124,11 @@ async function parseJsonSchemaToOptions(registry, schema, interactive = true) {
|
|
|
112
124
|
defaultValue = current.default;
|
|
113
125
|
}
|
|
114
126
|
break;
|
|
127
|
+
case 'array':
|
|
128
|
+
if (Array.isArray(current.default)) {
|
|
129
|
+
defaultValue = current.default;
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
115
132
|
case 'number':
|
|
116
133
|
if (typeof current.default == 'number') {
|
|
117
134
|
defaultValue = current.default;
|
|
@@ -199,7 +216,7 @@ function addSchemaOptionsToCommand(localYargs, options, includeDefaultValues) {
|
|
|
199
216
|
booleanOptionsWithNoPrefix.add(dashedName);
|
|
200
217
|
}
|
|
201
218
|
if (itemValueType) {
|
|
202
|
-
keyValuePairOptions.add(
|
|
219
|
+
keyValuePairOptions.add(dashedName);
|
|
203
220
|
}
|
|
204
221
|
const sharedOptions = {
|
|
205
222
|
alias,
|
|
@@ -207,7 +224,7 @@ function addSchemaOptionsToCommand(localYargs, options, includeDefaultValues) {
|
|
|
207
224
|
description,
|
|
208
225
|
deprecated,
|
|
209
226
|
choices,
|
|
210
|
-
coerce: itemValueType ? coerceToStringMap
|
|
227
|
+
coerce: itemValueType ? coerceToStringMap : undefined,
|
|
211
228
|
// This should only be done when `--help` is used otherwise default will override options set in angular.json.
|
|
212
229
|
...(includeDefaultValues ? { default: defaultVal } : {}),
|
|
213
230
|
};
|
|
@@ -229,6 +246,10 @@ function addSchemaOptionsToCommand(localYargs, options, includeDefaultValues) {
|
|
|
229
246
|
optionsWithAnalytics.set(name, userAnalytics);
|
|
230
247
|
}
|
|
231
248
|
}
|
|
249
|
+
// Valid key/value options
|
|
250
|
+
if (keyValuePairOptions.size) {
|
|
251
|
+
localYargs.check(checkStringMap.bind(null, keyValuePairOptions), false);
|
|
252
|
+
}
|
|
232
253
|
// Handle options which have been defined in the schema with `no` prefix.
|
|
233
254
|
if (booleanOptionsWithNoPrefix.size) {
|
|
234
255
|
localYargs.middleware((options) => {
|
|
@@ -242,3 +263,7 @@ function addSchemaOptionsToCommand(localYargs, options, includeDefaultValues) {
|
|
|
242
263
|
}
|
|
243
264
|
return optionsWithAnalytics;
|
|
244
265
|
}
|
|
266
|
+
const VALID_ENUM_TYPES = new Set(['boolean', 'number', 'string']);
|
|
267
|
+
function isValidTypeForEnum(value) {
|
|
268
|
+
return VALID_ENUM_TYPES.has(value);
|
|
269
|
+
}
|
|
@@ -47,11 +47,9 @@ function shouldWrapSchematic(schematicFile, schematicEncapsulation) {
|
|
|
47
47
|
}
|
|
48
48
|
// Check for first-party Angular schematic packages
|
|
49
49
|
// Angular schematics are safe to use in the wrapped VM context
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
// Otherwise use the value of the schematic collection's encapsulation option (current default of false)
|
|
54
|
-
return schematicEncapsulation;
|
|
50
|
+
const isFirstParty = /\/node_modules\/@(?:angular|schematics|nguniversal)\//.test(normalizedSchematicFile);
|
|
51
|
+
// Use value of defined option if present, otherwise default to first-party usage.
|
|
52
|
+
return schematicEncapsulation ?? isFirstParty;
|
|
55
53
|
}
|
|
56
54
|
class SchematicEngineHost extends tools_1.NodeModulesEngineHost {
|
|
57
55
|
_resolveReferenceString(refString, parentPath, collectionDescription) {
|
|
@@ -60,7 +58,7 @@ class SchematicEngineHost extends tools_1.NodeModulesEngineHost {
|
|
|
60
58
|
const fullPath = path[0] === '.' ? (0, node_path_1.resolve)(parentPath ?? process.cwd(), path) : path;
|
|
61
59
|
const referenceRequire = (0, node_module_1.createRequire)(__filename);
|
|
62
60
|
const schematicFile = referenceRequire.resolve(fullPath, { paths: [parentPath] });
|
|
63
|
-
if (shouldWrapSchematic(schematicFile,
|
|
61
|
+
if (shouldWrapSchematic(schematicFile, collectionDescription?.encapsulation)) {
|
|
64
62
|
const schematicPath = (0, node_path_1.dirname)(schematicFile);
|
|
65
63
|
const moduleCache = new Map();
|
|
66
64
|
const factoryInitializer = wrap(schematicFile, schematicPath, moduleCache, name || 'default');
|
package/src/commands/mcp/cli.js
CHANGED
|
@@ -24,6 +24,8 @@ To start using the Angular CLI MCP Server, add this configuration to your host:
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
Exact configuration may differ depending on the host.
|
|
27
|
+
|
|
28
|
+
For more information and documentation, visit: https://angular.dev/ai/mcp
|
|
27
29
|
`;
|
|
28
30
|
class McpCommandModule extends command_module_1.CommandModule {
|
|
29
31
|
command = 'mcp';
|
|
@@ -46,6 +48,8 @@ class McpCommandModule extends command_module_1.CommandModule {
|
|
|
46
48
|
alias: 'E',
|
|
47
49
|
array: true,
|
|
48
50
|
describe: 'Enable an experimental tool.',
|
|
51
|
+
choices: mcp_server_1.EXPERIMENTAL_TOOLS.map(({ name }) => name),
|
|
52
|
+
hidden: true,
|
|
49
53
|
});
|
|
50
54
|
}
|
|
51
55
|
async run(options) {
|
|
@@ -8,6 +8,17 @@
|
|
|
8
8
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
9
9
|
import type { AngularWorkspace } from '../../utilities/config';
|
|
10
10
|
import { AnyMcpToolDeclaration } from './tools/tool-registry';
|
|
11
|
+
/**
|
|
12
|
+
* The set of tools that are available but not enabled by default.
|
|
13
|
+
* These tools are considered experimental and may have limitations.
|
|
14
|
+
*/
|
|
15
|
+
export declare const EXPERIMENTAL_TOOLS: readonly [import("./tools/tool-registry").McpToolDeclaration<{
|
|
16
|
+
query: import("zod").ZodString;
|
|
17
|
+
}, import("zod").ZodRawShape>, import("./tools/tool-registry").McpToolDeclaration<{
|
|
18
|
+
transformations: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodEnum<[string, ...string[]]>, "many">>;
|
|
19
|
+
}, {
|
|
20
|
+
instructions: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString, "many">>;
|
|
21
|
+
}>];
|
|
11
22
|
export declare function createMcpServer(options: {
|
|
12
23
|
workspace?: AngularWorkspace;
|
|
13
24
|
readOnly?: boolean;
|
|
@@ -10,6 +10,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
10
10
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.EXPERIMENTAL_TOOLS = void 0;
|
|
13
14
|
exports.createMcpServer = createMcpServer;
|
|
14
15
|
exports.assembleToolDeclarations = assembleToolDeclarations;
|
|
15
16
|
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
@@ -31,7 +32,7 @@ const STABLE_TOOLS = [best_practices_1.BEST_PRACTICES_TOOL, doc_search_1.DOC_SEA
|
|
|
31
32
|
* The set of tools that are available but not enabled by default.
|
|
32
33
|
* These tools are considered experimental and may have limitations.
|
|
33
34
|
*/
|
|
34
|
-
|
|
35
|
+
exports.EXPERIMENTAL_TOOLS = [examples_1.FIND_EXAMPLE_TOOL, modernize_1.MODERNIZE_TOOL];
|
|
35
36
|
async function createMcpServer(options, logger) {
|
|
36
37
|
const server = new mcp_js_1.McpServer({
|
|
37
38
|
name: 'angular-cli-server',
|
|
@@ -46,7 +47,7 @@ async function createMcpServer(options, logger) {
|
|
|
46
47
|
'When writing or modifying Angular code, use the MCP server and its tools instead of direct shell commands where possible.',
|
|
47
48
|
});
|
|
48
49
|
(0, instructions_1.registerInstructionsResource)(server);
|
|
49
|
-
const toolDeclarations = assembleToolDeclarations(STABLE_TOOLS, EXPERIMENTAL_TOOLS, {
|
|
50
|
+
const toolDeclarations = assembleToolDeclarations(STABLE_TOOLS, exports.EXPERIMENTAL_TOOLS, {
|
|
50
51
|
...options,
|
|
51
52
|
logger,
|
|
52
53
|
});
|
|
@@ -112,7 +112,7 @@ function createDocSearchHandler() {
|
|
|
112
112
|
const response = await fetch(url);
|
|
113
113
|
if (response.ok) {
|
|
114
114
|
const html = await response.text();
|
|
115
|
-
const mainContent =
|
|
115
|
+
const mainContent = extractMainContent(html);
|
|
116
116
|
if (mainContent) {
|
|
117
117
|
topText += `\n\n--- DOCUMENTATION CONTENT ---\n${mainContent}`;
|
|
118
118
|
}
|
|
@@ -138,22 +138,21 @@ function createDocSearchHandler() {
|
|
|
138
138
|
};
|
|
139
139
|
}
|
|
140
140
|
/**
|
|
141
|
-
* Extracts the content of the `<
|
|
141
|
+
* Extracts the content of the `<main>` element from an HTML string.
|
|
142
142
|
*
|
|
143
143
|
* @param html The HTML content of a page.
|
|
144
|
-
* @returns The content of the `<
|
|
144
|
+
* @returns The content of the `<main>` element, or `undefined` if not found.
|
|
145
145
|
*/
|
|
146
|
-
function
|
|
147
|
-
|
|
148
|
-
const mainTagStart = html.indexOf('<body');
|
|
146
|
+
function extractMainContent(html) {
|
|
147
|
+
const mainTagStart = html.indexOf('<main');
|
|
149
148
|
if (mainTagStart === -1) {
|
|
150
149
|
return undefined;
|
|
151
150
|
}
|
|
152
|
-
const mainTagEnd = html.lastIndexOf('</
|
|
151
|
+
const mainTagEnd = html.lastIndexOf('</main>');
|
|
153
152
|
if (mainTagEnd <= mainTagStart) {
|
|
154
153
|
return undefined;
|
|
155
154
|
}
|
|
156
|
-
// Add 7 to include '</
|
|
155
|
+
// Add 7 to include '</main>'
|
|
157
156
|
return html.substring(mainTagStart, mainTagEnd + 7);
|
|
158
157
|
}
|
|
159
158
|
/**
|
|
@@ -22,11 +22,6 @@ const TRANSFORMATIONS = [
|
|
|
22
22
|
description: 'Converts tags for elements with no content to be self-closing (e.g., `<app-foo></app-foo>` becomes `<app-foo />`).',
|
|
23
23
|
documentationUrl: 'https://angular.dev/reference/migrations/self-closing-tags',
|
|
24
24
|
},
|
|
25
|
-
{
|
|
26
|
-
name: 'test-bed-get',
|
|
27
|
-
description: 'Updates `TestBed.get` to the preferred and type-safe `TestBed.inject` in TypeScript test files.',
|
|
28
|
-
documentationUrl: 'https://angular.dev/guide/testing/dependency-injection',
|
|
29
|
-
},
|
|
30
25
|
{
|
|
31
26
|
name: 'inject',
|
|
32
27
|
description: 'Converts usages of constructor-based injection to the inject() function.',
|
|
@@ -59,11 +54,6 @@ const TRANSFORMATIONS = [
|
|
|
59
54
|
'3. Run `ng g @angular/core:standalone` and select "Bootstrap the project using standalone APIs"',
|
|
60
55
|
documentationUrl: 'https://angular.dev/reference/migrations/standalone',
|
|
61
56
|
},
|
|
62
|
-
{
|
|
63
|
-
name: 'zoneless',
|
|
64
|
-
description: 'Migrates the application to be zoneless.',
|
|
65
|
-
documentationUrl: 'https://angular.dev/guide/zoneless',
|
|
66
|
-
},
|
|
67
57
|
];
|
|
68
58
|
const modernizeInputSchema = zod_1.z.object({
|
|
69
59
|
// Casting to [string, ...string[]] since the enum definition requires a nonempty array.
|
|
@@ -171,7 +171,7 @@ let PackageManagerUtils = (() => {
|
|
|
171
171
|
const { cwd = process.cwd(), silent = false } = options;
|
|
172
172
|
return new Promise((resolve) => {
|
|
173
173
|
const bufferedOutput = [];
|
|
174
|
-
const childProcess = (0, node_child_process_1.spawn)(this.name
|
|
174
|
+
const childProcess = (0, node_child_process_1.spawn)(`${this.name} ${args.join(' ')}`, {
|
|
175
175
|
// Always pipe stderr to allow for failures to be reported
|
|
176
176
|
stdio: silent ? ['ignore', 'ignore', 'pipe'] : 'pipe',
|
|
177
177
|
shell: true,
|
package/src/utilities/version.js
CHANGED