@ng-annotate/angular 0.5.0 → 0.5.2

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/README.md CHANGED
@@ -16,24 +16,31 @@ ng add @ng-annotate/angular
16
16
  ```
17
17
 
18
18
  The schematic configures everything automatically:
19
- - Adds the Vite plugin to `vite.config.ts`
19
+ - Switches the Angular dev server to `@ng-annotate/angular:dev-server` (handles WebSocket + manifest injection — no separate config file or proxy needed)
20
20
  - Adds `provideNgAnnotate()` to `app.config.ts`
21
- - Creates the MCP config file for your AI editor
21
+ - Creates the MCP config file for your AI editor (`.mcp.json` for Claude Code, `.vscode/mcp.json` for VS Code, or both)
22
+
23
+ Works with both `@angular/build:dev-server` and the legacy `@angular-devkit/build-angular:dev-server` builder.
22
24
 
23
25
  ## Manual install
24
26
 
25
27
  ```bash
26
- npm install @ng-annotate/angular @ng-annotate/vite-plugin --save-dev
28
+ npm install @ng-annotate/angular --save-dev
27
29
  ```
28
30
 
29
- **`vite.config.ts`**
30
- ```ts
31
- import { defineConfig } from 'vite';
32
- import { ngAnnotateMcp } from '@ng-annotate/vite-plugin';
33
-
34
- export default defineConfig({
35
- plugins: [...ngAnnotateMcp()],
36
- });
31
+ **`angular.json`** — change the serve builder:
32
+ ```json
33
+ {
34
+ "projects": {
35
+ "your-app": {
36
+ "architect": {
37
+ "serve": {
38
+ "builder": "@ng-annotate/angular:dev-server"
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
37
44
  ```
38
45
 
39
46
  **`src/app/app.config.ts`**
@@ -56,7 +63,7 @@ Once installed:
56
63
 
57
64
  **1. Start the dev server**
58
65
  ```bash
59
- npm run dev
66
+ ng serve
60
67
  ```
61
68
 
62
69
  **2. Start the agent polling loop**
@@ -113,8 +120,8 @@ export class AppModule {}
113
120
 
114
121
  | Package | Purpose |
115
122
  |---|---|
