@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.
- package/core/command-bus.js +6 -3
- package/core/server.js +98 -3
- package/index.js +4 -0
- package/package.json +1 -1
- package/rules/README.md +476 -0
- package/rules/index.js +34 -0
- package/rules/prerequisites.js +202 -0
- package/rules/rules.js +152 -0
- package/rules/workflow.js +406 -0
- package/tools/{anchors.js → anchor-tools.js} +1 -1
- package/tools/{animation.js → animation-tools.js} +1 -1
- package/tools/{canvas.js → canvas-tools.js} +1 -1
- package/tools/{colors.js → color-tools.js} +1 -1
- package/tools/{drawing.js → drawing-tools.js} +1 -1
- package/tools/{filters.js → filter-tools.js} +1 -1
- package/tools/{health.js → health-tools.js} +1 -1
- package/tools/{history.js → history-tools.js} +1 -1
- package/tools/index.js +30 -14
- package/tools/{layer.js → layer-tools.js} +2 -2
- package/tools/{modes.js → mode-tools.js} +1 -1
- package/tools/{query.js → query-tools.js} +1 -1
- package/tools/{region.js → region-tools.js} +1 -1
- package/tools/{sprite.js → sprite-tools.js} +1 -1
- package/tools/{workspace.js → workspace-tools.js} +2 -3
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* workflow.js — Workflow Engine (Strict step ordering with modes, phases, layers)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { WORKFLOW_STEPS, MODES, STATUSES, DRAWING_PHASES } = require('./rules');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const STATE_FILE = path.join(__dirname, '..', 'workflow_state.json');
|
|
11
|
+
let sessions = new Map();
|
|
12
|
+
|
|
13
|
+
// --- PERSISTENCE ---
|
|
14
|
+
function saveState() {
|
|
15
|
+
const data = {};
|
|
16
|
+
for (const [key, val] of sessions.entries()) {
|
|
17
|
+
data[key] = val;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
fs.writeFileSync(STATE_FILE, JSON.stringify(data, null, 2), 'utf-8');
|
|
21
|
+
} catch (e) {
|
|
22
|
+
console.error('Failed to save workflow state:', e);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function loadState() {
|
|
27
|
+
if (fs.existsSync(STATE_FILE)) {
|
|
28
|
+
try {
|
|
29
|
+
const content = fs.readFileSync(STATE_FILE, 'utf-8');
|
|
30
|
+
const data = JSON.parse(content);
|
|
31
|
+
sessions = new Map(Object.entries(data));
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.error('Failed to load workflow state:', e);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Load state on startup
|
|
39
|
+
loadState();
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Start a new workflow for a session
|
|
44
|
+
* @param {string} sessionId - Session ID (usually MCP_SESSION)
|
|
45
|
+
* @param {string} mode - The mode to start in (CREATE_IMAGE, EDIT_IMAGE, CREATE_ANIMATION)
|
|
46
|
+
* @returns {Object} Initial workflow state
|
|
47
|
+
*/
|
|
48
|
+
function start(sessionId, mode = MODES.CREATE_IMAGE) {
|
|
49
|
+
if (!WORKFLOW_STEPS[mode]) {
|
|
50
|
+
throw new Error(`Invalid mode: ${mode}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const state = {
|
|
54
|
+
current_mode: mode,
|
|
55
|
+
currentStepIndex: 0,
|
|
56
|
+
steps: WORKFLOW_STEPS[mode].map(s => ({ ...s, status: STATUSES.PENDING })),
|
|
57
|
+
current_layer: 0,
|
|
58
|
+
current_frame: mode === MODES.CREATE_ANIMATION ? 0 : null,
|
|
59
|
+
current_phase: null,
|
|
60
|
+
animation_meta: { fps: null, total_frames: null, loop: true },
|
|
61
|
+
step_status: STATUSES.IN_PROGRESS,
|
|
62
|
+
user_approval_required: false,
|
|
63
|
+
user_input_request: null, // { id, type, fields, status, created_at, response }
|
|
64
|
+
step_completion_flags: {}, // track internal flags for steps
|
|
65
|
+
completedSteps: [],
|
|
66
|
+
history: [],
|
|
67
|
+
startedAt: Date.now(),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
sessions.set(sessionId, state);
|
|
71
|
+
saveState();
|
|
72
|
+
return getState(sessionId);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get current workflow state
|
|
77
|
+
* @param {string} sessionId
|
|
78
|
+
* @returns {Object|null}
|
|
79
|
+
*/
|
|
80
|
+
function getState(sessionId) {
|
|
81
|
+
return sessions.get(sessionId) || null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Get current step
|
|
86
|
+
* @param {string} sessionId
|
|
87
|
+
* @returns {Object|null}
|
|
88
|
+
*/
|
|
89
|
+
function getCurrentStep(sessionId) {
|
|
90
|
+
const state = sessions.get(sessionId);
|
|
91
|
+
if (!state) return null;
|
|
92
|
+
return state.steps[state.currentStepIndex] || null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Check if the agent is allowed to perform this action
|
|
97
|
+
* @param {string} sessionId
|
|
98
|
+
* @param {string} stepId - ID of the step to perform
|
|
99
|
+
* @returns {{ allowed: boolean, message?: string, currentStep?: Object }}
|
|
100
|
+
*/
|
|
101
|
+
function validateStep(sessionId, stepId) {
|
|
102
|
+
const state = sessions.get(sessionId);
|
|
103
|
+
if (!state) {
|
|
104
|
+
return {
|
|
105
|
+
allowed: false,
|
|
106
|
+
message: '⚠️ Workflow has not started. Call workflow_start first!',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (state.user_approval_required) {
|
|
111
|
+
return {
|
|
112
|
+
allowed: false,
|
|
113
|
+
message: '⛔ Workflow is waiting for user approval. Ask the user for confirmation.',
|
|
114
|
+
currentStep: state.steps[state.currentStepIndex]
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const current = state.steps[state.currentStepIndex];
|
|
119
|
+
if (!current) {
|
|
120
|
+
return {
|
|
121
|
+
allowed: false,
|
|
122
|
+
message: '✅ Workflow is complete! No remaining steps.',
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const targetIndex = state.steps.findIndex(s => s.id === stepId);
|
|
127
|
+
if (targetIndex === -1) {
|
|
128
|
+
return {
|
|
129
|
+
allowed: false,
|
|
130
|
+
message: `❌ Step "${stepId}" not found in current mode workflow.`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (targetIndex < state.currentStepIndex) {
|
|
135
|
+
return {
|
|
136
|
+
allowed: true,
|
|
137
|
+
message: `⚠️ Step "${stepId}" was already completed. Are you sure you want to redo it?`,
|
|
138
|
+
currentStep: current,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (targetIndex === state.currentStepIndex) {
|
|
143
|
+
return {
|
|
144
|
+
allowed: true,
|
|
145
|
+
currentStep: current,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
allowed: false,
|
|
151
|
+
message: `⛔ You cannot perform "${stepId}" yet. First complete: "${current.label}" (${current.description})`,
|
|
152
|
+
currentStep: current,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Set user approval requirement
|
|
158
|
+
* @param {string} sessionId
|
|
159
|
+
* @param {boolean} required
|
|
160
|
+
*/
|
|
161
|
+
function setApprovalRequired(sessionId, required) {
|
|
162
|
+
const state = sessions.get(sessionId);
|
|
163
|
+
if (!state) return false;
|
|
164
|
+
state.user_approval_required = required;
|
|
165
|
+
if (required) {
|
|
166
|
+
state.step_status = STATUSES.WAITING_FOR_USER;
|
|
167
|
+
} else {
|
|
168
|
+
if (state.user_input_request && state.user_input_request.status === 'WAITING_FOR_USER') {
|
|
169
|
+
return false; // Cannot unpause if waiting for explicit input request
|
|
170
|
+
}
|
|
171
|
+
state.step_status = STATUSES.IN_PROGRESS;
|
|
172
|
+
}
|
|
173
|
+
saveState();
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Create a user input request
|
|
179
|
+
* @param {string} sessionId
|
|
180
|
+
* @param {string} type - e.g. CANVAS_SIZE, APPROVE_PLAN, SELECT_EDIT_REGION
|
|
181
|
+
* @param {Object} fields - fields required
|
|
182
|
+
*/
|
|
183
|
+
function createInputRequest(sessionId, type, fields = {}) {
|
|
184
|
+
const state = sessions.get(sessionId);
|
|
185
|
+
if (!state) return false;
|
|
186
|
+
|
|
187
|
+
state.user_input_request = {
|
|
188
|
+
id: `req_${Date.now()}_${Math.floor(Math.random()*1000)}`,
|
|
189
|
+
type,
|
|
190
|
+
fields,
|
|
191
|
+
status: 'WAITING_FOR_USER',
|
|
192
|
+
created_at: Date.now()
|
|
193
|
+
};
|
|
194
|
+
state.step_status = STATUSES.WAITING_FOR_USER;
|
|
195
|
+
state.history.push({ event: 'input_request_created', type, time: Date.now() });
|
|
196
|
+
saveState();
|
|
197
|
+
return state.user_input_request.id;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Complete a user input request
|
|
202
|
+
* @param {string} sessionId
|
|
203
|
+
* @param {string} reqId
|
|
204
|
+
* @param {string} response
|
|
205
|
+
*/
|
|
206
|
+
function completeInputRequest(sessionId, reqId, response) {
|
|
207
|
+
const state = sessions.get(sessionId);
|
|
208
|
+
if (!state || !state.user_input_request || state.user_input_request.id !== reqId) return false;
|
|
209
|
+
|
|
210
|
+
state.user_input_request.status = 'COMPLETED';
|
|
211
|
+
state.user_input_request.response = response;
|
|
212
|
+
state.step_status = STATUSES.IN_PROGRESS; // Unpause workflow
|
|
213
|
+
|
|
214
|
+
state.history.push({ event: 'input_request_completed', reqId, time: Date.now() });
|
|
215
|
+
saveState();
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Update layer/frame
|
|
221
|
+
*/
|
|
222
|
+
function setLayerAndFrame(sessionId, layer, frame = null) {
|
|
223
|
+
const state = sessions.get(sessionId);
|
|
224
|
+
if (!state) return false;
|
|
225
|
+
|
|
226
|
+
if (layer !== undefined && layer !== null) {
|
|
227
|
+
state.current_layer = layer;
|
|
228
|
+
}
|
|
229
|
+
if (frame !== undefined && frame !== null) {
|
|
230
|
+
state.current_frame = frame;
|
|
231
|
+
}
|
|
232
|
+
state.history.push({
|
|
233
|
+
event: 'layer_frame_change',
|
|
234
|
+
layer: state.current_layer,
|
|
235
|
+
frame: state.current_frame,
|
|
236
|
+
time: Date.now()
|
|
237
|
+
});
|
|
238
|
+
saveState();
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Update phase
|
|
244
|
+
*/
|
|
245
|
+
function setPhase(sessionId, phase) {
|
|
246
|
+
const state = sessions.get(sessionId);
|
|
247
|
+
if (!state) return false;
|
|
248
|
+
|
|
249
|
+
state.current_phase = phase;
|
|
250
|
+
state.history.push({
|
|
251
|
+
event: 'phase_change',
|
|
252
|
+
phase: phase,
|
|
253
|
+
time: Date.now()
|
|
254
|
+
});
|
|
255
|
+
saveState();
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Set animation meta
|
|
261
|
+
*/
|
|
262
|
+
function setAnimationMeta(sessionId, fps, total_frames, loop) {
|
|
263
|
+
const state = sessions.get(sessionId);
|
|
264
|
+
if (!state) return false;
|
|
265
|
+
|
|
266
|
+
if (fps !== undefined) state.animation_meta.fps = fps;
|
|
267
|
+
if (total_frames !== undefined) state.animation_meta.total_frames = total_frames;
|
|
268
|
+
if (loop !== undefined) state.animation_meta.loop = loop;
|
|
269
|
+
|
|
270
|
+
saveState();
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Set step completion flag (internal validation)
|
|
276
|
+
*/
|
|
277
|
+
function setStepFlag(sessionId, flagName, value) {
|
|
278
|
+
const state = sessions.get(sessionId);
|
|
279
|
+
if (!state) return false;
|
|
280
|
+
state.step_completion_flags[flagName] = value;
|
|
281
|
+
saveState();
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Mark current step as completed and advance to the next step
|
|
287
|
+
* @param {string} sessionId
|
|
288
|
+
* @returns {Object} Step transition result
|
|
289
|
+
*/
|
|
290
|
+
function advance(sessionId) {
|
|
291
|
+
const state = sessions.get(sessionId);
|
|
292
|
+
if (!state) {
|
|
293
|
+
return { success: false, message: 'Workflow has not started' };
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (state.user_approval_required) {
|
|
297
|
+
return { success: false, message: 'Cannot advance: Waiting for user approval.' };
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (state.step_status === STATUSES.WAITING_FOR_USER) {
|
|
301
|
+
return { success: false, message: 'Cannot advance: Waiting for user approval or input.' };
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const current = state.steps[state.currentStepIndex];
|
|
305
|
+
if (!current) {
|
|
306
|
+
return { success: false, message: 'Workflow is complete' };
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Pre-condition validation block
|
|
310
|
+
if (current.id === 'INITIALIZE_CANVAS' && !state.step_completion_flags.canvas_initialized) {
|
|
311
|
+
return { success: false, message: 'Cannot advance: Canvas has not been initialized. Create a canvas first.' };
|
|
312
|
+
}
|
|
313
|
+
if (current.id === 'PLAN_DRAWING' && !state.step_completion_flags.plan_created) {
|
|
314
|
+
return { success: false, message: 'Cannot advance: Drawing plan has not been finalized.' };
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
current.status = STATUSES.COMPLETED;
|
|
318
|
+
state.completedSteps.push(current.id);
|
|
319
|
+
state.history.push({ event: 'step_completed', step: current.id, layer: state.current_layer, frame: state.current_frame, time: Date.now() });
|
|
320
|
+
|
|
321
|
+
state.currentStepIndex++;
|
|
322
|
+
|
|
323
|
+
const next = state.steps[state.currentStepIndex] || null;
|
|
324
|
+
if (next) {
|
|
325
|
+
next.status = STATUSES.IN_PROGRESS;
|
|
326
|
+
state.step_status = STATUSES.IN_PROGRESS;
|
|
327
|
+
saveState();
|
|
328
|
+
return {
|
|
329
|
+
success: true,
|
|
330
|
+
completedStep: current,
|
|
331
|
+
nextStep: next,
|
|
332
|
+
message: `✅ Completed: "${current.label}". Next step: "${next.label}" — ${next.description}`,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
state.step_status = STATUSES.COMPLETED;
|
|
337
|
+
saveState();
|
|
338
|
+
return {
|
|
339
|
+
success: true,
|
|
340
|
+
completedStep: current,
|
|
341
|
+
nextStep: null,
|
|
342
|
+
message: `🎉 All steps completed! The task is ready.`,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Reset workflow to the beginning
|
|
348
|
+
* @param {string} sessionId
|
|
349
|
+
*/
|
|
350
|
+
function reset(sessionId) {
|
|
351
|
+
const state = sessions.get(sessionId);
|
|
352
|
+
const mode = state ? state.current_mode : MODES.CREATE_IMAGE;
|
|
353
|
+
sessions.delete(sessionId);
|
|
354
|
+
saveState();
|
|
355
|
+
return start(sessionId, mode);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Get text-based progress report for the agent
|
|
360
|
+
* @param {string} sessionId
|
|
361
|
+
* @returns {string}
|
|
362
|
+
*/
|
|
363
|
+
function getProgressReport(sessionId) {
|
|
364
|
+
const state = sessions.get(sessionId);
|
|
365
|
+
if (!state) return 'Workflow has not started.';
|
|
366
|
+
|
|
367
|
+
const lines = [
|
|
368
|
+
`📋 **Workflow Progress: [Mode: ${state.current_mode}]**`,
|
|
369
|
+
`Layer: ${state.current_layer} | Frame: ${state.current_frame !== null ? state.current_frame : 'N/A'}`,
|
|
370
|
+
`Phase: ${state.current_phase !== null ? state.current_phase : 'N/A'}`,
|
|
371
|
+
`Animation Meta: FPS=${state.animation_meta.fps || 'N/A'}, Frames=${state.animation_meta.total_frames || 'N/A'}, Loop=${state.animation_meta.loop}`,
|
|
372
|
+
`Status: ${state.step_status}`,
|
|
373
|
+
`User Approval Required: ${state.user_approval_required ? 'YES' : 'NO'}`,
|
|
374
|
+
state.user_input_request && state.user_input_request.status === 'WAITING_FOR_USER' ? `⚠️ PENDING REQUEST: ${state.user_input_request.type}` : '',
|
|
375
|
+
`\n**Steps:**`
|
|
376
|
+
];
|
|
377
|
+
|
|
378
|
+
state.steps.forEach((step, i) => {
|
|
379
|
+
const icon = step.status === STATUSES.COMPLETED ? '✅' :
|
|
380
|
+
step.status === STATUSES.IN_PROGRESS ? '🔄' : '⬜';
|
|
381
|
+
const marker = i === state.currentStepIndex ? ' ← **IN PROGRESS**' : '';
|
|
382
|
+
lines.push(`${icon} **${step.label}**${marker}`);
|
|
383
|
+
if (step.status === STATUSES.IN_PROGRESS || i === state.currentStepIndex) {
|
|
384
|
+
lines.push(` → ${step.description}`);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
return lines.join('\n');
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
module.exports = {
|
|
392
|
+
start,
|
|
393
|
+
getState,
|
|
394
|
+
getCurrentStep,
|
|
395
|
+
validateStep,
|
|
396
|
+
advance,
|
|
397
|
+
reset,
|
|
398
|
+
getProgressReport,
|
|
399
|
+
setApprovalRequired,
|
|
400
|
+
createInputRequest,
|
|
401
|
+
completeInputRequest,
|
|
402
|
+
setLayerAndFrame,
|
|
403
|
+
setPhase,
|
|
404
|
+
setAnimationMeta,
|
|
405
|
+
setStepFlag
|
|
406
|
+
};
|
package/tools/index.js
CHANGED
|
@@ -4,21 +4,37 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Imports and registers all core drawing/utility tools on an MCP server instance.
|
|
6
6
|
* To add a new tool category, create a new file in this folder and add it here.
|
|
7
|
+
*
|
|
8
|
+
* File naming convention: {category}-tools.js
|
|
9
|
+
* - canvas-tools.js → Canvas operations
|
|
10
|
+
* - workspace-tools.js → Tab/workspace management
|
|
11
|
+
* - animation-tools.js → Animation frames
|
|
12
|
+
* - drawing-tools.js → Drawing primitives
|
|
13
|
+
* - sprite-tools.js → Sprite/stamp system
|
|
14
|
+
* - region-tools.js → Region clipboard
|
|
15
|
+
* - filter-tools.js → Visual filters
|
|
16
|
+
* - anchor-tools.js → Coordinate anchors
|
|
17
|
+
* - query-tools.js → Query & visual feedback
|
|
18
|
+
* - history-tools.js → Undo/redo
|
|
19
|
+
* - mode-tools.js → Mode settings
|
|
20
|
+
* - color-tools.js → Color management
|
|
21
|
+
* - health-tools.js → Health check
|
|
22
|
+
* - layer-tools.js → Layer management
|
|
7
23
|
*/
|
|
8
|
-
const canvas = require('./canvas');
|
|
9
|
-
const workspace = require('./workspace');
|
|
10
|
-
const animation = require('./animation');
|
|
11
|
-
const drawing = require('./drawing');
|
|
12
|
-
const sprite = require('./sprite');
|
|
13
|
-
const region = require('./region');
|
|
14
|
-
const filters = require('./
|
|
15
|
-
const anchors = require('./
|
|
16
|
-
const query = require('./query');
|
|
17
|
-
const history = require('./history');
|
|
18
|
-
const modes = require('./
|
|
19
|
-
const colors = require('./
|
|
20
|
-
const health = require('./health');
|
|
21
|
-
const layer = require('./layer');
|
|
24
|
+
const canvas = require('./canvas-tools');
|
|
25
|
+
const workspace = require('./workspace-tools');
|
|
26
|
+
const animation = require('./animation-tools');
|
|
27
|
+
const drawing = require('./drawing-tools');
|
|
28
|
+
const sprite = require('./sprite-tools');
|
|
29
|
+
const region = require('./region-tools');
|
|
30
|
+
const filters = require('./filter-tools');
|
|
31
|
+
const anchors = require('./anchor-tools');
|
|
32
|
+
const query = require('./query-tools');
|
|
33
|
+
const history = require('./history-tools');
|
|
34
|
+
const modes = require('./mode-tools');
|
|
35
|
+
const colors = require('./color-tools');
|
|
36
|
+
const health = require('./health-tools');
|
|
37
|
+
const layer = require('./layer-tools');
|
|
22
38
|
|
|
23
39
|
/**
|
|
24
40
|
* Register all core tools on the given MCP server instance.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* layer.js — MCP Tool Registration for Layers
|
|
3
|
+
* layer-tools.js — MCP Tool Registration for Layers
|
|
4
4
|
*
|
|
5
5
|
* Exposes the layer management functionality to MCP clients.
|
|
6
6
|
*/
|
|
@@ -77,4 +77,4 @@ function register(server) {
|
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
module.exports = { register };
|
|
80
|
+
module.exports = { register };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* workspace.js — Workspace / Tabs tools
|
|
3
|
+
* workspace-tools.js — Workspace / Tabs tools
|
|
4
4
|
*
|
|
5
5
|
* Tools: workspace_list_tabs, workspace_get_active_tab, workspace_create_tab,
|
|
6
6
|
* workspace_switch_tab, workspace_rename_tab, workspace_save
|
|
7
7
|
*/
|
|
8
8
|
const { z } = require('zod');
|
|
9
|
-
const { registerTool } = require('../core/server');
|
|
9
|
+
const { registerTool, sendCommand } = require('../core/server');
|
|
10
10
|
|
|
11
11
|
function register(server) {
|
|
12
12
|
registerTool(server, 'workspace_list_tabs',
|
|
@@ -19,7 +19,6 @@ function register(server) {
|
|
|
19
19
|
{},
|
|
20
20
|
() => ({ action: 'getActiveTabId' }));
|
|
21
21
|
|
|
22
|
-
const { sendCommand } = require('../core/server');
|
|
23
22
|
server.tool('workspace_create_tab',
|
|
24
23
|
'Create a new blank canvas tab',
|
|
25
24
|
{
|