Skip to content

Commit a9c700a

Browse files
authored
refactor(@angular/cli): import type improvements & mcp cleanups
1 parent 8a17fe8 commit a9c700a

30 files changed

+138
-136
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@
77
*/
88

99
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10-
import { Argv } from 'yargs';
11-
import { CommandModule, CommandModuleImplementation } from '../../command-builder/command-module';
10+
import type { Argv } from 'yargs';
11+
import {
12+
CommandModule,
13+
type CommandModuleImplementation,
14+
} from '../../command-builder/command-module';
1215
import { isTTY } from '../../utilities/tty';
1316
import { EXPERIMENTAL_TOOLS, createMcpServer } from './mcp-server';
1417

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import { ChildProcess } from 'child_process';
10-
import { Host } from './host';
9+
import type { ChildProcess } from 'child_process';
10+
import type { Host } from './host';
1111

1212
// Log messages that we want to catch to identify the build status.
1313

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

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

99
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
10-
import path from 'node:path';
10+
import { join } from 'node:path';
1111
import type { AngularWorkspace } from '../../utilities/config';
1212
import { VERSION } from '../../utilities/version';
13-
import { DevServer } from './dev-server';
13+
import type { DevServer } from './dev-server';
1414
import { registerInstructionsResource } from './resources/instructions';
1515
import { AI_TUTOR_TOOL } from './tools/ai-tutor';
1616
import { BEST_PRACTICES_TOOL } from './tools/best-practices';
@@ -23,7 +23,7 @@ import { FIND_EXAMPLE_TOOL } from './tools/examples';
2323
import { MODERNIZE_TOOL } from './tools/modernize';
2424
import { ZONELESS_MIGRATION_TOOL } from './tools/onpush-zoneless-migration/zoneless-migration';
2525
import { LIST_PROJECTS_TOOL } from './tools/projects';
26-
import { AnyMcpToolDeclaration, registerTools } from './tools/tool-registry';
26+
import { type AnyMcpToolDeclaration, registerTools } from './tools/tool-registry';
2727

2828
/**
2929
* Tools to manage devservers. Should be bundled together, then added to experimental or stable as a group.
@@ -113,7 +113,7 @@ equivalent actions.
113113
{
114114
workspace: options.workspace,
115115
logger,
116-
exampleDatabasePath: path.join(__dirname, '../../../lib/code-examples.db'),
116+
exampleDatabasePath: join(__dirname, '../../../lib/code-examples.db'),
117117
devServers: new Map<string, DevServer>(),
118118
},
119119
toolDeclarations,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
9+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
1010
import { readFile } from 'node:fs/promises';
11-
import path from 'node:path';
11+
import { join } from 'node:path';
1212

1313
export function registerInstructionsResource(server: McpServer): void {
1414
server.registerResource(
@@ -24,7 +24,7 @@ export function registerInstructionsResource(server: McpServer): void {
2424
mimeType: 'text/markdown',
2525
},
2626
async () => {
27-
const text = await readFile(path.join(__dirname, 'best-practices.md'), 'utf-8');
27+
const text = await readFile(join(__dirname, 'best-practices.md'), 'utf-8');
2828

2929
return { contents: [{ uri: 'instructions://best-practices', text }] };
3030
},

packages/angular/cli/src/commands/mcp/testing/mock-host.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import { Host } from '../host';
9+
import type { Host } from '../host';
1010

1111
/**
1212
* A mock implementation of the `Host` interface for testing purposes.

packages/angular/cli/src/commands/mcp/tools/ai-tutor.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import { readFile } from 'node:fs/promises';
10-
import path from 'node:path';
10+
import { join } from 'node:path';
1111
import { declareTool } from './tool-registry';
1212

1313
export const AI_TUTOR_TOOL = declareTool({
@@ -40,10 +40,7 @@ with a new core identity and knowledge base.
4040
let aiTutorText: string;
4141

4242
return async () => {
43-
aiTutorText ??= await readFile(
44-
path.join(__dirname, '..', 'resources', 'ai-tutor.md'),
45-
'utf-8',
46-
);
43+
aiTutorText ??= await readFile(join(__dirname, '../resources/ai-tutor.md'), 'utf-8');
4744

4845
return {
4946
content: [

packages/angular/cli/src/commands/mcp/tools/best-practices.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717

1818
import { readFile, stat } from 'node:fs/promises';
1919
import { createRequire } from 'node:module';
20-
import path from 'node:path';
20+
import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
2121
import { z } from 'zod';
2222
import { VERSION } from '../../../utilities/version';
23-
import { McpToolContext, declareTool } from './tool-registry';
23+
import { type McpToolContext, declareTool } from './tool-registry';
2424

2525
const bestPracticesInputSchema = z.object({
2626
workspacePath: z
@@ -72,7 +72,7 @@ that **MUST** be followed for any task involving the creation, analysis, or modi
7272
* @returns A promise that resolves to the string content of the bundled markdown file.
7373
*/
7474
async function getBundledBestPractices(): Promise<string> {
75-
return readFile(path.join(__dirname, '..', 'resources', 'best-practices.md'), 'utf-8');
75+
return readFile(join(__dirname, '../resources/best-practices.md'), 'utf-8');
7676
}
7777

