Skip to content

Commit 01f6b13

Browse files
committed
fix(@angular/cli): correct linting errors in mcp tools
1 parent d971e53 commit 01f6b13

4 files changed

Lines changed: 64 additions & 24 deletions

File tree

packages/angular/cli/src/commands/mcp/mcp-server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import { readFile } from 'node:fs/promises';
1111
import path from 'node:path';
1212
import type { AngularWorkspace } from '../../utilities/config';
1313
import { VERSION } from '../../utilities/version';
14+
import { registerInstructionsResource } from './resources/instructions';
1415
import { registerBestPracticesTool } from './tools/best-practices';
1516
import { registerDocSearchTool } from './tools/doc-search';
1617
import { registerFindExampleTool } from './tools/examples';
17-
import { registerListProjectsTool } from './tools/projects';
18-
import { registerInstructionsResource } from './resources/instructions';
1918
import { registerModernizeTool } from './tools/modernize';
19+
import { registerListProjectsTool } from './tools/projects';
2020

2121
export async function createMcpServer(
2222
context: {

packages/angular/cli/src/commands/mcp/resources/instructions.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
19
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
210
import { readFile } from 'node:fs/promises';
311
import path from 'node:path';

packages/angular/cli/src/commands/mcp/tools/modernize.ts

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
19
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
210
import { z } from 'zod';
311

@@ -52,13 +60,15 @@ const TRANSFORMATIONS: Array<Transformation> = [
5260
{
5361
name: 'standalone',
5462
description:
55-
'Converts the application to use standalone components, directives, and pipes. This is a three-step process. After each step, you should verify that your application builds and runs correctly.',
56-
instructions: `This migration requires running a cli schematic multiple times. Run the commands in the order listed below, verifying that your code builds and runs between each step:
57-
58-
1. Run \`ng g @angular/core:standalone\` and select "Convert all components, directives and pipes to standalone"
59-
2. Run \`ng g @angular/core:standalone\` and select "Remove unnecessary NgModule classes"
60-
3. Run \`ng g @angular/core:standalone\` and select "Bootstrap the project using standalone APIs"
61-
`,
63+
'Converts the application to use standalone components, directives, and pipes. This is a ' +
64+
'three-step process. After each step, you should verify that your application builds and ' +
65+
'runs correctly.',
66+
instructions:
67+
'This migration requires running a cli schematic multiple times. Run the commands in the ' +
68+
'order listed below, verifying that your code builds and runs between each step:\n\n' +
69+
'1. Run `ng g @angular/core:standalone` and select "Convert all components, directives and pipes to standalone"\n' +
70+
'2. Run `ng g @angular/core:standalone` and select "Remove unnecessary NgModule classes"\n' +
71+
'3. Run `ng g @angular/core:standalone` and select "Bootstrap the project using standalone APIs"',
6272
documentationUrl: 'https://angular.dev/reference/migrations/standalone',
6373
},
6474
{
@@ -81,8 +91,10 @@ export async function runModernization(input: ModernizeInput) {
8191
try {
8292
if (!input.transformations || input.transformations.length === 0) {
8393
const instructions = [
84-
'See https://angular.dev/best-practices for Angular best practices. You can call this tool if you have specific transformation you want to run.',
94+
'See https://angular.dev/best-practices for Angular best practices. ' +
95+
'You can call this tool if you have specific transformation you want to run.',
8596
];
97+
8698
return {
8799
content: [
88100
{
@@ -99,7 +111,7 @@ export async function runModernization(input: ModernizeInput) {
99111
}
100112

101113
const transformationsToRun = TRANSFORMATIONS.filter((t) =>
102-
input.transformations!.includes(t.name),
114+
input.transformations?.includes(t.name),
103115
);
104116

105117
const allInstructions: string[] = [];
@@ -129,6 +141,7 @@ export async function runModernization(input: ModernizeInput) {
129141
};
130142
} catch (e) {
131143
const message = e instanceof Error ? e.message : 'An unknown error occurred.';
144+
132145
return {
133146
content: [
134147
{
@@ -149,12 +162,16 @@ export function registerModernizeTool(server: McpServer): void {
149162
title: 'Modernize Angular Code',
150163
description:
151164
'<Purpose>\n' +
152-
'This tool modernizes Angular code by applying the latest best practices and syntax improvements, ensuring it is idiomatic, readable, and maintainable.\n\n' +
165+
'This tool modernizes Angular code by applying the latest best practices and syntax improvements, ' +
166+
'ensuring it is idiomatic, readable, and maintainable.\n\n' +
153167
'</Purpose>\n' +
154168
'<Use Cases>\n' +
155-
'* After generating new code: Run this tool immediately after creating new Angular components, directives, or services to ensure they adhere to modern standards.\n' +
156-
'* On existing code: Apply to existing TypeScript files (.ts) and Angular templates (.ng.html) to update them with the latest features, such as the new built-in control flow syntax.\n\n' +
157-
'* When the user asks for a specific transformation: When the transformation list is populated, these specific ones will be ran on the inputs.\n' +
169+
'* After generating new code: Run this tool immediately after creating new Angular components, directives, ' +
170+
'or services to ensure they adhere to modern standards.\n' +
171+
'* On existing code: Apply to existing TypeScript files (.ts) and Angular templates (.ng.html) to update ' +
172+
'them with the latest features, such as the new built-in control flow syntax.\n\n' +
173+
'* When the user asks for a specific transformation: When the transformation list is populated, ' +
174+
'these specific ones will be ran on the inputs.\n' +
158175
'</Use Cases>\n' +
159176
'<Transformations>\n' +
160177
TRANSFORMATIONS.map((t) => `* ${t.name}: ${t.description}`).join('\n') +
@@ -170,6 +187,6 @@ export function registerModernizeTool(server: McpServer): void {
170187
.describe('A list of instructions on how to run the migrations.'),
171188
},
172189
},
173-
(input) => runModernization(input as ModernizeInput),
190+
(input) => runModernization(input),
174191
);
175192
}

packages/angular/cli/src/commands/mcp/tools/modernize_spec.ts

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
19
import { ModernizeInput, runModernization } from './modernize';
210

311
describe('Modernize Tool', () => {
412
async function getInstructions(input: ModernizeInput): Promise<string[] | undefined> {
513
const { structuredContent } = await runModernization(input);
14+
615
if (!structuredContent || !('instructions' in structuredContent)) {
716
fail('Expected instructions to be present in the result');
17+
818
return;
919
}
20+
1021
return structuredContent.instructions;
1122
}
1223

@@ -16,8 +27,9 @@ describe('Modernize Tool', () => {
1627
});
1728

1829
expect(instructions).toEqual([
19-
'To run the self-closing-tags-migration migration, execute the following command: `ng generate @angular/core:self-closing-tags-migration`.' +
20-
'\nFor more information, see https://angular.dev/reference/migrations/self-closing-tags.',
30+
'To run the self-closing-tags-migration migration, execute the following command: ' +
31+
'`ng generate @angular/core:self-closing-tags-migration`.\nFor more information, ' +
32+
'see https://angular.dev/reference/migrations/self-closing-tags.',
2133
]);
2234
});
2335

@@ -27,10 +39,12 @@ describe('Modernize Tool', () => {
2739
});
2840

2941
const expectedInstructions = [
30-
'To run the self-closing-tags-migration migration, execute the following command: `ng generate @angular/core:self-closing-tags-migration`.' +
31-
'\nFor more information, see https://angular.dev/reference/migrations/self-closing-tags.',
32-
'To run the test-bed-get migration, execute the following command: `ng generate @angular/core:test-bed-get`.' +
33-
'\nFor more information, see https://angular.dev/guide/testing/dependency-injection.',
42+
'To run the self-closing-tags-migration migration, execute the following command: ' +
43+
'`ng generate @angular/core:self-closing-tags-migration`.\nFor more information, ' +
44+
'see https://angular.dev/reference/migrations/self-closing-tags.',
45+
'To run the test-bed-get migration, execute the following command: ' +
46+
'`ng generate @angular/core:test-bed-get`.\nFor more information, ' +
47+
'see https://angular.dev/guide/testing/dependency-injection.',
3448
];
3549

3650
expect(instructions?.sort()).toEqual(expectedInstructions.sort());
@@ -42,7 +56,8 @@ describe('Modernize Tool', () => {
4256
});
4357

4458
expect(instructions).toEqual([
45-
'See https://angular.dev/best-practices for Angular best practices. You can call this tool if you have specific transformation you want to run.',
59+
'See https://angular.dev/best-practices for Angular best practices. You can call this ' +
60+
'tool if you have specific transformation you want to run.',
4661
]);
4762
});
4863

@@ -51,7 +66,7 @@ describe('Modernize Tool', () => {
5166
transformations: ['standalone'],
5267
});
5368

54-
expect(instructions![0]).toContain(
69+
expect(instructions?.[0]).toContain(
5570
'Run the commands in the order listed below, verifying that your code builds and runs between each step:',
5671
);
5772
});

0 commit comments

Comments
 (0)