Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,11 @@ my-angular-workspace/

### Component Analysis

- **`report-violations`**: Report deprecated CSS usage in a directory with configurable grouping format
- **`report-violations`**: Report deprecated CSS usage for a specific component in a directory. Supports optional file output with statistics.

- **`report-all-violations`**: Report all deprecated CSS usage across all components in a directory. Supports optional file output with statistics.

- **`group-violations`**: Creates balanced work distribution groups from violations reports using bin-packing algorithm. Maintains path exclusivity and directory boundaries for parallel development.

- **`report-deprecated-css`**: Report deprecated CSS classes found in styling files

Expand Down
48 changes: 35 additions & 13 deletions docs/tools.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
# Design System Tools for AI Agents
# Angular MCP Tools for AI Agents

This document provides comprehensive guidance for AI agents working with Angular Design System (DS) migration and analysis tools. Each tool is designed to support automated refactoring, validation, and analysis workflows.
This document provides comprehensive guidance for AI agents working with Angular migration and analysis tools. Each tool is designed to support automated refactoring, validation, and analysis workflows.

## Tool Categories

### 🔍 Project Analysis Tools

#### `report-violations`
**Purpose**: Identifies deprecated DS CSS usage patterns in Angular projects
**AI Usage**: Use as the first step in migration workflows to identify all violations before planning refactoring
**Purpose**: Identifies deprecated CSS usage patterns for a specific component in Angular projects
**AI Usage**: Use when you need to analyze violations for a specific component before planning refactoring
**Key Parameters**:
- `directory`: Target analysis directory (use relative paths like `./src/app`)
- `componentName`: DS component class name (e.g., `DsButton`)
- `componentName`: Component class name (e.g., `DsButton`)
- `groupBy`: `"file"` or `"folder"` for result organization
**Output**: Structured violation reports grouped by file or folder
**Best Practice**: Always run this before other migration tools to establish baseline
- `saveAsFile`: Optional boolean - if `true`, saves report to `tmp/.angular-toolkit-mcp/violations-report/<componentName>/<directory>-violations.json`
**Output**:
- Default: Structured violation reports grouped by file or folder
- With `saveAsFile: true`: File path and statistics (components, files, lines)
**Best Practice**: Use `saveAsFile: true` when you need to persist results for later processing or grouping workflows

#### `report-all-violations`
**Purpose**: Reports all deprecated DS CSS usage for every DS component within a directory
**Purpose**: Reports all deprecated CSS usage for every component within a directory
**AI Usage**: Use for a fast, global inventory of violations across the codebase before narrowing to specific components
**Key Parameters**:
- `directory`: Target analysis directory (use relative paths like `./src/app`)
- `groupBy`: `"file"` or `"folder"` for result organization (default: `"file"`)
**Output**: Structured violation reports grouped by file or folder covering all DS components
**Best Practice**: Use to discover all violations and establish the baseline for subsequent refactoring.
- `groupBy`: `"component"` or `"file"` for result organization (default: `"component"`)
- `saveAsFile`: Optional boolean - if `true`, saves report to `tmp/.angular-toolkit-mcp/violations-report/<directory>-violations.json`
**Output**:
- Default: Structured violation reports grouped by component or file covering all components
- With `saveAsFile: true`: File path and statistics (components, files, lines)
**Best Practice**: Use `saveAsFile: true` to persist results for grouping workflows or large-scale migration planning. The saved file can be used as input for work distribution grouping tools.

#### `get-project-dependencies`
**Purpose**: Analyzes project structure, dependencies, and buildability
Expand All @@ -34,6 +40,21 @@ This document provides comprehensive guidance for AI agents working with Angular
**Output**: Dependency analysis, buildable/publishable status, peer dependencies
**Best Practice**: Use to understand project constraints before recommending changes

#### `group-violations`
**Purpose**: Creates balanced work distribution groups from violations reports for parallel development
**AI Usage**: Use after `report-all-violations` to organize violations into balanced work groups for team distribution
**Key Parameters**:
- `fileName`: Name of violations JSON file in `tmp/.angular-toolkit-mcp/violations-report/` (e.g., `"packages-poker-core-lib-violations.json"`)
- `minGroups`: Minimum number of groups (default: 3)
- `maxGroups`: Maximum number of groups (default: 5)
- `variance`: Acceptable variance percentage for balance (default: 20)
**Output**:
- Work groups with balanced violation counts
- Individual JSON and Markdown files per group
- Metadata with validation results
- Saved to `tmp/.angular-toolkit-mcp/violation-groups/<reportName>/`
**Best Practice**: Use after saving violations with `saveAsFile: true`. The tool accepts both component-grouped and file-grouped reports. Groups maintain path exclusivity (each file in exactly one group) and preserve directory boundaries to enable parallel development without merge conflicts.