116
- | [`@ng-annotate/vite-plugin`](https://www.npmjs.com/package/@ng-annotate/vite-plugin) | Vite plugin (WebSocket server, component manifest) |
117
123
  | [`@ng-annotate/mcp-server`](https://www.npmjs.com/package/@ng-annotate/mcp-server) | MCP server exposing tools to the AI agent |
124
+ | [`@ng-annotate/vite-plugin`](https://www.npmjs.com/package/@ng-annotate/vite-plugin) | For non-Angular-CLI Vite projects (Vue, Svelte, etc.) |
118
125
 
119
126
  ## License
120
127
 
package/dist/README.md CHANGED
@@ -16,24 +16,31 @@ ng add @ng-annotate/angular
16
16
  ```
17
17
 
18
18
  The schematic configures everything automatically:
19
- - Adds the Vite plugin to `vite.config.ts`
19
+ - Switches the Angular dev server to `@ng-annotate/angular:dev-server` (handles WebSocket + manifest injection — no separate config file or proxy needed)
20
20
  - Adds `provideNgAnnotate()` to `app.config.ts`
21
- - Creates the MCP config file for your AI editor
21
+ - Creates the MCP config file for your AI editor (`.mcp.json` for Claude Code, `.vscode/mcp.json` for VS Code, or both)
22
+
23
+ Works with both `@angular/build:dev-server` and the legacy `@angular-devkit/build-angular:dev-server` builder.
22
24
 
23
25
  ## Manual install
24
26
 
25
27
  ```bash
26
- npm install @ng-annotate/angular @ng-annotate/vite-plugin --save-dev
28
+ npm install @ng-annotate/angular --save-dev
27
29
  ```
28
30
 
29
- **`vite.config.ts`**
30
- ```ts
31
- import { defineConfig } from 'vite';
32
- import { ngAnnotateMcp } from '@ng-annotate/vite-plugin';
33
-
34
- export default defineConfig({
35
- plugins: [...ngAnnotateMcp()],
36
- });
31
+ **`angular.json`** — change the serve builder:
32
+ ```json
33
+ {
34
+ "projects": {
35
+ "your-app": {
36
+ "architect": {
37
+ "serve": {
38
+ "builder": "@ng-annotate/angular:dev-server"
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
37
44
  ```
38
45
 
39
46
  **`src/app/app.config.ts`**
@@ -56,7 +63,7 @@ Once installed:
56
63
 
57
64
  **1. Start the dev server**
58
65
  ```bash
59
- npm run dev
66
+ ng serve
60
67
  ```
61
68
 
62
69
  **2. Start the agent polling loop**
@@ -113,8 +120,8 @@ export class AppModule {}
113
120
 
114
121
  | Package | Purpose |
115
122
  |---|---|
116
- | [`@ng-annotate/vite-plugin`](https://www.npmjs.com/package/@ng-annotate/vite-plugin) | Vite plugin (WebSocket server, component manifest) |
117
123
  | [`@ng-annotate/mcp-server`](https://www.npmjs.com/package/@ng-annotate/mcp-server) | MCP server exposing tools to the AI agent |
124
+ | [`@ng-annotate/vite-plugin`](https://www.npmjs.com/package/@ng-annotate/vite-plugin) | For non-Angular-CLI Vite projects (Vue, Svelte, etc.) |
118
125
 
119
126
  ## License
120
127
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ng-annotate/angular",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "schematics": "./schematics/collection.json",
5
5
  "builders": "./builders.json",
6
6
  "description": "Angular library for ng-annotate-mcp — browser overlay for annotating components and routing instructions to an AI agent",
@@ -41,7 +41,13 @@ const path = __importStar(require("path"));
41
41
  const helpers_1 = require("./helpers");
42
42
  const MIN_ANGULAR_MAJOR = 21;
43
43
  const NG_ANNOTATE_BUILDER = '@ng-annotate/angular:dev-server';
44
- const ANGULAR_DEV_SERVER_BUILDER = '@angular/build:dev-server';
44
+ // Both builders use the same underlying implementation in Angular 17+.
45
+ // @angular-devkit/build-angular:dev-server is the legacy alias that many
46
+ // projects still have in their angular.json even on Angular 21.
47
+ const COMPATIBLE_DEV_SERVER_BUILDERS = [
48
+ '@angular/build:dev-server',
49
+ '@angular-devkit/build-angular:dev-server',
50
+ ];
45
51
  function checkAngularVersion() {
46
52
  return (tree) => {
47
53
  const pkgPath = 'package.json';
@@ -83,9 +89,9 @@ function updateAngularJsonBuilder() {
83
89
  context.logger.info(`ng-annotate builder already configured in ${projectName}, skipping.`);
84
90
  continue;
85
91
  }
86
- if (currentBuilder !== ANGULAR_DEV_SERVER_BUILDER) {
92
+ if (!COMPATIBLE_DEV_SERVER_BUILDERS.includes(currentBuilder ?? '')) {
87
93
  context.logger.warn(`⚠️ Project "${projectName}" uses builder "${String(currentBuilder)}" which is not ` +
88
- `"${ANGULAR_DEV_SERVER_BUILDER}". Skipping automatic builder update — ` +
94
+ `a compatible dev-server builder. Skipping automatic builder update — ` +
89
95
  `set it to "${NG_ANNOTATE_BUILDER}" manually if compatible.`);
90
96
  continue;
91
97
  }
@@ -239,8 +245,18 @@ function addDevDependency() {
239
245
  if (!tree.exists(pkgPath))
240
246
  return;
241
247
  const pkg = JSON.parse(tree.read(pkgPath).toString('utf-8'));
248
+ pkg['dependencies'] ?? (pkg['dependencies'] = {});
242
249
  pkg['devDependencies'] ?? (pkg['devDependencies'] = {});
243
250
  let changed = false;
251
+ // ng add installs @ng-annotate/angular into dependencies by default.
252
+ // Move it to devDependencies — it is a dev-only tool.
253
+ const ngAnnotateVersion = pkg['dependencies']['@ng-annotate/angular'];
254
+ if (ngAnnotateVersion && !pkg['devDependencies']['@ng-annotate/angular']) {
255
+ pkg['devDependencies']['@ng-annotate/angular'] = ngAnnotateVersion;
256
+ delete pkg['dependencies']['@ng-annotate/angular'];
257
+ changed = true;
258
+ context.logger.info('✅ Moved @ng-annotate/angular to devDependencies');
259
+ }
244
260
  if (!pkg['devDependencies']['@ng-annotate/mcp-server']) {
245
261
  pkg['devDependencies']['@ng-annotate/mcp-server'] = 'latest';
246
262
  changed = true;
@@ -97,6 +97,40 @@ function makeTree(files: Record<string, string>): Tree {
97
97
  return tree;
98
98
  }
99
99
 
100
+ // ─── addDevDependency ─────────────────────────────────────────────────────────
101
+
102
+ describe('ng-add schematic — addDevDependency', () => {
103
+ it('moves @ng-annotate/angular from dependencies to devDependencies', async () => {
104
+ const pkg = JSON.stringify({
105
+ dependencies: { '@angular/core': '^21.0.0', '@ng-annotate/angular': '^0.5.0' },
106
+ devDependencies: {},
107
+ });
108
+ const tree = makeTree({ 'package.json': pkg });
109
+ const result = await runSchematic(tree);
110
+ const parsed = JSON.parse(result.readText('package.json')) as Record<string, Record<string, string>>;
111
+ expect(parsed['devDependencies']['@ng-annotate/angular']).toBe('^0.5.0');
112
+ expect(parsed['dependencies']['@ng-annotate/angular']).toBeUndefined();
113
+ });
114
+
115
+ it('adds @ng-annotate/mcp-server to devDependencies', async () => {
116
+ const tree = makeTree({ 'package.json': BASE_PKG });
117
+ const result = await runSchematic(tree);
118
+ const parsed = JSON.parse(result.readText('package.json')) as Record<string, Record<string, string>>;
119
+ expect(parsed['devDependencies']['@ng-annotate/mcp-server']).toBe('latest');
120
+ });
121
+
122
+ it('skips @ng-annotate/mcp-server if already present', async () => {
123
+ const pkg = JSON.stringify({
124
+ dependencies: { '@angular/core': '^21.0.0' },
125
+ devDependencies: { '@ng-annotate/mcp-server': '^0.4.0' },
126
+ });
127
+ const tree = makeTree({ 'package.json': pkg });
128
+ const result = await runSchematic(tree);
129
+ const parsed = JSON.parse(result.readText('package.json')) as Record<string, Record<string, string>>;
130
+ expect(parsed['devDependencies']['@ng-annotate/mcp-server']).toBe('^0.4.0');
131
+ });
132
+ });
133
+
100
134
  // ─── updateAngularJsonBuilder ─────────────────────────────────────────────────
101
135
 
102
136
  describe('ng-add schematic — updateAngularJsonBuilder', () => {
@@ -130,6 +164,27 @@ describe('ng-add schematic — updateAngularJsonBuilder', () => {
130
164
  expect((serve['builder'] as string)).toBe('@ng-annotate/angular:dev-server');
131
165
  });
132
166
 
167
+ it('updates legacy @angular-devkit/build-angular:dev-server builder too', async () => {
168
+ const withLegacyBuilder = JSON.stringify({
169
+ projects: {
170
+ 'my-app': {
171
+ architect: {
172
+ serve: {
173
+ builder: '@angular-devkit/build-angular:dev-server',
174
+ options: {},
175
+ },
176
+ },
177
+ },
178
+ },
179
+ });
180
+ const tree = makeTree({ 'package.json': BASE_PKG, 'angular.json': withLegacyBuilder });
181
+ const result = await runSchematic(tree);
182
+ const angular = JSON.parse(result.readText('angular.json')) as Record<string, unknown>;
183
+ const projects = angular['projects'] as Record<string, Record<string, unknown>>;
184
+ const serve = (projects['my-app']['architect'] as Record<string, Record<string, unknown>>)['serve'];
185
+ expect((serve['builder'] as string)).toBe('@ng-annotate/angular:dev-server');
186
+ });
187
+
133
188
  it('warns but does not change unknown builders', async () => {
134
189
  const withCustomBuilder = JSON.stringify({
135
190
  projects: {
@@ -10,7 +10,14 @@ interface Options {
10
10
 
11
11
  const MIN_ANGULAR_MAJOR = 21;
12
12
  const NG_ANNOTATE_BUILDER = '@ng-annotate/angular:dev-server';
13
- const ANGULAR_DEV_SERVER_BUILDER = '@angular/build:dev-server';
13
+
14
+ // Both builders use the same underlying implementation in Angular 17+.
15
+ // @angular-devkit/build-angular:dev-server is the legacy alias that many
16
+ // projects still have in their angular.json even on Angular 21.
17
+ const COMPATIBLE_DEV_SERVER_BUILDERS = [
18
+ '@angular/build:dev-server',
19
+ '@angular-devkit/build-angular:dev-server',
20
+ ];
14
21
 
15
22
  function checkAngularVersion(): Rule {
16
23
  return (tree: Tree) => {
@@ -69,10 +76,10 @@ function updateAngularJsonBuilder(): Rule {
69
76
  continue;
70
77
  }
71
78
 
72
- if (currentBuilder !== ANGULAR_DEV_SERVER_BUILDER) {
79
+ if (!COMPATIBLE_DEV_SERVER_BUILDERS.includes(currentBuilder ?? '')) {
73
80
  context.logger.warn(
74
81
  `⚠️ Project "${projectName}" uses builder "${String(currentBuilder)}" which is not ` +
75
- `"${ANGULAR_DEV_SERVER_BUILDER}". Skipping automatic builder update — ` +
82
+ `a compatible dev-server builder. Skipping automatic builder update — ` +
76
83
  `set it to "${NG_ANNOTATE_BUILDER}" manually if compatible.`,
77
84
  );
78
85
  continue;
@@ -268,10 +275,21 @@ function addDevDependency(): Rule {
268
275
  string,
269
276
  Record<string, string>
270
277
  >;
278
+ pkg['dependencies'] ??= {};
271
279
  pkg['devDependencies'] ??= {};
272
280
 
273
281
  let changed = false;
274
282
 
283
+ // ng add installs @ng-annotate/angular into dependencies by default.
284
+ // Move it to devDependencies — it is a dev-only tool.
285
+ const ngAnnotateVersion = pkg['dependencies']['@ng-annotate/angular'];
286
+ if (ngAnnotateVersion && !pkg['devDependencies']['@ng-annotate/angular']) {
287
+ pkg['devDependencies']['@ng-annotate/angular'] = ngAnnotateVersion;
288
+ delete pkg['dependencies']['@ng-annotate/angular'];
289
+ changed = true;
290
+ context.logger.info('✅ Moved @ng-annotate/angular to devDependencies');
291
+ }
292
+
275
293
  if (!pkg['devDependencies']['@ng-annotate/mcp-server']) {
276
294
  pkg['devDependencies']['@ng-annotate/mcp-server'] = 'latest';
277
295
  changed = true;