Skip to content

Commit 504e6e5

Browse files
committed
fixup! feat(@schematics/angular): update ai-config to include Angular MCP server config
1 parent 4490726 commit 504e6e5

4 files changed

Lines changed: 20 additions & 43 deletions

File tree

BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ exports_files([
1515
"tsconfig-build-ng.json",
1616
"tsconfig-build.json",
1717
"package.json",
18+
"node_modules/@angular/core/resources/best-practices.md",
1819
])
1920

2021
npm_link_all_packages()

packages/schematics/angular/BUILD.bazel

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# Use of this source code is governed by an MIT-style license that can be
44
# found in the LICENSE file at https://angular.dev/license
55

6+
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
67
load("@npm//:defs.bzl", "npm_link_all_packages")
78
load("//tools:defaults.bzl", "copy_to_bin", "jasmine_test", "npm_package", "ts_project")
89
load("//tools:ts_json_schema.bzl", "ts_json_schema")
@@ -45,15 +46,10 @@ copy_to_bin(
4546
srcs = glob(["**/schema.json"]),
4647
)
4748

48-
genrule(
49+
copy_file(
4950
name = "angular_best_practices",
50-
srcs = [
51-
"//:node_modules/@angular/core/dir",
52-
],
53-
outs = ["ai-config/files/__bestPracticesName__.template"],
54-
cmd = """
55-
cp "$(location //:node_modules/@angular/core/dir)/resources/best-practices.md" $@
56-
""",
51+
src = "//:node_modules/@angular/core/resources/best-practices.md",
52+
out = "ai-config/files/__bestPracticesName__.template",
5753
)
5854

5955
RUNTIME_ASSETS = [

packages/schematics/angular/ai-config/file_utils.ts

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import {
1818
strings,
1919
url,
2020
} from '@angular-devkit/schematics';
21+
import { parse } from 'jsonc-parser';
22+
import { JSONFile } from '../utility/json-file';
2123
import { FileConfigurationHandlerOptions } from './types';
2224

2325
const TOML_MCP_SERVERS_PROP = '[mcp_servers.angular-cli]';
@@ -26,7 +28,7 @@ const TOML_MCP_SERVERS_PROP = '[mcp_servers.angular-cli]';
2628
* Create or update a JSON MCP configuration file to include the Angular MCP server.
2729
*/
2830
export function addJsonMcpConfig(
29-
{ tree, context, fileInfo, tool }: FileConfigurationHandlerOptions,
31+
{ tree, fileInfo }: FileConfigurationHandlerOptions,
3032
mcpServersProperty: string,
3133
): Rule {
3234
const { name, directory } = fileInfo;
@@ -45,43 +47,18 @@ export function addJsonMcpConfig(
4547
return file;
4648
}
4749

48-
const existingFileBuffer = tree.read(file.path);
49-
5050
// If we have an existing file, update the server property with
5151
// Angular MCP server configuration.
52-
if (existingFileBuffer) {
53-
// The JSON config file should be record-like.
54-
let existing: Record<string, unknown>;
55-
try {
56-
existing = JSON.parse(existingFileBuffer.toString());
57-
} catch {
58-
const path = `${directory}/${name}`;
59-
const toolName = strings.classify(tool);
60-
context.logger.warn(
61-
`Skipping Angular MCP server configuration for '${toolName}'.\n` +
62-
`Unable to modify '${path}'. ` +
63-
'Make sure that the file has a valid JSON syntax.\n',
64-
);
52+
const existingConfig = new JSONFile(tree, file.path);
53+
const existingMcpServers = existingConfig.get([mcpServersProperty]) ?? {};
54+
const templateServersProp = parse(file.content.toString())[mcpServersProperty];
6555

66-
return null;
67-
}
68-
const existingServersProp = existing[mcpServersProperty];
69-
const templateServersProp = JSON.parse(file.content.toString())[mcpServersProperty];
70-
71-
// Note: If the Angular MCP server config already exists, we'll overwrite it.
72-
existing[mcpServersProperty] = existingServersProp
73-
? {
74-
...existingServersProp,
75-
...templateServersProp,
76-
}
77-
: templateServersProp;
78-
79-
tree.overwrite(file.path, JSON.stringify(existing, null, 2));
56+
existingConfig.modify([mcpServersProperty], {
57+
...existingMcpServers,
58+
...templateServersProp,
59+
});
8060

81-
return null;
82-
}
83-
84-
return file;
61+
return null;
8562
}),
8663
]),
8764
);

packages/schematics/angular/ai-config/index_spec.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
10+
import { parse } from 'jsonc-parser';
1011
import { Schema as WorkspaceOptions } from '../workspace/schema';
1112
import { Schema as ConfigOptions, Tool as ConfigTool } from './schema';
1213

@@ -129,7 +130,9 @@ describe('AI Config Schematic', () => {
129130
},
130131
};
131132

132-
expect(tree.readContent('.mcp.json')).toBe(JSON.stringify(modifiedConfig, null, 2));
133+
const actualConfig = parse(tree.readContent('.mcp.json'));
134+
135+
expect(JSON.stringify(actualConfig, null, 2)).toBe(JSON.stringify(modifiedConfig, null, 2));
133136
});
134137

135138
it('should handle invalid JSON MCP server config', async () => {

0 commit comments

Comments
 (0)