@pixel-normal-edit/mcp 2.0.8 → 2.1.0

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.
@@ -15,11 +15,14 @@ const TIMEOUT = parseInt(process.env.MCP_TIMEOUT || '20000');
15
15
  /**
16
16
  * Send a command payload to the browser via Firestore and wait for response.
17
17
  * @param {Object} payload - The command action and parameters
18
+ * @param {number} timeoutOverride - Optional timeout in milliseconds
18
19
  * @returns {Promise<Object>} MCP-compatible response object
19
20
  */
20
- async function sendCommand(payload) {
21
+ async function sendCommand(payload, timeoutOverride = null) {
21
22
  const id = crypto.randomUUID();
22
23
  const ref = doc(db, 'mcp_sessions', SESSION, 'commands', id);
24
+ const actualTimeout = timeoutOverride || TIMEOUT;
25
+
23
26
  await setDoc(ref, { ...payload, status: 'pending', timestamp: Date.now() });
24
27
 
25
28
  return new Promise((resolve) => {
@@ -27,9 +30,9 @@ async function sendCommand(payload) {
27
30
  unsub();
28
31
  resolve({
29
32
  isError: true,
30
- content: [{ type: 'text', text: `⏱ Timeout (${TIMEOUT}ms). Is the browser tab open with session: ${SESSION}?` }]
33
+ content: [{ type: 'text', text: `⏱ Timeout (${actualTimeout}ms). Is the browser tab open with session: ${SESSION}?` }]
31
34
  });
32
- }, TIMEOUT);
35
+ }, actualTimeout);
33
36
 
34
37
  const unsub = onSnapshot(ref, (snap) => {
35
38
  const d = snap.data();
package/core/server.js CHANGED
@@ -6,7 +6,9 @@
6
6
  * Provides a tool registration factory for consistent tool definitions.
7
7
  */
8
8
  const { McpServer } = require('@modelcontextprotocol/sdk/server/mcp.js');
9
- const { sendCommand } = require('./command-bus');
9
+ const { sendCommand, SESSION } = require('./command-bus');
10
+ const workflow = require('../rules/workflow');
11
+ const { DRAWING_STEPS } = require('../rules/rules');
10
12
 
11
13
  /**
12
14
  * Create a new MCP server instance
@@ -16,16 +18,109 @@ function createServer() {
16
18
  return new McpServer({ name: 'PixelNormalEdit', version: '2.0.0' });
17
19
  }
18
20
 
21
+ /**
22
+ * Read-only tools that do not modify the canvas and should bypass strict workflow checks
23
+ */
24
+ const READ_ONLY_TOOLS = [
25
+ 'ping',
26
+ 'layer_get_info',
27
+ 'workspace_list_tabs',
28
+ 'workspace_get_active_tab',
29
+ 'animation_get_info',
30
+ 'anchor_list',
31
+ 'query_snapshot',
32
+ 'query_bounding_box',
33
+ 'query_palette',
34
+ 'query_pixel',
35
+ 'query_export_image',
36
+ 'query_document_state',
37
+ 'workflow_status',
38
+ 'workflow_get_progress'
39
+ ];
40
+
41
+ /**
42
+ * Identify if a tool is a drawing tool that should only be allowed in drawing steps
43
+ */
44
+ function isDrawingTool(name) {
45
+ return name.startsWith('draw_') ||
46
+ name.startsWith('bulk_') ||
47
+ name.startsWith('filter_') ||
48
+ name.startsWith('sprite_') ||
49
+ name.startsWith('region_') ||
50
+ name.startsWith('layer_') ||
51
+ name.startsWith('animation_') ||
52
+ name.startsWith('art_tree_');
53
+ }
54
+
19
55
  /**
20
56
  * Register a single-command tool on the server
21
57
  * @param {McpServer} server - The MCP server instance
22
58
  * @param {string} name - Tool name
23
59
  * @param {string} desc - Tool description
24
60
  * @param {Object} schema - Zod schema for parameters
25
- * @param {Function} mapToCmd - Function mapping params to command payload
61
+ * @param {Function} mapToCmd - Function mapping params to command payload or returning MCP response
26
62
  */
27
63
  function registerTool(server, name, desc, schema, mapToCmd) {
28
- server.tool(name, desc, schema, async (params) => sendCommand(mapToCmd(params)));
64
+ server.tool(name, desc, schema, async (params) => {
65
+ // 1. Strict Middleware Enforcement (Run BEFORE tool execution)
66
+ if (!READ_ONLY_TOOLS.includes(name)) {
67
+ const state = workflow.getState(SESSION);
68
+
69
+ // Allow workflow_start to run even if state is null
70
+ if (!state && name !== 'workflow_start') {
71
+ return {
72
+ isError: true,
73
+ content: [{ type: 'text', text: "⛔ Middleware Block: Workflow not started! Call workflow_start first." }]
74
+ };
75
+ }
76
+
77
+ if (state) {
78
+ if (state.step_status === 'WAITING_FOR_USER') {
79
+ return {
80
+ isError: true,
81
+ content: [{ type: 'text', text: "⛔ Middleware Block: Workflow is paused! Waiting for user approval. You cannot execute this tool." }]
82
+ };
83
+ }
84
+
85
+ if (state.step_status === 'COMPLETED') {
86
+ return {
87
+ isError: true,
88
+ content: [{ type: 'text', text: "⛔ Middleware Block: Workflow is completed! Please start a new workflow." }]
89
+ };
90
+ }
91
+
92
+ // Block creating new tabs in EDIT_IMAGE mode
93
+ if (name === 'workspace_create_tab' && state.current_mode === 'EDIT_IMAGE') {
94
+ return {
95
+ isError: true,
96
+ content: [{ type: 'text', text: "⛔ Middleware Block: You cannot create new images in EDIT_IMAGE mode. Please only edit the existing image." }]
97
+ };
98
+ }
99
+
100
+ // Check Drawing Steps Enforcement
101
+ if (isDrawingTool(name)) {
102
+ const currentStep = state.steps[state.currentStepIndex];
103
+ if (!currentStep || !DRAWING_STEPS.includes(currentStep.id)) {
104
+ return {
105
+ isError: true,
106
+ content: [{ type: 'text', text: `⛔ Middleware Block: You cannot use drawing/layer tools in the current step ("${currentStep ? currentStep.label : 'None'}"). You must advance to a drawing step (e.g. EXECUTE_PHASES) first.` }]
107
+ };
108
+ }
109
+ }
110
+ }
111
+ }
112
+
113
+ // 2. Execute the tool implementation
114
+ const res = mapToCmd(params);
115
+
116
+ // 3. If the tool implementation returns an MCP response directly (local tool like workflow_*)
117
+ if (res && res.content) {
118
+ return res;
119
+ }
120
+
121
+ // 4. Forward the command payload to the browser
122
+ return sendCommand(res);
123
+ });
29
124
  }
30
125
 
31
126
  module.exports = { createServer, registerTool, sendCommand };
package/index.js CHANGED
@@ -28,6 +28,7 @@ require('dotenv').config({ path: require('path').join(__dirname, '..', '.env') }
28
28
  const { createServer } = require('./core/server');
29
29
  const { registerAll: registerCoreTools } = require('./tools/index');
30
30
  const { registerAll: registerArtTree } = require('./domains/art-tree/index');
31
+ const { registerAll: registerRules } = require('./rules/index');
31
32
 
32
33
  // ── Initialize ────────────────────────────────────────────────────────────
33
34
  const server = createServer();
@@ -35,6 +36,9 @@ const server = createServer();
35
36
  // ── Register Core Tools ───────────────────────────────────────────────────
36
37
  registerCoreTools(server);
37
38
 
39
+ // ── Register Rules / Workflow Tools (BẮT BUỘC: chạy trước khi vẽ) ────────
40
+ registerRules(server);
41
+
38
42
  // ── Register Domain Modules ───────────────────────────────────────────────
39
43
  registerArtTree(server);
40
44
  // Future domains: registerPixelArt(server), registerCharacterDrawing(server), etc.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pixel-normal-edit/mcp",
3
- "version": "2.0.8",
3
+ "version": "2.1.0",
4
4
  "description": "MCP server for Pixel Normal Edit canvas - enables AI agents to draw pixel art",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -0,0 +1,476 @@
1
+ # RULE: QUY TRÌNH TẠO, SỬA ẢNH VÀ TẠO ANIMATION
2
+
3
+ ## 1. Nguyên tắc chung
4
+
5
+ Mọi thao tác vẽ, sửa ảnh hoặc tạo animation phải được thực hiện theo quy trình tuần tự, có trạng thái rõ ràng.
6
+
7
+ AI không được tự ý:
8
+
9
+ * Bỏ qua bước.
10
+ * Nhảy sang bước tiếp theo khi bước hiện tại chưa hoàn tất.
11
+ * Tự ý tạo ảnh mới trong quy trình sửa ảnh.
12
+ * Thay đổi các thành phần không nằm trong phạm vi yêu cầu.
13
+ * Ghi đè trạng thái của bước trước nếu chưa hoàn tất hoặc chưa được xác nhận.
14
+
15
+ Mỗi bước phải được lưu vào trạng thái, ví dụ:
16
+
17
+ ```text
18
+ current_mode
19
+ current_step
20
+ current_layer
21
+ current_frame
22
+ user_approval_required
23
+ step_status
24
+ ```
25
+
26
+ Trạng thái mẫu:
27
+
28
+ ```text
29
+ current_mode: CREATE_IMAGE
30
+ current_step: ANALYZE_REQUEST
31
+ current_layer: 0
32
+ current_frame: null
33
+ step_status: IN_PROGRESS
34
+ user_approval_required: false
35
+ ```
36
+
37
+ Các trạng thái có thể sử dụng:
38
+
39
+ ```text
40
+ PENDING
41
+ IN_PROGRESS
42
+ WAITING_FOR_USER
43
+ COMPLETED
44
+ FAILED
45
+ CANCELLED
46
+ ```
47
+
48
+ ---
49
+
50
+ # 2. TẠO ẢNH MỚI
51
+
52
+ ## Bước 1: Khởi tạo Canvas
53
+
54
+ Khi người dùng yêu cầu tạo ảnh:
55
+
56
+ 1. Kiểm tra kích thước canvas.
57
+ 2. Kích thước pixel bắt buộc phải do người dùng cung cấp.
58
+ 3. Nếu người dùng chưa cung cấp kích thước, phải hỏi lại.
59
+ 4. Không tự động sử dụng kích thước mặc định 32×32 nếu chưa được người dùng xác nhận.
60
+
61
+ Ví dụ:
62
+
63
+ ```text
64
+ Canvas:
65
+ width: [user_input]
66
+ height: [user_input]
67
+ ```
68
+
69
+ Sau khi nhận được kích thước, tạo canvas mới.
70
+
71
+ Trạng thái:
72
+
73
+ ```text
74
+ current_step: INITIALIZE_CANVAS
75
+ step_status: COMPLETED
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Bước 2: Phân tích yêu cầu
81
+
82
+ Phân tích yêu cầu của người dùng thành các thành phần có cấu trúc.
83
+
84
+ Ví dụ:
85
+
86
+ ```text
87
+ Subject:
88
+ - Cây
89
+
90
+ Components:
91
+ - Thân cây
92
+ - Cành cây
93
+ - Lá cây
94
+ - Hoa/quả
95
+
96
+ Environment:
97
+ - Mặt đất
98
+ - Bầu trời
99
+ - Vật thể xung quanh
100
+
101
+ Style:
102
+ - Pixel art
103
+ - Anime
104
+ - Realistic
105
+ - ...
106
+
107
+ Lighting:
108
+ - Direction
109
+ - Intensity
110
+ - Shadow
111
+
112
+ Composition:
113
+ - Position
114
+ - Scale
115
+ - Perspective
116
+ ```
117
+
118
+ Cấu trúc này phải có khả năng mở rộng tùy theo yêu cầu.
119
+
120
+ Trạng thái:
121
+
122
+ ```text
123
+ current_step: ANALYZE_REQUEST
124
+ step_status: COMPLETED
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Bước 3: Lập kế hoạch vẽ
130
+
131
+ AI phải tạo kế hoạch vẽ theo thứ tự từ tổng thể đến chi tiết.
132
+
133
+ Ví dụ:
134
+
135
+ ```text
136
+ 1. Phác thảo bố cục tổng thể.
137
+ 2. Vẽ background.
138
+ 3. Vẽ các hình khối chính.
139
+ 4. Vẽ line hoặc silhouette.
140
+ 5. Vẽ từng thành phần chính.
141
+ 6. Thêm màu cơ bản.
142
+ 7. Thêm ánh sáng và bóng.
143
+ 8. Thêm chi tiết nhỏ.
144
+ 9. Kiểm tra tổng thể.
145
+ 10. Tinh chỉnh.
146
+ ```
147
+
148
+ AI phải trả kế hoạch cho người dùng trước khi bắt đầu thực hiện.
149
+
150
+ Nếu quy trình yêu cầu xác nhận, chuyển sang:
151
+
152
+ ```text
153
+ step_status: WAITING_FOR_USER
154
+ user_approval_required: true
155
+ ```
156
+
157
+ AI chỉ được tiếp tục sau khi người dùng xác nhận.
158
+
159
+ ---
160
+
161
+ # 3. QUY TẮC VẼ THEO TỪNG GIAI ĐOẠN
162
+
163
+ AI phải vẽ theo từng giai đoạn, không thực hiện toàn bộ ảnh trong một bước duy nhất.
164
+
165
+ Thứ tự tổng quát:
166
+
167
+ ```text
168
+ PHASE_0: SKETCH / BLOCKING
169
+ PHASE_1: BACKGROUND
170
+ PHASE_2: MAIN_SHAPES
171
+ PHASE_3: LINE / SILHOUETTE
172
+ PHASE_4: BASE_COLORS
173
+ PHASE_5: SHADING
174
+ PHASE_6: LIGHTING
175
+ PHASE_7: DETAILS
176
+ PHASE_8: FINAL_REVIEW
177
+ ```
178
+
179
+ Sau mỗi giai đoạn:
180
+
181
+ 1. Lưu trạng thái.
182
+ 2. Kiểm tra kết quả.
183
+ 3. Nếu cần, cung cấp ảnh xem trước hoặc cho phép người dùng sử dụng lệnh xem ảnh.
184
+ 4. Nếu chưa đạt, tiếp tục chỉnh sửa ở đúng giai đoạn hiện tại.
185
+ 5. Không được chuyển sang giai đoạn tiếp theo nếu giai đoạn hiện tại chưa hoàn tất.
186
+
187
+ Ví dụ:
188
+
189
+ ```text
190
+ current_step: DRAW_BACKGROUND
191
+ step_status: IN_PROGRESS
192
+ ```
193
+
194
+ Sau khi hoàn tất:
195
+
196
+ ```text
197
+ current_step: DRAW_BACKGROUND
198
+ step_status: COMPLETED
199
+ ```
200
+
201
+ Sau đó mới được chuyển sang:
202
+
203
+ ```text
204
+ current_step: DRAW_MAIN_SHAPES
205
+ step_status: IN_PROGRESS
206
+ ```
207
+
208
+ ---
209
+
210
+ # 4. QUẢN LÝ LAYER
211
+
212
+ Layer được sử dụng xuyên suốt toàn bộ quy trình.
213
+
214
+ Cấu trúc cơ bản:
215
+
216
+ ```text
217
+ Layer 0: Background
218
+ Layer 1: Main subject
219
+ Layer 2: Secondary subject
220
+ Layer 3: Details
221
+ Layer n: Additional elements
222
+ ```
223
+
224
+ Tuy nhiên, layer phải được phân chia theo thành phần cần chỉnh sửa độc lập.
225
+
226
+ Ví dụ với một cái cây:
227
+
228
+ ```text
229
+ Layer 0: Background
230
+ Layer 1: Trunk
231
+ Layer 2: Branches
232
+ Layer 3: Leaves
233
+ Layer 4: Fruits
234
+ Layer 5: Shadows
235
+ Layer 6: Highlights
236
+ ```
237
+
238
+ Nguyên tắc:
239
+
240
+ * Mỗi thành phần có thể chỉnh sửa độc lập nên được đặt trên layer riêng.
241
+ * Không gộp nhiều thành phần khác nhau vào cùng một layer nếu việc đó làm mất khả năng chỉnh sửa riêng.
242
+ * Khi thêm một thành phần mới, phải xác định layer phù hợp trước khi vẽ.
243
+ * Mọi thay đổi phải được ghi nhận vào trạng thái.
244
+
245
+ Ví dụ:
246
+
247
+ ```text
248
+ current_layer: 3
249
+ layer_name: Leaves
250
+ layer_status: IN_PROGRESS
251
+ ```
252
+
253
+ ---
254
+
255
+ # 5. KIỂM TRA VÀ XÁC NHẬN
256
+
257
+ Sau mỗi giai đoạn, AI phải kiểm tra:
258
+
259
+ ```text
260
+ - Đúng yêu cầu người dùng chưa?
261
+ - Bố cục có đúng không?
262
+ - Tỷ lệ có phù hợp không?
263
+ - Layer có đúng không?
264
+ - Thành phần có bị ảnh hưởng ngoài phạm vi không?
265
+ - Có lỗi phát sinh từ bước trước không?
266
+ ```
267
+
268
+ Nếu cần người dùng xác nhận:
269
+
270
+ ```text
271
+ step_status: WAITING_FOR_USER
272
+ ```
273
+
274
+ AI phải dừng và chờ phản hồi.
275
+
276
+ Người dùng có thể:
277
+
278
+ ```text
279
+ APPROVE
280
+ CONTINUE
281
+ REVIEW
282
+ EDIT
283
+ UNDO
284
+ REGENERATE_CURRENT_STEP
285
+ ```
286
+
287
+ Nếu người dùng yêu cầu chỉnh sửa, chỉ chỉnh sửa bước hoặc layer liên quan, không tự động tạo lại toàn bộ ảnh.
288
+
289
+ ---
290
+
291
+ # 6. SỬA ẢNH
292
+
293
+ Quy trình sửa ảnh phải sử dụng ảnh hiện tại làm nguồn gốc.
294
+
295
+ AI không được tự ý tạo một ảnh mới thay thế ảnh hiện tại.
296
+
297
+ Quy trình:
298
+
299
+ ```text
300
+ 1. Nhận yêu cầu sửa.
301
+ 2. Phân tích chính xác nội dung cần sửa.
302
+ 3. Lấy ảnh hiện tại.
303
+ 4. So sánh yêu cầu với ảnh hiện tại.
304
+ 5. Xác định vùng hoặc layer cần chỉnh sửa.
305
+ 6. Khoanh vùng khu vực cần sửa.
306
+ 7. Thực hiện chỉnh sửa trong phạm vi đó.
307
+ 8. Kiểm tra sự tương thích với môi trường xung quanh.
308
+ 9. Điều chỉnh phần chuyển tiếp nếu cần.
309
+ 10. Cập nhật thay đổi vào ảnh hiện tại.
310
+ 11. Kiểm tra kết quả.
311
+ ```
312
+
313
+ Ví dụ:
314
+
315
+ ```text
316
+ current_mode: EDIT_IMAGE
317
+ target_area: Layer 3 / Leaves
318
+ edit_scope: Specific region
319
+ ```
320
+
321
+ Nguyên tắc bắt buộc:
322
+
323
+ * Chỉ sửa phần được yêu cầu.
324
+ * Giữ nguyên các phần không liên quan.
325
+ * Không tạo lại toàn bộ ảnh.
326
+ * Không thay đổi bố cục, phong cách hoặc thành phần khác nếu người dùng không yêu cầu.
327
+ * Sau khi sửa phải kiểm tra sự hòa hợp với các vùng xung quanh.
328
+
329
+ Nếu chỉnh sửa chưa đạt:
330
+
331
+ ```text
332
+ current_step: EDIT_TARGET_AREA
333
+ step_status: IN_PROGRESS
334
+ ```
335
+
336
+ Không được chuyển sang bước khác cho đến khi vùng chỉnh sửa hoàn tất.
337
+
338
+ ---
339
+
340
+ # 7. TẠO ANIMATION MỚI
341
+
342
+ Quy trình tạo animation tương tự quy trình tạo ảnh nhưng bổ sung hệ thống frame.
343
+
344
+ ## Bước 1: Khởi tạo
345
+
346
+ Xác định:
347
+
348
+ ```text
349
+ Canvas:
350
+ width
351
+ height
352
+
353
+ Animation:
354
+ fps
355
+ total_frames
356
+ loop
357
+ ```
358
+
359
+ Nếu người dùng chưa cung cấp thông tin cần thiết, phải hỏi lại.
360
+
361
+ ---
362
+
363
+ ## Bước 2: Phân tích animation
364
+
365
+ Phân tích:
366
+
367
+ ```text
368
+ - Đối tượng.
369
+ - Chuyển động.
370
+ - Hướng chuyển động.
371
+ - Frame bắt đầu.
372
+ - Frame kết thúc.
373
+ - Các keyframe.
374
+ - Các frame trung gian.
375
+ - Layer cần sử dụng.
376
+ ```
377
+
378
+ Ví dụ:
379
+
380
+ ```text
381
+ Frame 0: Initial pose
382
+ Frame 1: Movement begins
383
+ Frame 2: Mid movement
384
+ Frame 3: Peak movement
385
+ Frame 4: Return
386
+ ```
387
+
388
+ ---
389
+
390
+ ## Bước 3: Tạo và xử lý từng frame
391
+
392
+ Mỗi frame phải được xử lý riêng theo đúng thứ tự:
393
+
394
+ ```text
395
+ 1. Activate frame.
396
+ 2. Xác định trạng thái của frame.
397
+ 3. Xác định layer cần vẽ.
398
+ 4. Vẽ hoặc chỉnh sửa layer.
399
+ 5. Kiểm tra tính liên tục với frame trước và sau.
400
+ 6. Lưu frame.
401
+ 7. Chuyển sang frame tiếp theo.
402
+ ```
403
+
404
+ Ví dụ:
405
+
406
+ ```text
407
+ current_frame: 0
408
+ current_layer: 1
409
+ current_step: DRAW_FRAME
410
+ step_status: IN_PROGRESS
411
+ ```
412
+
413
+ Chỉ được chuyển sang:
414
+
415
+ ```text
416
+ current_frame: 1
417
+ ```
418
+
419
+ sau khi frame 0 đã hoàn tất.
420
+
421
+ ---
422
+
423
+ # 8. KIỂM TRA TÍNH LIÊN TỤC CỦA ANIMATION
424
+
425
+ Sau khi hoàn thành các frame, phải kiểm tra:
426
+
427
+ ```text
428
+ - Vị trí đối tượng có chuyển động liên tục không?
429
+ - Layer có nhất quán giữa các frame không?
430
+ - Có hiện tượng nhảy hình không?
431
+ - Có thay đổi ngoài ý muốn không?
432
+ - Bố cục có bị lệch không?
433
+ - Chuyển động có đúng yêu cầu không?
434
+ ```
435
+
436
+ Nếu phát hiện lỗi, chỉ quay lại frame hoặc layer bị lỗi để sửa.
437
+
438
+ Không được tạo lại toàn bộ animation nếu chỉ một frame hoặc một layer bị lỗi.
439
+
440
+ ---
441
+
442
+ # 9. NGUYÊN TẮC TRẠNG THÁI BẮT BUỘC
443
+
444
+ Mọi thao tác phải tuân theo:
445
+
446
+ ```text
447
+ CHECK_CURRENT_STATE
448
+ → EXECUTE_CURRENT_STEP
449
+ → SAVE_STATE
450
+ → VALIDATE_RESULT
451
+ → WAIT_FOR_USER_IF_REQUIRED
452
+ → COMPLETE_CURRENT_STEP
453
+ → MOVE_TO_NEXT_STEP
454
+ ```
455
+
456
+ Không được:
457
+
458
+ ```text
459
+ CURRENT_STEP
460
+ → SKIP
461
+ → NEXT_STEP
462
+ ```
463
+
464
+ Mọi thao tác phải có trạng thái rõ ràng:
465
+
466
+ ```text
467
+ mode
468
+ step
469
+ layer
470
+ frame
471
+ status
472
+ user_approval
473
+ history
474
+ ```
475
+
476
+ Mục tiêu của hệ thống là đảm bảo toàn bộ quá trình tạo ảnh, sửa ảnh và tạo animation có thể kiểm soát, theo dõi, xem lại và tiếp tục chính xác từ bất kỳ bước nào mà không làm mất trạng thái trước đó.
package/rules/index.js ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * rules/index.js — Rules Module Aggregator
4
+ *
5
+ * Aggregates and exports all rules, workflow engine, and prerequisite tools.
6
+ *
7
+ * This module provides:
8
+ * 1. rules.js — Defines rules (naming, constraints, validators)
9
+ * 2. workflow.js — Workflow engine (manages step order)
10
+ * 3. prerequisites.js — MCP Tools for workflow (start, status, advance, validate)
11
+ *
12
+ * How to add a new rule:
13
+ * - Add to rules.js (NAMING_RULES, WORKFLOW_STEPS, DRAWING_CONSTRAINTS)
14
+ * - If complex logic is needed, create a new file in rules/ and import it here
15
+ */
16
+
17
+ const rules = require('./rules');
18
+ const workflow = require('./workflow');
19
+ const prerequisites = require('./prerequisites');
20
+
21
+ /**
22
+ * Register all workflow/prerequisite tools to the MCP server
23
+ * @param {McpServer} server
24
+ */
25
+ function registerAll(server) {
26
+ prerequisites.register(server);
27
+ }
28
+
29
+ module.exports = {
30
+ rules,
31
+ workflow,
32
+ prerequisites,
33
+ registerAll,
34
+ };