#### `report-deprecated-css`
**Purpose**: Scans styling files for deprecated CSS classes
**AI Usage**: Complement violation reports with style-specific analysis
Expand Down Expand Up @@ -147,8 +168,9 @@ This document provides comprehensive guidance for AI agents working with Angular
### 1. Discovery & Analysis Workflow
```
1. list-ds-components → Discover available DS components
2. report-violations → Identify all violations
3. get-project-dependencies → Analyze project structure
2. report-all-violations (saveAsFile: true) → Identify all violations and save to file
3. group-violations → Create balanced work distribution groups
4. get-project-dependencies → Analyze project structure
```

### 2. Planning & Preparation Workflow
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ import { buildComponentContract } from './utils/build-contract.js';
import { generateContractSummary } from '../shared/utils/contract-file-ops.js';
import { ContractResult } from './models/types.js';
import { resolveCrossPlatformPath } from '../../shared/utils/cross-platform-path.js';
import {
OUTPUT_SUBDIRS,
resolveDefaultSaveLocation,
} from '../../shared/constants.js';
import { createHash } from 'node:crypto';
import { dirname } from 'node:path';
import { mkdir, writeFile } from 'node:fs/promises';

interface BuildComponentContractOptions extends BaseHandlerOptions {
saveLocation: string;
saveLocation?: string;
templateFile?: string;
styleFile?: string;
typescriptFile: string;
Expand All @@ -36,6 +42,13 @@ export const buildComponentContractHandler = createHandler<
typescriptFile,
);

const defaultSaveLocation = resolveDefaultSaveLocation(
saveLocation,
OUTPUT_SUBDIRS.CONTRACTS,
typescriptFile,
'-contract.json',
);

// If templateFile or styleFile are not provided, use the TypeScript file path
// This indicates inline template/styles
const effectiveTemplatePath = templateFile
Expand All @@ -55,10 +68,11 @@ export const buildComponentContractHandler = createHandler<
const contractString = JSON.stringify(contract, null, 2);
const hash = createHash('sha256').update(contractString).digest('hex');

const effectiveSaveLocation = resolveCrossPlatformPath(cwd, saveLocation);
const effectiveSaveLocation = resolveCrossPlatformPath(
cwd,
defaultSaveLocation,
);

const { mkdir, writeFile } = await import('node:fs/promises');
const { dirname } = await import('node:path');
await mkdir(dirname(effectiveSaveLocation), { recursive: true });

const contractData = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { ToolSchemaOptions } from '@push-based/models';
import { COMMON_ANNOTATIONS } from '../../../shared/index.js';
import {
COMMON_ANNOTATIONS,
DEFAULT_OUTPUT_BASE,
OUTPUT_SUBDIRS,
} from '../../../shared/index.js';

