@ng-annotate/angular 0.2.4 → 0.2.6

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 ADDED
@@ -0,0 +1,97 @@
1
+ # @ng-annotate/angular
2
+
3
+ Angular library for [ng-annotate-mcp](https://github.com/yngvebn/ngagentify) — a dev-only toolchain addon that lets you annotate components directly in the browser and have an AI agent (Claude) act on those annotations in real time.
4
+
5
+ ## How it works
6
+
7
+ 1. Press `Alt+Shift+A` in the browser to enter inspect mode
8
+ 2. Click any component and type an annotation (instruction for the agent)
9
+ 3. The agent reads the annotation via MCP, edits the relevant files, and resolves it
10
+ 4. The browser hot-reloads automatically
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ ng add @ng-annotate/angular
16
+ ```
17
+
18
+ The schematic configures everything automatically:
19
+ - Adds the Vite plugin to `vite.config.ts`
20
+ - Adds `provideNgAnnotate()` to `app.config.ts`
21
+ - Creates the MCP config file for your AI editor
22
+
23
+ ## Manual install
24
+
25
+ ```bash
26
+ npm install @ng-annotate/angular @ng-annotate/vite-plugin --save-dev
27
+ ```
28
+
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
+ });
37
+ ```
38
+
39
+ **`src/app/app.config.ts`**
40
+ ```ts
41
+ import { ApplicationConfig } from '@angular/core';
42
+ import { provideNgAnnotate } from '@ng-annotate/angular';
43
+
44
+ export const appConfig: ApplicationConfig = {
45
+ providers: [
46
+ provideNgAnnotate(),
47
+ ],
48
+ };
49
+ ```
50
+
51
+ No template changes needed — the overlay is injected automatically.
52
+
53
+ ## Keyboard shortcuts
54
+
55
+ | Shortcut | Action |
56
+ |---|---|
57
+ | `Alt+Shift+A` | Toggle inspect mode |
58
+ | Click component | Open annotation panel |
59
+ | `Esc` | Cancel / go back |
60
+
61
+ ## API
62
+
63
+ ### `provideNgAnnotate()`
64
+
65
+ Standalone providers function for Angular 21+. Registers `InspectorService`, `BridgeService`, and dynamically mounts the overlay component to `document.body` during app initialization. Only active in dev mode.
66
+
67
+ ```ts
68
+ import { provideNgAnnotate } from '@ng-annotate/angular';
69
+
70
+ export const appConfig: ApplicationConfig = {
71
+ providers: [provideNgAnnotate()],
72
+ };
73
+ ```
74
+
75
+ ### `NgAnnotateModule`
76
+
77
+ For NgModule-based apps:
78
+
79
+ ```ts
80
+ import { NgAnnotateModule } from '@ng-annotate/angular';
81
+
82
+ @NgModule({
83
+ imports: [NgAnnotateModule],
84
+ })
85
+ export class AppModule {}
86
+ ```
87
+
88
+ ## Related packages
89
+
90
+ | Package | Purpose |
91
+ |---|---|
92
+ | [`@ng-annotate/vite-plugin`](https://www.npmjs.com/package/@ng-annotate/vite-plugin) | Vite plugin (WebSocket server, component manifest) |
93
+ | [`@ng-annotate/mcp-server`](https://www.npmjs.com/package/@ng-annotate/mcp-server) | MCP server exposing tools to the AI agent |
94
+
95
+ ## License
96
+
97
+ MIT
package/dist/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # @ng-annotate/angular
2
+
3
+ Angular library for [ng-annotate-mcp](https://github.com/yngvebn/ngagentify) — a dev-only toolchain addon that lets you annotate components directly in the browser and have an AI agent (Claude) act on those annotations in real time.
4
+
5
+ ## How it works
6
+
7
+ 1. Press `Alt+Shift+A` in the browser to enter inspect mode
8
+ 2. Click any component and type an annotation (instruction for the agent)
9
+ 3. The agent reads the annotation via MCP, edits the relevant files, and resolves it
10
+ 4. The browser hot-reloads automatically
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ ng add @ng-annotate/angular
16
+ ```
17
+
18
+ The schematic configures everything automatically:
19
+ - Adds the Vite plugin to `vite.config.ts`
20
+ - Adds `provideNgAnnotate()` to `app.config.ts`
21
+ - Creates the MCP config file for your AI editor
22
+
23
+ ## Manual install
24
+
25
+ ```bash
26
+ npm install @ng-annotate/angular @ng-annotate/vite-plugin --save-dev
27
+ ```
28
+
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
+ });
37
+ ```
38
+
39
+ **`src/app/app.config.ts`**
40
+ ```ts
41
+ import { ApplicationConfig } from '@angular/core';
42
+ import { provideNgAnnotate } from '@ng-annotate/angular';
43
+
44
+ export const appConfig: ApplicationConfig = {
45
+ providers: [
46
+ provideNgAnnotate(),
47
+ ],
48
+ };
49
+ ```
50
+
51
+ No template changes needed — the overlay is injected automatically.
52
+
53
+ ## Keyboard shortcuts
54
+
55
+ | Shortcut | Action |
56
+ |---|---|
57
+ | `Alt+Shift+A` | Toggle inspect mode |
58
+ | Click component | Open annotation panel |
59
+ | `Esc` | Cancel / go back |
60
+
61
+ ## API
62
+
63
+ ### `provideNgAnnotate()`
64
+
65
+ Standalone providers function for Angular 21+. Registers `InspectorService`, `BridgeService`, and dynamically mounts the overlay component to `document.body` during app initialization. Only active in dev mode.
66
+
67
+ ```ts
68
+ import { provideNgAnnotate } from '@ng-annotate/angular';
69
+
70
+ export const appConfig: ApplicationConfig = {
71
+ providers: [provideNgAnnotate()],
72
+ };
73
+ ```
74
+
75
+ ### `NgAnnotateModule`
76
+
77
+ For NgModule-based apps:
78
+
79
+ ```ts
80
+ import { NgAnnotateModule } from '@ng-annotate/angular';
81
+
82
+ @NgModule({
83
+ imports: [NgAnnotateModule],
84
+ })
85
+ export class AppModule {}
86
+ ```
87
+
88
+ ## Related packages
89
+
90
+ | Package | Purpose |
91
+ |---|---|
92
+ | [`@ng-annotate/vite-plugin`](https://www.npmjs.com/package/@ng-annotate/vite-plugin) | Vite plugin (WebSocket server, component manifest) |
93
+ | [`@ng-annotate/mcp-server`](https://www.npmjs.com/package/@ng-annotate/mcp-server) | MCP server exposing tools to the AI agent |
94
+
95
+ ## License
96
+
97
+ MIT
package/package.json CHANGED
@@ -1,14 +1,25 @@
1
1
  {
2
2
  "name": "@ng-annotate/angular",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "schematics": "./schematics/collection.json",
5
+ "description": "Angular library for ng-annotate-mcp — browser overlay for annotating components and routing instructions to an AI agent",
6
+ "keywords": [
7
+ "angular",
8
+ "mcp",
9
+ "ai",
10
+ "devtools",
11
+ "ng-annotate",
12
+ "ng-add",
13
+ "schematics"
14
+ ],
5
15
  "repository": {
6
16
  "type": "git",
7
17
  "url": "https://github.com/yngvebn/ngagentify"
8
18
  },
9
19
  "files": [
10
20
  "dist",
11
- "schematics"
21
+ "schematics",
22
+ "README.md"
12
23
  ],
13
24
  "main": "dist/fesm2022/ng-annotate-angular.mjs",
14
25
  "module": "dist/fesm2022/ng-annotate-angular.mjs",
@@ -3,7 +3,8 @@
3
3
  "schematics": {
4
4
  "ng-add": {
5
5
  "description": "Add ng-annotate-mcp to the Angular project.",
6
- "factory": "./ng-add/index"
6
+ "factory": "./ng-add/index",
7
+ "schema": "./ng-add/schema.json"
7
8
  }
8
9
  }
9
10
  }
@@ -69,22 +69,77 @@ function addProviders() {
69
69
  context.logger.info(`✅ Added provideNgAnnotate() to ${appConfigPath}`);
70
70
  };
71
71
  }
72
- function addMcpConfig() {
72
+ function addMcpConfig(options) {
73
73
  return (tree, context) => {
74
- if (tree.exists('.mcp.json')) {
75
- context.logger.info('.mcp.json already exists, skipping.');
74
+ const projectRoot = process.cwd().replace(/\\/g, '/');
75
+ const env = { NG_ANNOTATE_PROJECT_ROOT: projectRoot };
76
+ const isWindows = process.platform === 'win32';
77
+ const { aiTool } = options;
78
+ if (aiTool === 'other') {
79
+ const claudeConfig = JSON.stringify({
80
+ mcpServers: {
81
+ 'ng-annotate': isWindows
82
+ ? { command: 'cmd', args: ['/c', 'npx', '-y', '@ng-annotate/mcp-server'], env }
83
+ : { command: 'npx', args: ['-y', '@ng-annotate/mcp-server'], env },
84
+ },
85
+ }, null, 2);
86
+ const vscodeConfig = JSON.stringify({
87
+ servers: {
88
+ 'ng-annotate': {
89
+ type: 'stdio',
90
+ command: 'npx',
91
+ args: ['-y', '@ng-annotate/mcp-server'],
92
+ env,
93
+ },
94
+ },
95
+ }, null, 2);
96
+ context.logger.info('\n⚙️ Manual MCP configuration:\n\n' +
97
+ 'For Claude Code (.mcp.json):\n' +
98
+ claudeConfig +
99
+ '\n\n' +
100
+ 'For VS Code Copilot (.vscode/mcp.json):\n' +
101
+ vscodeConfig +
102
+ '\n');
76
103
  return;
77
104
  }
78
- const mcpConfig = {
79
- mcpServers: {
80
- 'ng-annotate': {
81
- command: 'npx',
82
- args: ['-y', '@ng-annotate/mcp-server'],
83
- },
84
- },
85
- };
86
- tree.create('.mcp.json', JSON.stringify(mcpConfig, null, 2) + '\n');
87
- context.logger.info('✅ Created .mcp.json');
105
+ // .mcp.json Claude Code (needs cmd /c on Windows to invoke npx.cmd)
106
+ if (aiTool === 'claude-code' || aiTool === 'both') {
107
+ if (!tree.exists('.mcp.json')) {
108
+ const mcpConfig = {
109
+ mcpServers: {
110
+ 'ng-annotate': isWindows
111
+ ? { command: 'cmd', args: ['/c', 'npx', '-y', '@ng-annotate/mcp-server'], env }
112
+ : { command: 'npx', args: ['-y', '@ng-annotate/mcp-server'], env },
113
+ },
114
+ };
115
+ tree.create('.mcp.json', JSON.stringify(mcpConfig, null, 2) + '\n');
116
+ context.logger.info('✅ Created .mcp.json');
117
+ }
118
+ else {
119
+ context.logger.info('.mcp.json already exists, skipping.');
120
+ }
121
+ }
122
+ // .vscode/mcp.json — VS Code Copilot
123
+ if (aiTool === 'vscode' || aiTool === 'both') {
124
+ const vscodeMcpPath = '.vscode/mcp.json';
125
+ if (!tree.exists(vscodeMcpPath)) {
126
+ const vscodeMcpConfig = {
127
+ servers: {
128
+ 'ng-annotate': {
129
+ type: 'stdio',
130
+ command: 'npx',
131
+ args: ['-y', '@ng-annotate/mcp-server'],
132
+ env,
133
+ },
134
+ },
135
+ };
136
+ tree.create(vscodeMcpPath, JSON.stringify(vscodeMcpConfig, null, 2) + '\n');
137
+ context.logger.info('✅ Created .vscode/mcp.json');
138
+ }
139
+ else {
140
+ context.logger.info('.vscode/mcp.json already exists, skipping.');
141
+ }
142
+ }
88
143
  };
89
144
  }
90
145
  function addDevDependency() {
@@ -94,17 +149,32 @@ function addDevDependency() {
94
149
  return;
95
150
  const pkg = JSON.parse(tree.read(pkgPath).toString('utf-8'));
96
151
  pkg['devDependencies'] ?? (pkg['devDependencies'] = {});
152
+ let changed = false;
97
153
  if (!pkg['devDependencies']['@ng-annotate/vite-plugin']) {
98
154
  pkg['devDependencies']['@ng-annotate/vite-plugin'] = 'latest';
155
+ changed = true;
156
+ context.logger.info('✅ Added @ng-annotate/vite-plugin to devDependencies');
157
+ }
158
+ if (!pkg['devDependencies']['@ng-annotate/mcp-server']) {
159
+ pkg['devDependencies']['@ng-annotate/mcp-server'] = 'latest';
160
+ changed = true;
161
+ context.logger.info('✅ Added @ng-annotate/mcp-server to devDependencies');
162
+ }
163
+ if (changed) {
99
164
  tree.overwrite(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
100
165
  context.addTask(new tasks_1.NodePackageInstallTask());
101
- context.logger.info('✅ Added @ng-annotate/vite-plugin to devDependencies');
102
166
  }
103
167
  };
104
168
  }
105
- function default_1() {
169
+ function default_1(options) {
106
170
  return (tree, context) => {
107
- context.logger.info('Setting up @ng-annotate/vite-plugin...');
108
- return (0, schematics_1.chain)([checkAngularVersion(), addDevDependency(), addVitePlugin(), addProviders(), addMcpConfig()])(tree, context);
171
+ context.logger.info('Setting up @ng-annotate...');
172
+ return (0, schematics_1.chain)([
173
+ checkAngularVersion(),
174
+ addDevDependency(),
175
+ addVitePlugin(),
176
+ addProviders(),
177
+ addMcpConfig(options),
178
+ ])(tree, context);
109
179
  };
110
180
  }
@@ -1,6 +1,10 @@
1
1
  import { Rule, SchematicContext, Tree, chain, SchematicsException } from '@angular-devkit/schematics';
2
2
  import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
3
3
 
4
+ interface Options {
5
+ aiTool: 'claude-code' | 'vscode' | 'both' | 'other';
6
+ }
7
+
4
8
  const MIN_ANGULAR_MAJOR = 21;
5
9
 
6
10
  function checkAngularVersion(): Rule {
@@ -100,24 +104,88 @@ function addProviders(): Rule {
100
104
  };
101
105
  }
102
106
 
103
- function addMcpConfig(): Rule {
107
+ function addMcpConfig(options: Options): Rule {
104
108
  return (tree: Tree, context: SchematicContext) => {
105
- if (tree.exists('.mcp.json')) {
106
- context.logger.info('.mcp.json already exists, skipping.');
109
+ const projectRoot = process.cwd().replace(/\\/g, '/');
110
+ const env = { NG_ANNOTATE_PROJECT_ROOT: projectRoot };
111
+ const isWindows = process.platform === 'win32';
112
+ const { aiTool } = options;
113
+
114
+ if (aiTool === 'other') {
115
+ const claudeConfig = JSON.stringify(
116
+ {
117
+ mcpServers: {
118
+ 'ng-annotate': isWindows
119
+ ? { command: 'cmd', args: ['/c', 'npx', '-y', '@ng-annotate/mcp-server'], env }
120
+ : { command: 'npx', args: ['-y', '@ng-annotate/mcp-server'], env },
121
+ },
122
+ },
123
+ null,
124
+ 2,
125
+ );
126
+ const vscodeConfig = JSON.stringify(
127
+ {
128
+ servers: {
129
+ 'ng-annotate': {
130
+ type: 'stdio',
131
+ command: 'npx',
132
+ args: ['-y', '@ng-annotate/mcp-server'],
133
+ env,
134
+ },
135
+ },
136
+ },
137
+ null,
138
+ 2,
139
+ );
140
+ context.logger.info(
141
+ '\n⚙️ Manual MCP configuration:\n\n' +
142
+ 'For Claude Code (.mcp.json):\n' +
143
+ claudeConfig +
144
+ '\n\n' +
145
+ 'For VS Code Copilot (.vscode/mcp.json):\n' +
146
+ vscodeConfig +
147
+ '\n',
148
+ );
107
149
  return;
108
150
  }
109
151
 
110
- const mcpConfig = {
111
- mcpServers: {
112
- 'ng-annotate': {
113
- command: 'npx',
114
- args: ['-y', '@ng-annotate/mcp-server'],
115
- },
116
- },
117
- };
152
+ // .mcp.json Claude Code (needs cmd /c on Windows to invoke npx.cmd)
153
+ if (aiTool === 'claude-code' || aiTool === 'both') {
154
+ if (!tree.exists('.mcp.json')) {
155
+ const mcpConfig = {
156
+ mcpServers: {
157
+ 'ng-annotate': isWindows
158
+ ? { command: 'cmd', args: ['/c', 'npx', '-y', '@ng-annotate/mcp-server'], env }
159
+ : { command: 'npx', args: ['-y', '@ng-annotate/mcp-server'], env },
160
+ },
161
+ };
162
+ tree.create('.mcp.json', JSON.stringify(mcpConfig, null, 2) + '\n');
163
+ context.logger.info('✅ Created .mcp.json');
164
+ } else {
165
+ context.logger.info('.mcp.json already exists, skipping.');
166
+ }
167
+ }
118
168
 
119
- tree.create('.mcp.json', JSON.stringify(mcpConfig, null, 2) + '\n');
120
- context.logger.info(' Created .mcp.json');
169
+ // .vscode/mcp.json VS Code Copilot
170
+ if (aiTool === 'vscode' || aiTool === 'both') {
171
+ const vscodeMcpPath = '.vscode/mcp.json';
172
+ if (!tree.exists(vscodeMcpPath)) {
173
+ const vscodeMcpConfig = {
174
+ servers: {
175
+ 'ng-annotate': {
176
+ type: 'stdio',
177
+ command: 'npx',
178
+ args: ['-y', '@ng-annotate/mcp-server'],
179
+ env,
180
+ },
181
+ },
182
+ };
183
+ tree.create(vscodeMcpPath, JSON.stringify(vscodeMcpConfig, null, 2) + '\n');
184
+ context.logger.info('✅ Created .vscode/mcp.json');
185
+ } else {
186
+ context.logger.info('.vscode/mcp.json already exists, skipping.');
187
+ }
188
+ }
121
189
  };
122
190
  }
123
191
 
@@ -132,21 +200,36 @@ function addDevDependency(): Rule {
132
200
  >;
133
201
  pkg['devDependencies'] ??= {};
134
202
 
203
+ let changed = false;
204
+
135
205
  if (!pkg['devDependencies']['@ng-annotate/vite-plugin']) {
136
206
  pkg['devDependencies']['@ng-annotate/vite-plugin'] = 'latest';
207
+ changed = true;
208
+ context.logger.info('✅ Added @ng-annotate/vite-plugin to devDependencies');
209
+ }
210
+
211
+ if (!pkg['devDependencies']['@ng-annotate/mcp-server']) {
212
+ pkg['devDependencies']['@ng-annotate/mcp-server'] = 'latest';
213
+ changed = true;
214
+ context.logger.info('✅ Added @ng-annotate/mcp-server to devDependencies');
215
+ }
216
+
217
+ if (changed) {
137
218
  tree.overwrite(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
138
219
  context.addTask(new NodePackageInstallTask());
139
- context.logger.info('✅ Added @ng-annotate/vite-plugin to devDependencies');
140
220
  }
141
221
  };
142
222
  }
143
223
 
144
- export default function (): Rule {
224
+ export default function (options: Options): Rule {
145
225
  return (tree: Tree, context: SchematicContext) => {
146
- context.logger.info('Setting up @ng-annotate/vite-plugin...');
147
- return chain([checkAngularVersion(), addDevDependency(), addVitePlugin(), addProviders(), addMcpConfig()])(
148
- tree,
149
- context,
150
- );
226
+ context.logger.info('Setting up @ng-annotate...');
227
+ return chain([
228
+ checkAngularVersion(),
229
+ addDevDependency(),
230
+ addVitePlugin(),
231
+ addProviders(),
232
+ addMcpConfig(options),
233
+ ])(tree, context);
151
234
  };
152
235
  }
@@ -0,0 +1,26 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema",
3
+ "$id": "SchematicsNgAnnotateNgAdd",
4
+ "title": "ng-annotate ng-add options",
5
+ "type": "object",
6
+ "description": "Adds @ng-annotate/angular to an Angular project",
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "aiTool": {
10
+ "type": "string",
11
+ "description": "Which AI tool will use the MCP server?",
12
+ "enum": ["claude-code", "vscode", "both", "other"],
13
+ "x-prompt": {
14
+ "message": "Which AI tool will use the ng-annotate MCP server?",
15
+ "type": "list",
16
+ "items": [
17
+ { "value": "claude-code", "label": "Claude Code (generates .mcp.json)" },
18
+ { "value": "vscode", "label": "VS Code Copilot (generates .vscode/mcp.json)" },
19
+ { "value": "both", "label": "Both" },
20
+ { "value": "other", "label": "Other — show manual config instructions" }
21
+ ]
22
+ }
23
+ }
24
+ },
25
+ "required": ["aiTool"]
26
+ }