@gherk/reactive-architecture 1.3.2 → 1.4.1
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/dist/index.js +7 -11
- package/dist/index.js.map +1 -1
- package/dist/tools/create-feature.d.ts +3 -0
- package/dist/tools/create-feature.d.ts.map +1 -0
- package/dist/tools/create-feature.js +270 -0
- package/dist/tools/create-feature.js.map +1 -0
- package/dist/tools/validate.d.ts.map +1 -1
- package/dist/tools/validate.js +109 -4
- package/dist/tools/validate.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -19,11 +19,9 @@ import { registerExamplesTool } from './tools/examples.js';
|
|
|
19
19
|
import { registerDetectAndGuideTool } from './tools/detect-and-guide.js';
|
|
20
20
|
import { registerStyleRulesTool } from './tools/style-rules.js';
|
|
21
21
|
import { registerFolderStructureTool } from './tools/folder-structure.js';
|
|
22
|
-
import { registerBackendGuideTool } from './tools/backend-guide.js';
|
|
23
|
-
import { registerBackendFolderStructureTool } from './tools/backend-folder-structure.js';
|
|
24
|
-
import { registerAuditProjectTool } from './tools/audit-project.js';
|
|
25
22
|
import { registerScanElementsTool } from './tools/scan-elements.js';
|
|
26
23
|
import { registerCreateElementTool } from './tools/create-element.js';
|
|
24
|
+
import { registerCreateFeatureTool } from './tools/create-feature.js';
|
|
27
25
|
// Resources
|
|
28
26
|
import { registerPhilosophyResource } from './resources/philosophy-resource.js';
|
|
29
27
|
// Prompts
|
|
@@ -31,21 +29,19 @@ import { registerPlanFeaturePrompt } from './prompts/plan-feature.js';
|
|
|
31
29
|
// Create the MCP server
|
|
32
30
|
const server = new McpServer({
|
|
33
31
|
name: 'reactive-architecture',
|
|
34
|
-
version: '1.
|
|
32
|
+
version: '1.4.1',
|
|
35
33
|
});
|
|
36
34
|
// Register all tools
|
|
37
35
|
registerArchitectureGuideTool(server);
|
|
38
|
-
registerScaffoldTool(server);
|
|
39
|
-
registerValidateTool(server);
|
|
40
|
-
registerExamplesTool(server);
|
|
41
|
-
registerDetectAndGuideTool(server);
|
|
42
36
|
registerStyleRulesTool(server);
|
|
43
37
|
registerFolderStructureTool(server);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
registerExamplesTool(server);
|
|
39
|
+
registerScaffoldTool(server);
|
|
40
|
+
registerDetectAndGuideTool(server);
|
|
41
|
+
registerValidateTool(server);
|
|
47
42
|
registerScanElementsTool(server);
|
|
48
43
|
registerCreateElementTool(server);
|
|
44
|
+
registerCreateFeatureTool(server);
|
|
49
45
|
// Register resources
|
|
50
46
|
registerPhilosophyResource(server);
|
|
51
47
|
// Register prompts
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,gFAAgF;AAChF,mCAAmC;AACnC,gFAAgF;AAChF,qEAAqE;AACrE,qDAAqD;AACrD,mDAAmD;AACnD,EAAE;AACF,wEAAwE;AACxE,kCAAkC;AAClC,gFAAgF;AAEhF,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,QAAQ;AACR,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,gFAAgF;AAChF,mCAAmC;AACnC,gFAAgF;AAChF,qEAAqE;AACrE,qDAAqD;AACrD,mDAAmD;AACnD,EAAE;AACF,wEAAwE;AACxE,kCAAkC;AAClC,gFAAgF;AAEhF,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,QAAQ;AACR,OAAO,EAAE,6BAA6B,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAI1E,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,YAAY;AACZ,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AAEhF,UAAU;AACV,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAEtE,wBAAwB;AACxB,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IACzB,IAAI,EAAE,uBAAuB;IAC7B,OAAO,EAAE,OAAO;CACnB,CAAC,CAAC;AAEH,qBAAqB;AACrB,6BAA6B,CAAC,MAAM,CAAC,CAAC;AACtC,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAC/B,2BAA2B,CAAC,MAAM,CAAC,CAAC;AACpC,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,0BAA0B,CAAC,MAAM,CAAC,CAAC;AACnC,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,wBAAwB,CAAC,MAAM,CAAC,CAAC;AACjC,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAClC,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAElC,qBAAqB;AACrB,0BAA0B,CAAC,MAAM,CAAC,CAAC;AAEnC,mBAAmB;AACnB,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAElC,8BAA8B;AAC9B,KAAK,UAAU,IAAI;IACf,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,qEAAqE;AACzE,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-feature.d.ts","sourceRoot":"","sources":["../../src/tools/create-feature.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA6OpE,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,QAyD1D"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
// Reusing logic from scaffold.ts but adapted for file writing
|
|
5
|
+
// ideally we would share code, but for now we duplicate to avoid breaking existing tools during refactor
|
|
6
|
+
function toKebabCase(str) {
|
|
7
|
+
return str
|
|
8
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
9
|
+
.replace(/[\s_]+/g, '-')
|
|
10
|
+
.toLowerCase();
|
|
11
|
+
}
|
|
12
|
+
function toPascalCase(str) {
|
|
13
|
+
return str
|
|
14
|
+
.split(/[-_\s]+/)
|
|
15
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
|
|
16
|
+
.join('');
|
|
17
|
+
}
|
|
18
|
+
function toCamelCase(str) {
|
|
19
|
+
const pascal = toPascalCase(str);
|
|
20
|
+
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
21
|
+
}
|
|
22
|
+
function getAngularFiles(feature) {
|
|
23
|
+
const kebab = toKebabCase(feature);
|
|
24
|
+
const pascal = toPascalCase(feature);
|
|
25
|
+
const camel = toCamelCase(feature);
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
path: `models/${kebab}.model.ts`,
|
|
29
|
+
content: `export interface ${pascal} {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface Create${pascal}Dto {
|
|
35
|
+
name: string;
|
|
36
|
+
}
|
|
37
|
+
`
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
path: `services/${kebab}.service.ts`,
|
|
41
|
+
content: `import { Injectable, inject } from '@angular/core';
|
|
42
|
+
import { HttpClient } from '@angular/common/http';
|
|
43
|
+
import { Observable } from 'rxjs';
|
|
44
|
+
import { ${pascal}, Create${pascal}Dto } from '../models/${kebab}.model';
|
|
45
|
+
|
|
46
|
+
@Injectable({ providedIn: 'root' })
|
|
47
|
+
export class ${pascal}Service {
|
|
48
|
+
private readonly http = inject(HttpClient);
|
|
49
|
+
private readonly baseUrl = '/api/${kebab}s';
|
|
50
|
+
|
|
51
|
+
getAll(): Observable<${pascal}[]> {
|
|
52
|
+
return this.http.get<${pascal}[]>(this.baseUrl);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
getById(id: string): Observable<${pascal}> {
|
|
56
|
+
return this.http.get<${pascal}>(\`\${this.baseUrl}/\${id}\`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
create(data: Create${pascal}Dto): Observable<${pascal}> {
|
|
60
|
+
return this.http.post<${pascal}>(this.baseUrl, data);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
update(id: string, data: Partial<${pascal}>): Observable<${pascal}> {
|
|
64
|
+
return this.http.put<${pascal}>(\`\${this.baseUrl}/\${id}\`, data);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
delete(id: string): Observable<void> {
|
|
68
|
+
return this.http.delete<void>(\`\${this.baseUrl}/\${id}\`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
`
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
path: `store/${kebab}.store.ts`,
|
|
75
|
+
content: `import { computed, inject } from '@angular/core';
|
|
76
|
+
import { signalStore, withState, withComputed, withMethods, patchState } from '@ngrx/signals';
|
|
77
|
+
import { rxMethod } from '@ngrx/signals/rxjs-interop';
|
|
78
|
+
import { pipe, switchMap, tap } from 'rxjs';
|
|
79
|
+
import { tapResponse } from '@ngrx/operators';
|
|
80
|
+
import { ${pascal}Service } from '../services/${kebab}.service';
|
|
81
|
+
import { ${pascal} } from '../models/${kebab}.model';
|
|
82
|
+
|
|
83
|
+
interface ${pascal}State {
|
|
84
|
+
${camel}s: ${pascal}[];
|
|
85
|
+
selected${pascal}: ${pascal} | null;
|
|
86
|
+
loading: boolean;
|
|
87
|
+
error: string | null;
|
|
88
|
+
loaded: boolean;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const initialState: ${pascal}State = {
|
|
92
|
+
${camel}s: [],
|
|
93
|
+
selected${pascal}: null,
|
|
94
|
+
loading: false,
|
|
95
|
+
error: null,
|
|
96
|
+
loaded: false,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const ${pascal}Store = signalStore(
|
|
100
|
+
{ providedIn: 'root' },
|
|
101
|
+
withState(initialState),
|
|
102
|
+
withComputed((state) => ({
|
|
103
|
+
${camel}Count: computed(() => state.${camel}s().length),
|
|
104
|
+
})),
|
|
105
|
+
withMethods((store, service = inject(${pascal}Service)) => ({
|
|
106
|
+
load${pascal}s: rxMethod<void>(
|
|
107
|
+
pipe(
|
|
108
|
+
tap(() => patchState(store, { loading: true, error: null })),
|
|
109
|
+
switchMap(() =>
|
|
110
|
+
service.getAll().pipe(
|
|
111
|
+
tapResponse({
|
|
112
|
+
next: (${camel}s) => patchState(store, { ${camel}s, loading: false, loaded: true }),
|
|
113
|
+
error: (err: Error) => patchState(store, { error: err.message, loading: false }),
|
|
114
|
+
})
|
|
115
|
+
)
|
|
116
|
+
)
|
|
117
|
+
)
|
|
118
|
+
),
|
|
119
|
+
|
|
120
|
+
create${pascal}: rxMethod<Create${pascal}Dto>(
|
|
121
|
+
pipe(
|
|
122
|
+
tap(() => patchState(store, { loading: true, error: null })),
|
|
123
|
+
switchMap((data) =>
|
|
124
|
+
service.create(data).pipe(
|
|
125
|
+
tapResponse({
|
|
126
|
+
next: (newItem) => patchState(store, {
|
|
127
|
+
${camel}s: [...store.${camel}s(), newItem],
|
|
128
|
+
loading: false
|
|
129
|
+
}),
|
|
130
|
+
error: (err: Error) => patchState(store, { error: err.message, loading: false }),
|
|
131
|
+
})
|
|
132
|
+
)
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
),
|
|
136
|
+
|
|
137
|
+
update${pascal}: rxMethod<{ id: string; data: Partial<${pascal}> }>(
|
|
138
|
+
pipe(
|
|
139
|
+
tap(() => patchState(store, { loading: true, error: null })),
|
|
140
|
+
switchMap(({ id, data }) =>
|
|
141
|
+
service.update(id, data).pipe(
|
|
142
|
+
tapResponse({
|
|
143
|
+
next: (updatedItem) => patchState(store, {
|
|
144
|
+
${camel}s: store.${camel}s().map(i => i.id === id ? updatedItem : i),
|
|
145
|
+
loading: false
|
|
146
|
+
}),
|
|
147
|
+
error: (err: Error) => patchState(store, { error: err.message, loading: false }),
|
|
148
|
+
})
|
|
149
|
+
)
|
|
150
|
+
)
|
|
151
|
+
)
|
|
152
|
+
),
|
|
153
|
+
|
|
154
|
+
delete${pascal}: rxMethod<string>(
|
|
155
|
+
pipe(
|
|
156
|
+
tap(() => patchState(store, { loading: true, error: null })),
|
|
157
|
+
switchMap((id) =>
|
|
158
|
+
service.delete(id).pipe(
|
|
159
|
+
tapResponse({
|
|
160
|
+
next: () => patchState(store, {
|
|
161
|
+
${camel}s: store.${camel}s().filter(i => i.id !== id),
|
|
162
|
+
loading: false
|
|
163
|
+
}),
|
|
164
|
+
error: (err: Error) => patchState(store, { error: err.message, loading: false }),
|
|
165
|
+
})
|
|
166
|
+
)
|
|
167
|
+
)
|
|
168
|
+
)
|
|
169
|
+
),
|
|
170
|
+
}))
|
|
171
|
+
);
|
|
172
|
+
`
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
path: `components/${kebab}-list/${kebab}-list.component.ts`,
|
|
176
|
+
content: `import { Component, inject, OnInit } from '@angular/core';
|
|
177
|
+
import { CommonModule } from '@angular/common';
|
|
178
|
+
import { ${pascal}Store } from '../../store/${kebab}.store';
|
|
179
|
+
|
|
180
|
+
@Component({
|
|
181
|
+
selector: 'app-${kebab}-list',
|
|
182
|
+
standalone: true,
|
|
183
|
+
imports: [CommonModule],
|
|
184
|
+
template: \`
|
|
185
|
+
<div class="p-4">
|
|
186
|
+
<h2 class="text-xl font-bold mb-4">${pascal} List</h2>
|
|
187
|
+
|
|
188
|
+
@if (store.loading()) {
|
|
189
|
+
<div class="loading">Loading...</div>
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@if (store.error(); as error) {
|
|
193
|
+
<div class="error text-red-500">{{ error }}</div>
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
<ul class="space-y-2">
|
|
197
|
+
@for (item of store.${camel}s(); track item.id) {
|
|
198
|
+
<li class="p-2 border rounded hover:bg-gray-50">
|
|
199
|
+
{{ item.name }}
|
|
200
|
+
</li>
|
|
201
|
+
}
|
|
202
|
+
</ul>
|
|
203
|
+
</div>
|
|
204
|
+
\`,
|
|
205
|
+
})
|
|
206
|
+
export class ${pascal}ListComponent implements OnInit {
|
|
207
|
+
readonly store = inject(${pascal}Store);
|
|
208
|
+
|
|
209
|
+
ngOnInit() {
|
|
210
|
+
this.store.load${pascal}s();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
`
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
path: 'index.ts',
|
|
217
|
+
content: `export { ${pascal}ListComponent } from './components/${kebab}-list/${kebab}-list.component';
|
|
218
|
+
export { ${pascal}Store } from './store/${kebab}.store';
|
|
219
|
+
export { ${pascal}Service } from './services/${kebab}.service';
|
|
220
|
+
export type { ${pascal}, Create${pascal}Dto } from './models/${kebab}.model';
|
|
221
|
+
`
|
|
222
|
+
}
|
|
223
|
+
];
|
|
224
|
+
}
|
|
225
|
+
export function registerCreateFeatureTool(server) {
|
|
226
|
+
server.tool('create_feature', `Creates a complete, self-contained feature module on disk.
|
|
227
|
+
Generates the component, store, service, model, and index files in the correct strict folder structure.
|
|
228
|
+
Enforces "Module Portability" by co-locating all related files.
|
|
229
|
+
CURRENTLY SUPPORTS: Angular (Signals + Standalone).`, {
|
|
230
|
+
name: z.string().describe('Name of the feature (e.g. "user-profile", "orders")'),
|
|
231
|
+
parentPath: z.string().describe('Absolute path to the parent directory where the feature folder should be created'),
|
|
232
|
+
stack: z.enum(['angular']).default('angular').describe('Target stack (currently only angular supported)'),
|
|
233
|
+
}, async ({ name, parentPath, stack }) => {
|
|
234
|
+
const kebabName = toKebabCase(name);
|
|
235
|
+
const featureDir = path.join(parentPath, kebabName);
|
|
236
|
+
if (fs.existsSync(featureDir)) {
|
|
237
|
+
return {
|
|
238
|
+
content: [{ type: 'text', text: '❌ Error: Directory ' + featureDir + ' already exists.' }],
|
|
239
|
+
isError: true,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
// Create feature directory
|
|
243
|
+
fs.mkdirSync(featureDir, { recursive: true });
|
|
244
|
+
let files = [];
|
|
245
|
+
if (stack === 'angular') {
|
|
246
|
+
files = getAngularFiles(name);
|
|
247
|
+
}
|
|
248
|
+
// Write files
|
|
249
|
+
const createdFiles = [];
|
|
250
|
+
for (const file of files) {
|
|
251
|
+
const fullPath = path.join(featureDir, file.path);
|
|
252
|
+
const dir = path.dirname(fullPath);
|
|
253
|
+
if (!fs.existsSync(dir)) {
|
|
254
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
255
|
+
}
|
|
256
|
+
fs.writeFileSync(fullPath, file.content);
|
|
257
|
+
createdFiles.push(file.path);
|
|
258
|
+
}
|
|
259
|
+
const fileList = createdFiles.map(f => '- ' + f).join('\\n');
|
|
260
|
+
const resultMsg = '✅ Created feature "**' + name + '**" in \`' + featureDir + '\`\\n\\n' +
|
|
261
|
+
'Generated structure:\\n' + fileList;
|
|
262
|
+
return {
|
|
263
|
+
content: [{
|
|
264
|
+
type: 'text',
|
|
265
|
+
text: resultMsg
|
|
266
|
+
}]
|
|
267
|
+
};
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=create-feature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-feature.js","sourceRoot":"","sources":["../../src/tools/create-feature.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAgRpE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAmG5D"}
|
package/dist/tools/validate.js
CHANGED
|
@@ -122,15 +122,120 @@ function validateDescription(description) {
|
|
|
122
122
|
}
|
|
123
123
|
return issues;
|
|
124
124
|
}
|
|
125
|
+
function validateCode(code) {
|
|
126
|
+
const issues = [];
|
|
127
|
+
const lower = code.toLowerCase();
|
|
128
|
+
// Check 1: Component injecting Service (The Cardinal Sin)
|
|
129
|
+
// Matches: class ...Component ... inject(...Service) OR constructor(...Service)
|
|
130
|
+
const isComponent = /class\s+\w+Component/.test(code) || /@Component/.test(code);
|
|
131
|
+
if (isComponent) {
|
|
132
|
+
// Regex for detecting service injection
|
|
133
|
+
// 1. private service = inject(UserService)
|
|
134
|
+
// 2. constructor(private userService: UserService)
|
|
135
|
+
const injectsService = /inject\s*\(\s*\w+Service\s*\)/.test(code);
|
|
136
|
+
const constructsService = /constructor\s*\([^)]*\w+Service/.test(code);
|
|
137
|
+
const importsService = /import\s+.*Service.*\s+from/.test(code);
|
|
138
|
+
if (injectsService || constructsService) {
|
|
139
|
+
issues.push({
|
|
140
|
+
severity: 'error',
|
|
141
|
+
message: '⛔ CRITICAL PHILOSOPHY VIOLATION: Component is injecting a Service directly.\n' +
|
|
142
|
+
'The Reactive Architecture mandates: Component → Store → Service.\n' +
|
|
143
|
+
'Skipping the Store breaks Unidirectional Data Flow and State Management.\n' +
|
|
144
|
+
'FIX: Remove Service injection. Inject the Store instead.',
|
|
145
|
+
rule: 'component-injects-service',
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
else if (importsService) {
|
|
149
|
+
// Import without injection might be okay (e.g. for types), but suspicious if used
|
|
150
|
+
// We'll warn if we see usage like "UserService.someMethod" or "new UserService"
|
|
151
|
+
if (/\w+Service\./.test(code) || /new\s+\w+Service/.test(code)) {
|
|
152
|
+
issues.push({
|
|
153
|
+
severity: 'error',
|
|
154
|
+
message: 'Component is using a Service class directly (static or instantiation). ' +
|
|
155
|
+
'All logic must go through the Store.',
|
|
156
|
+
rule: 'component-calls-service',
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Check 2: Service holding state
|
|
162
|
+
// Matches: class ...Service ... boolean = ... or array = [] (heuristic)
|
|
163
|
+
if (/class\s+\w+Service/.test(code)) {
|
|
164
|
+
if (/subject<|behavior_subject<|signal<|writable</i.test(code)) {
|
|
165
|
+
issues.push({
|
|
166
|
+
severity: 'error',
|
|
167
|
+
message: 'Service appears to be holding reactive state (Subject/Signal). ' +
|
|
168
|
+
'Services must be stateless. Move state to a Store.',
|
|
169
|
+
rule: 'service-has-state',
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Check 3: Cyclomatic Complexity (Mock Linter)
|
|
174
|
+
// Heuristic: Count branching keywords
|
|
175
|
+
const complexityMatches = code.match(/(\bif\b|\bfor\b|\bwhile\b|\bcase\b|\bcatch\b|\?|\|\||&&)/g);
|
|
176
|
+
const complexity = complexityMatches ? complexityMatches.length + 1 : 1;
|
|
177
|
+
// Only strictly enforce on smaller snippets (to avoid flagging whole files)
|
|
178
|
+
// If it looks like a single function (no 'class' keyword)
|
|
179
|
+
const isClass = /\bclass\b/.test(code);
|
|
180
|
+
if (!isClass && complexity > 5) {
|
|
181
|
+
issues.push({
|
|
182
|
+
severity: 'warning',
|
|
183
|
+
message: `Detected High Cyclomatic Complexity (${complexity}). ` +
|
|
184
|
+
'Style Rules limit complexity to 5 per function. ' +
|
|
185
|
+
'Simplify logic or extract helper functions.',
|
|
186
|
+
rule: 'max-complexity',
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
// Check 4: Function Length
|
|
190
|
+
// If it's not a class, check line count
|
|
191
|
+
if (!isClass) {
|
|
192
|
+
// Exclude empty lines and comments
|
|
193
|
+
const meaningfulLines = code.split('\n')
|
|
194
|
+
.map(l => l.trim())
|
|
195
|
+
.filter(l => l && !l.startsWith('//') && !l.startsWith('/*') && !l.startsWith('*'));
|
|
196
|
+
if (meaningfulLines.length > 15) { // 10 lines code + some leeway for imports/signatures
|
|
197
|
+
issues.push({
|
|
198
|
+
severity: 'warning',
|
|
199
|
+
message: `Snippet length (${meaningfulLines.length} lines) exceeds the limit. ` +
|
|
200
|
+
'Functions must be ≤ 10 lines of code. Split into smaller functions.',
|
|
201
|
+
rule: 'max-lines-per-function',
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
// For files/classes, check total length (leeway for imports)
|
|
207
|
+
const lines = code.split('\n').length;
|
|
208
|
+
if (lines > 180) { // 160 + leeway
|
|
209
|
+
issues.push({
|
|
210
|
+
severity: 'warning',
|
|
211
|
+
message: `File length (${lines} lines) exceeds the limit (160). ` +
|
|
212
|
+
'Refactor and split into multiple files.',
|
|
213
|
+
rule: 'max-file-lines',
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return issues;
|
|
218
|
+
}
|
|
125
219
|
export function registerValidateTool(server) {
|
|
126
220
|
server.tool('validate_architecture', `Validates whether a proposed frontend architecture or code structure follows ` +
|
|
127
221
|
`the reactive Component → Store → Service pattern. ` +
|
|
128
|
-
`Provide a text description
|
|
222
|
+
`Provide a text description OR a code snippet to receive validation feedback.`, {
|
|
129
223
|
description: z
|
|
130
224
|
.string()
|
|
131
|
-
.
|
|
132
|
-
|
|
133
|
-
|
|
225
|
+
.optional()
|
|
226
|
+
.describe('Text description of the proposed architecture'),
|
|
227
|
+
code: z
|
|
228
|
+
.string()
|
|
229
|
+
.optional()
|
|
230
|
+
.describe('Code snippet (Component or Service) to validate against architectural rules'),
|
|
231
|
+
}, async ({ description, code }) => {
|
|
232
|
+
let issues = [];
|
|
233
|
+
if (description) {
|
|
234
|
+
issues = [...issues, ...validateDescription(description)];
|
|
235
|
+
}
|
|
236
|
+
if (code) {
|
|
237
|
+
issues = [...issues, ...validateCode(code)];
|
|
238
|
+
}
|
|
134
239
|
if (issues.length === 0) {
|
|
135
240
|
return {
|
|
136
241
|
content: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/tools/validate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gherk/reactive-architecture",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "MCP server that teaches AI assistants the reactive architecture philosophy: Component → Store → Service + Controller → Service → Repository",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|