/**
* Schema for building component contracts
Expand All @@ -13,8 +17,7 @@ export const buildComponentContractSchema: ToolSchemaOptions = {
properties: {
saveLocation: {
type: 'string',
description:
'Path where to save the contract file. Supports both absolute and relative paths.',
description: `Path where to save the contract file. Supports both absolute and relative paths. If not provided, defaults to ${DEFAULT_OUTPUT_BASE}/${OUTPUT_SUBDIRS.CONTRACTS}/<component-name>-contract.json. When building contracts for comparison, use descriptive names like <component-name>-before-contract.json or <component-name>-after-contract.json to distinguish between refactoring phases.`,
},
templateFile: {
type: 'string',
Expand All @@ -37,7 +40,7 @@ export const buildComponentContractSchema: ToolSchemaOptions = {
default: '',
},
},
required: ['saveLocation', 'typescriptFile'],
required: ['typescriptFile'],
},
annotations: {
title: 'Build Component Contract',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import {
resolveCrossPlatformPath,
normalizePathsInObject,
} from '../../shared/utils/cross-platform-path.js';
import {
OUTPUT_SUBDIRS,
resolveDefaultSaveLocation,
} from '../../shared/constants.js';
import { diffComponentContractSchema } from './models/schema.js';
import type { DomPathDictionary } from '../shared/models/types.js';
import { loadContract } from '../shared/utils/contract-file-ops.js';
Expand All @@ -15,10 +19,11 @@ import {
generateDiffSummary,
} from './utils/diff-utils.js';
import { writeFile, mkdir } from 'node:fs/promises';
import { dirname } from 'node:path';
import diff from 'microdiff';

interface DiffComponentContractOptions extends BaseHandlerOptions {
saveLocation: string;
saveLocation?: string;
contractBeforePath: string;
contractAfterPath: string;
dsComponentName?: string;
Expand Down Expand Up @@ -46,6 +51,14 @@ export const diffComponentContractHandler = createHandler<
);
const effectiveAfterPath = resolveCrossPlatformPath(cwd, contractAfterPath);

const defaultSaveLocation = resolveDefaultSaveLocation(
saveLocation,
OUTPUT_SUBDIRS.CONTRACT_DIFFS,
contractBeforePath,
'-diff.json',
'-contract.json',
);

const contractBefore = await loadContract(effectiveBeforePath);
const contractAfter = await loadContract(effectiveAfterPath);

Expand All @@ -68,9 +81,11 @@ export const diffComponentContractHandler = createHandler<

const normalizedDiffData = normalizePathsInObject(diffData, workspaceRoot);

const effectiveSaveLocation = resolveCrossPlatformPath(cwd, saveLocation);
const effectiveSaveLocation = resolveCrossPlatformPath(
cwd,
defaultSaveLocation,
);

const { dirname } = await import('node:path');
await mkdir(dirname(effectiveSaveLocation), { recursive: true });

const diffFilePath = effectiveSaveLocation;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { ToolSchemaOptions } from '@push-based/models';
import { COMMON_ANNOTATIONS } from '../../../shared/index.js';
import {
COMMON_ANNOTATIONS,
DEFAULT_OUTPUT_BASE,
OUTPUT_SUBDIRS,
} from '../../../shared/index.js';

/**
* Schema for diffing component contracts
Expand All @@ -13,26 +17,23 @@ export const diffComponentContractSchema: ToolSchemaOptions = {
properties: {
saveLocation: {
type: 'string',
description:
'Path where to save the diff result file. Supports both absolute and relative paths.',
description: `Path where to save the diff result file. Supports both absolute and relative paths. If not provided, defaults to ${DEFAULT_OUTPUT_BASE}/${OUTPUT_SUBDIRS.CONTRACT_DIFFS}/<component-name>-diff.json`,
},
contractBeforePath: {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Contract diff has a default saveLocation path, would be good to have an unified approach to provide same default location for contractBefore-*/afterPath

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I improved schemas, but not sure we want to have explicit before/after folders.

type: 'string',
description:
'Path to the contract file before refactoring. Supports both absolute and relative paths.',
description: `Path to the contract file before refactoring. Supports both absolute and relative paths. Typically located at ${DEFAULT_OUTPUT_BASE}/${OUTPUT_SUBDIRS.CONTRACTS}/<component-name>-before-contract.json`,
},
contractAfterPath: {
type: 'string',
description:
'Path to the contract file after refactoring. Supports both absolute and relative paths.',
description: `Path to the contract file after refactoring. Supports both absolute and relative paths. Typically located at ${DEFAULT_OUTPUT_BASE}/${OUTPUT_SUBDIRS.CONTRACTS}/<component-name>-after-contract.json`,
},
dsComponentName: {
type: 'string',
description: 'The name of the design system component being used',
default: '',
},
},
required: ['saveLocation', 'contractBeforePath', 'contractAfterPath'],
required: ['contractBeforePath', 'contractAfterPath'],
},
annotations: {
title: 'Diff Component Contract',
Expand Down
2 changes: 2 additions & 0 deletions packages/angular-mcp-server/src/lib/tools/ds/ds.tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { join } from 'node:path';
import {
reportViolationsTools,
reportAllViolationsTools,
groupViolationsTools,
} from './report-violations/index.js';

export const componentCoverageToolsSchema: ToolSchemaOptions = {
Expand Down Expand Up @@ -137,4 +138,5 @@ export const dsTools = [
...componentCoverageTools,
...reportViolationsTools,
...reportAllViolationsTools,
...groupViolationsTools,
];
Loading
Loading