7878
/**
@@ -126,14 +126,14 @@ async function getVersionSpecificBestPractices(
126126
bestPracticesInfo.format === 'markdown' &&
127127
typeof bestPracticesInfo.path === 'string'
128128
) {
129-
const packageDirectory = path.dirname(pkgJsonPath);
130-
const guidePath = path.resolve(packageDirectory, bestPracticesInfo.path);
129+
const packageDirectory = dirname(pkgJsonPath);
130+
const guidePath = resolve(packageDirectory, bestPracticesInfo.path);
131131

132132
// Ensure the resolved guide path is within the package boundary.
133133
// Uses path.relative to create a cross-platform, case-insensitive check.
134134
// If the relative path starts with '..' or is absolute, it is a traversal attempt.
135-
const relativePath = path.relative(packageDirectory, guidePath);
136-
if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {
135+
const relativePath = relative(packageDirectory, guidePath);
136+
if (relativePath.startsWith('..') || isAbsolute(relativePath)) {
137137
logger.warn(
138138
`Detected a potential path traversal attempt in '${pkgJsonPath}'. ` +
139139
`The path '${bestPracticesInfo.path}' escapes the package boundary. ` +

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
*/
88

99
import { z } from 'zod';
10-
import { CommandError, Host, LocalWorkspaceHost } from '../host';
10+
import { CommandError, type Host, LocalWorkspaceHost } from '../host';
1111
import { createStructuredContentOutput } from '../utils';
12-
import { McpToolDeclaration, declareTool } from './tool-registry';
12+
import { type McpToolDeclaration, declareTool } from './tool-registry';
1313

1414
const DEFAULT_CONFIGURATION = 'development';
1515

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import { CommandError, Host } from '../host';
10-
import { MockHost } from '../testing/mock-host';
10+
import type { MockHost } from '../testing/mock-host';
1111
import { runBuild } from './build';
1212

1313
describe('Build Tool', () => {
@@ -18,7 +18,7 @@ describe('Build Tool', () => {
1818
runCommand: jasmine.createSpy<Host['runCommand']>('runCommand').and.resolveTo({ logs: [] }),
1919
stat: jasmine.createSpy<Host['stat']>('stat'),
2020
existsSync: jasmine.createSpy<Host['existsSync']>('existsSync'),
21-
} as Partial<MockHost> as MockHost;
21+
} as MockHost;
2222
});
2323

2424
it('should construct the command correctly with default configuration', async () => {

packages/angular/cli/src/commands/mcp/tools/devserver/serve_spec.ts

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

99
import { EventEmitter } from 'events';
10-
import { ChildProcess } from 'node:child_process';
11-
import { MockHost } from '../../testing/mock-host';
12-
import { McpToolContext } from '../tool-registry';
10+
import type { ChildProcess } from 'node:child_process';
11+
import type { MockHost } from '../../testing/mock-host';
12+
import type { McpToolContext } from '../tool-registry';
1313
import { startDevServer } from './start-devserver';
1414
import { stopDevserver } from './stop-devserver';
1515
import { WATCH_DELAY, waitForDevserverBuild } from './wait-for-devserver-build';
@@ -34,7 +34,7 @@ describe('Serve Tools', () => {
3434
getAvailablePort: jasmine.createSpy('getAvailablePort').and.callFake(() => {
3535
return Promise.resolve(portCounter++);
3636
}),
37-
} as Partial<MockHost> as MockHost;
37+
} as MockHost;
3838

3939
mockContext = {
4040
devServers: new Map(),

0 commit comments

Comments
 (0)