indesign-cli 0.2.0__py3-none-any.whl
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.
- cli_anything/indesign/README.md +32 -0
- cli_anything/indesign/__init__.py +1 -0
- cli_anything/indesign/__main__.py +5 -0
- cli_anything/indesign/core/artifacts.py +57 -0
- cli_anything/indesign/core/catalog.py +405 -0
- cli_anything/indesign/core/domains.py +178 -0
- cli_anything/indesign/core/envelope.py +65 -0
- cli_anything/indesign/core/errors.py +30 -0
- cli_anything/indesign/core/health.py +46 -0
- cli_anything/indesign/core/hidden_backend.py +116 -0
- cli_anything/indesign/core/hidden_handler_schemas.py +223 -0
- cli_anything/indesign/core/mcp_backend.py +152 -0
- cli_anything/indesign/core/node_setup.py +35 -0
- cli_anything/indesign/core/paths.py +41 -0
- cli_anything/indesign/core/plugins/__init__.py +2 -0
- cli_anything/indesign/core/plugins/backend.py +90 -0
- cli_anything/indesign/core/plugins/discovery.py +69 -0
- cli_anything/indesign/core/plugins/host_actions.py +76 -0
- cli_anything/indesign/core/plugins/install.py +38 -0
- cli_anything/indesign/core/plugins/manifest.py +279 -0
- cli_anything/indesign/core/plugins/validate.py +181 -0
- cli_anything/indesign/core/router.py +217 -0
- cli_anything/indesign/core/runtime.py +59 -0
- cli_anything/indesign/core/scripts.py +44 -0
- cli_anything/indesign/core/session.py +68 -0
- cli_anything/indesign/indesign_cli.py +320 -0
- cli_anything/indesign/node/hidden_handler_bridge.mjs +111 -0
- cli_anything/indesign/server/package-lock.json +168 -0
- cli_anything/indesign/server/package.json +45 -0
- cli_anything/indesign/server/src/advanced/index.js +76 -0
- cli_anything/indesign/server/src/core/InDesignMCPServer.js +273 -0
- cli_anything/indesign/server/src/core/scriptExecutor.js +271 -0
- cli_anything/indesign/server/src/core/sessionManager.js +545 -0
- cli_anything/indesign/server/src/handlers/advancedTemplateHandlers.js +1072 -0
- cli_anything/indesign/server/src/handlers/bookHandlers.js +490 -0
- cli_anything/indesign/server/src/handlers/documentHandlers.js +1472 -0
- cli_anything/indesign/server/src/handlers/exportHandlers.js +208 -0
- cli_anything/indesign/server/src/handlers/graphicsHandlers.js +605 -0
- cli_anything/indesign/server/src/handlers/groupHandlers.js +358 -0
- cli_anything/indesign/server/src/handlers/helpHandlers.js +347 -0
- cli_anything/indesign/server/src/handlers/index.js +77 -0
- cli_anything/indesign/server/src/handlers/layerHandlers.js +75 -0
- cli_anything/indesign/server/src/handlers/masterSpreadHandlers.js +451 -0
- cli_anything/indesign/server/src/handlers/pageHandlers.js +698 -0
- cli_anything/indesign/server/src/handlers/pageItemHandlers.js +704 -0
- cli_anything/indesign/server/src/handlers/presentationHandlers.js +220 -0
- cli_anything/indesign/server/src/handlers/spreadHandlers.js +348 -0
- cli_anything/indesign/server/src/handlers/styleHandlers.js +458 -0
- cli_anything/indesign/server/src/handlers/textHandlers.js +431 -0
- cli_anything/indesign/server/src/handlers/utilityHandlers.js +83 -0
- cli_anything/indesign/server/src/index.js +17 -0
- cli_anything/indesign/server/src/types/index.js +106 -0
- cli_anything/indesign/server/src/types/toolDefinitionsAdvancedTemplates.js +144 -0
- cli_anything/indesign/server/src/types/toolDefinitionsBook.js +224 -0
- cli_anything/indesign/server/src/types/toolDefinitionsContent.js +353 -0
- cli_anything/indesign/server/src/types/toolDefinitionsDocument.js +409 -0
- cli_anything/indesign/server/src/types/toolDefinitionsExport.js +65 -0
- cli_anything/indesign/server/src/types/toolDefinitionsLayer.js +40 -0
- cli_anything/indesign/server/src/types/toolDefinitionsMasterSpread.js +160 -0
- cli_anything/indesign/server/src/types/toolDefinitionsPage.js +271 -0
- cli_anything/indesign/server/src/types/toolDefinitionsPageItemGroup.js +437 -0
- cli_anything/indesign/server/src/types/toolDefinitionsPresentation.js +83 -0
- cli_anything/indesign/server/src/types/toolDefinitionsSpread.js +158 -0
- cli_anything/indesign/server/src/types/toolDefinitionsUtility.js +40 -0
- cli_anything/indesign/server/src/utils/stringUtils.js +107 -0
- cli_anything/indesign/skills/SKILL.md +198 -0
- indesign_cli-0.2.0.dist-info/METADATA +267 -0
- indesign_cli-0.2.0.dist-info/RECORD +72 -0
- indesign_cli-0.2.0.dist-info/WHEEL +5 -0
- indesign_cli-0.2.0.dist-info/entry_points.txt +3 -0
- indesign_cli-0.2.0.dist-info/licenses/LICENSE +21 -0
- indesign_cli-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,704 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PageItem management handlers
|
|
3
|
+
*/
|
|
4
|
+
import { ScriptExecutor } from '../core/scriptExecutor.js';
|
|
5
|
+
import { formatResponse, formatErrorResponse, escapeJsxString } from '../utils/stringUtils.js';
|
|
6
|
+
|
|
7
|
+
const JSON_SERIALIZER_SNIPPET = `
|
|
8
|
+
function __mcpEscapeJsonString(str) {
|
|
9
|
+
if (str === null || str === undefined) return "";
|
|
10
|
+
var result = "";
|
|
11
|
+
for (var i = 0; i < str.length; i++) {
|
|
12
|
+
var ch = str.charAt(i);
|
|
13
|
+
var code = str.charCodeAt(i);
|
|
14
|
+
if (ch === '"' || ch === '\\\\') {
|
|
15
|
+
result += '\\\\' + ch;
|
|
16
|
+
} else if (code === 8) {
|
|
17
|
+
result += '\\\\b';
|
|
18
|
+
} else if (code === 9) {
|
|
19
|
+
result += '\\\\t';
|
|
20
|
+
} else if (code === 10) {
|
|
21
|
+
result += '\\\\n';
|
|
22
|
+
} else if (code === 12) {
|
|
23
|
+
result += '\\\\f';
|
|
24
|
+
} else if (code === 13) {
|
|
25
|
+
result += '\\\\r';
|
|
26
|
+
} else if (code < 32) {
|
|
27
|
+
var hex = code.toString(16);
|
|
28
|
+
result += '\\\\u' + ('0000' + hex).slice(-4);
|
|
29
|
+
} else {
|
|
30
|
+
result += ch;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
function __mcpSerializeValue(value) {
|
|
36
|
+
if (value === null || value === undefined) return "null";
|
|
37
|
+
var type = typeof value;
|
|
38
|
+
if (type === "number" || type === "boolean") {
|
|
39
|
+
return String(value);
|
|
40
|
+
}
|
|
41
|
+
if (type === "string") {
|
|
42
|
+
return "\\""+__mcpEscapeJsonString(value)+"\\"";
|
|
43
|
+
}
|
|
44
|
+
if (value instanceof Array) {
|
|
45
|
+
var arr = [];
|
|
46
|
+
for (var i = 0; i < value.length; i++) {
|
|
47
|
+
arr.push(__mcpSerializeValue(value[i]));
|
|
48
|
+
}
|
|
49
|
+
return "[" + arr.join(",") + "]";
|
|
50
|
+
}
|
|
51
|
+
if (type === "object") {
|
|
52
|
+
var props = [];
|
|
53
|
+
for (var key in value) {
|
|
54
|
+
if (!value.hasOwnProperty(key)) continue;
|
|
55
|
+
var propertyValue = value[key];
|
|
56
|
+
if (propertyValue === undefined) continue;
|
|
57
|
+
props.push("\\"" + __mcpEscapeJsonString(key) + "\\":" + __mcpSerializeValue(propertyValue));
|
|
58
|
+
}
|
|
59
|
+
return "{" + props.join(",") + "}";
|
|
60
|
+
}
|
|
61
|
+
return "null";
|
|
62
|
+
}
|
|
63
|
+
function __mcpSerializeResponse(success, payload, errorMessage) {
|
|
64
|
+
var response = { success: success ? true : false };
|
|
65
|
+
if (response.success) {
|
|
66
|
+
response.data = (payload === undefined) ? [] : payload;
|
|
67
|
+
} else {
|
|
68
|
+
response.error = errorMessage || "";
|
|
69
|
+
}
|
|
70
|
+
return __mcpSerializeValue(response);
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
const PAGE_ITEM_LABEL_HELPERS_SNIPPET = `
|
|
75
|
+
function __mcpFindPageByNumber(doc, pageNumber) {
|
|
76
|
+
if (!doc || !doc.isValid) return null;
|
|
77
|
+
for (var i = 0; i < doc.pages.length; i++) {
|
|
78
|
+
var page = doc.pages[i];
|
|
79
|
+
try {
|
|
80
|
+
if ((page.documentOffset + 1) === pageNumber) {
|
|
81
|
+
return page;
|
|
82
|
+
}
|
|
83
|
+
} catch (_offsetErr) {}
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
function __mcpFindItemIndexOnPage(page, itemId) {
|
|
88
|
+
if (!page || !page.isValid) return -1;
|
|
89
|
+
var items = page.allPageItems;
|
|
90
|
+
for (var i = 0; i < items.length; i++) {
|
|
91
|
+
if (items[i].id === itemId) {
|
|
92
|
+
return i;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return -1;
|
|
96
|
+
}
|
|
97
|
+
function __mcpFindItemById(page, objectId) {
|
|
98
|
+
if (!page || !page.isValid) return null;
|
|
99
|
+
var items = page.allPageItems;
|
|
100
|
+
for (var i = 0; i < items.length; i++) {
|
|
101
|
+
if (items[i].id === objectId) {
|
|
102
|
+
return items[i];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
`;
|
|
108
|
+
|
|
109
|
+
function parseJsonResult(raw, operationName) {
|
|
110
|
+
const trimmed = (raw ?? '').trim();
|
|
111
|
+
if (!trimmed) {
|
|
112
|
+
return { success: true, data: [] };
|
|
113
|
+
}
|
|
114
|
+
if (trimmed.startsWith('Error:')) {
|
|
115
|
+
const message = trimmed.slice(6).trim() || `${operationName} failed inside InDesign`;
|
|
116
|
+
return { success: false, error: message };
|
|
117
|
+
}
|
|
118
|
+
let parsed;
|
|
119
|
+
try {
|
|
120
|
+
parsed = JSON.parse(trimmed);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
return { success: false, error: `Unable to parse InDesign response for ${operationName}: ${error.message}` };
|
|
123
|
+
}
|
|
124
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
125
|
+
return { success: false, error: `${operationName} returned an unexpected result` };
|
|
126
|
+
}
|
|
127
|
+
if (parsed.success === false) {
|
|
128
|
+
return { success: false, error: parsed.error || `${operationName} failed` };
|
|
129
|
+
}
|
|
130
|
+
return { success: true, data: parsed.data ?? [] };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
export class PageItemHandlers {
|
|
135
|
+
/**
|
|
136
|
+
* Get information about a page item
|
|
137
|
+
*/
|
|
138
|
+
static async getPageItemInfo(args) {
|
|
139
|
+
const { pageIndex, itemIndex } = args;
|
|
140
|
+
|
|
141
|
+
const script = [
|
|
142
|
+
'if (app.documents.length === 0) {',
|
|
143
|
+
' "No document open";',
|
|
144
|
+
'} else {',
|
|
145
|
+
' var doc = app.activeDocument;',
|
|
146
|
+
` if (${pageIndex} >= doc.pages.length) {`,
|
|
147
|
+
' "Page index out of range";',
|
|
148
|
+
' } else {',
|
|
149
|
+
` var page = doc.pages[${pageIndex}];`,
|
|
150
|
+
` if (${itemIndex} >= page.allPageItems.length) {`,
|
|
151
|
+
' "Page item index out of range";',
|
|
152
|
+
' } else {',
|
|
153
|
+
` var item = page.allPageItems[${itemIndex}];`,
|
|
154
|
+
' var info = "=== PAGE ITEM INFO ===\\n";',
|
|
155
|
+
' info += "Type: " + item.constructor.name + "\\n";',
|
|
156
|
+
' info += "Name: " + (item.name || "Unnamed") + "\\n";',
|
|
157
|
+
' info += "ID: " + item.id + "\\n";',
|
|
158
|
+
' info += "Visible: " + item.visible + "\\n";',
|
|
159
|
+
' info += "Locked: " + item.locked + "\\n";',
|
|
160
|
+
' info += "Bounds: " + item.geometricBounds.join(", ") + "\\n";',
|
|
161
|
+
' info += "Fill Color: " + (item.fillColor ? item.fillColor.name : "None") + "\\n";',
|
|
162
|
+
' info += "Stroke Color: " + (item.strokeColor ? item.strokeColor.name : "None") + "\\n";',
|
|
163
|
+
' info += "Stroke Weight: " + item.strokeWeight + "\\n";',
|
|
164
|
+
' info;',
|
|
165
|
+
' }',
|
|
166
|
+
' }',
|
|
167
|
+
'}'
|
|
168
|
+
].join('\n');
|
|
169
|
+
|
|
170
|
+
const result = await ScriptExecutor.executeInDesignScript(script);
|
|
171
|
+
return formatResponse(result, "Get Page Item Info");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Select a page item
|
|
176
|
+
*/
|
|
177
|
+
static async selectPageItem(args) {
|
|
178
|
+
const { pageIndex, itemIndex, existingSelection = 'REPLACE_WITH' } = args;
|
|
179
|
+
|
|
180
|
+
const script = [
|
|
181
|
+
'if (app.documents.length === 0) {',
|
|
182
|
+
' "No document open";',
|
|
183
|
+
'} else {',
|
|
184
|
+
' var doc = app.activeDocument;',
|
|
185
|
+
` if (${pageIndex} >= doc.pages.length) {`,
|
|
186
|
+
' "Page index out of range";',
|
|
187
|
+
' } else {',
|
|
188
|
+
` var page = doc.pages[${pageIndex}];`,
|
|
189
|
+
` if (${itemIndex} >= page.allPageItems.length) {`,
|
|
190
|
+
' "Page item index out of range";',
|
|
191
|
+
' } else {',
|
|
192
|
+
` var item = page.allPageItems[${itemIndex}];`,
|
|
193
|
+
` item.select(SelectionOptions.${existingSelection});`,
|
|
194
|
+
' "Page item selected successfully";',
|
|
195
|
+
' }',
|
|
196
|
+
' }',
|
|
197
|
+
'}'
|
|
198
|
+
].join('\n');
|
|
199
|
+
|
|
200
|
+
const result = await ScriptExecutor.executeInDesignScript(script);
|
|
201
|
+
return formatResponse(result, "Select Page Item");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Move a page item
|
|
206
|
+
*/
|
|
207
|
+
static async movePageItem(args) {
|
|
208
|
+
const { pageIndex, itemIndex, x, y } = args;
|
|
209
|
+
|
|
210
|
+
const script = [
|
|
211
|
+
'if (app.documents.length === 0) {',
|
|
212
|
+
' "No document open";',
|
|
213
|
+
'} else {',
|
|
214
|
+
' var doc = app.activeDocument;',
|
|
215
|
+
` if (${pageIndex} >= doc.pages.length) {`,
|
|
216
|
+
' "Page index out of range";',
|
|
217
|
+
' } else {',
|
|
218
|
+
` var page = doc.pages[${pageIndex}];`,
|
|
219
|
+
` if (${itemIndex} >= page.allPageItems.length) {`,
|
|
220
|
+
' "Page item index out of range";',
|
|
221
|
+
' } else {',
|
|
222
|
+
` var item = page.allPageItems[${itemIndex}];`,
|
|
223
|
+
` item.move([${x}, ${y}]);`,
|
|
224
|
+
' "Page item moved successfully";',
|
|
225
|
+
' }',
|
|
226
|
+
' }',
|
|
227
|
+
'}'
|
|
228
|
+
].join('\n');
|
|
229
|
+
|
|
230
|
+
const result = await ScriptExecutor.executeInDesignScript(script);
|
|
231
|
+
return formatResponse(result, "Move Page Item");
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Resize a page item
|
|
236
|
+
*/
|
|
237
|
+
static async resizePageItem(args) {
|
|
238
|
+
const { pageIndex, itemIndex, width, height, anchorPoint = 'CENTER_ANCHOR' } = args;
|
|
239
|
+
|
|
240
|
+
const script = [
|
|
241
|
+
'if (app.documents.length === 0) {',
|
|
242
|
+
' "No document open";',
|
|
243
|
+
'} else {',
|
|
244
|
+
' var doc = app.activeDocument;',
|
|
245
|
+
` if (${pageIndex} >= doc.pages.length) {`,
|
|
246
|
+
' "Page index out of range";',
|
|
247
|
+
' } else {',
|
|
248
|
+
` var page = doc.pages[${pageIndex}];`,
|
|
249
|
+
` if (${itemIndex} >= page.allPageItems.length) {`,
|
|
250
|
+
' "Page item index out of range";',
|
|
251
|
+
' } else {',
|
|
252
|
+
` var item = page.allPageItems[${itemIndex}];`,
|
|
253
|
+
' var bounds = item.geometricBounds;',
|
|
254
|
+
` item.geometricBounds = [bounds[0], bounds[1], bounds[0] + ${height}, bounds[1] + ${width}];`,
|
|
255
|
+
' "Page item resized successfully";',
|
|
256
|
+
' }',
|
|
257
|
+
' }',
|
|
258
|
+
'}'
|
|
259
|
+
].join('\n');
|
|
260
|
+
|
|
261
|
+
const result = await ScriptExecutor.executeInDesignScript(script);
|
|
262
|
+
return formatResponse(result, "Resize Page Item");
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Set page item properties
|
|
267
|
+
*/
|
|
268
|
+
static async setPageItemProperties(args) {
|
|
269
|
+
const { pageIndex, itemIndex, fillColor, strokeColor, strokeWeight, visible, locked } = args;
|
|
270
|
+
|
|
271
|
+
const fillColorLiteral = typeof fillColor === 'string' && fillColor !== ''
|
|
272
|
+
? JSON.stringify(escapeJsxString(fillColor))
|
|
273
|
+
: 'null';
|
|
274
|
+
const strokeColorLiteral = typeof strokeColor === 'string' && strokeColor !== ''
|
|
275
|
+
? JSON.stringify(escapeJsxString(strokeColor))
|
|
276
|
+
: 'null';
|
|
277
|
+
const strokeWeightLiteral = typeof strokeWeight === 'number' && !Number.isNaN(strokeWeight)
|
|
278
|
+
? strokeWeight
|
|
279
|
+
: 'null';
|
|
280
|
+
const visibleLiteral = typeof visible === 'boolean' ? visible : 'null';
|
|
281
|
+
const lockedLiteral = typeof locked === 'boolean' ? locked : 'null';
|
|
282
|
+
|
|
283
|
+
const script = [
|
|
284
|
+
'if (app.documents.length === 0) {',
|
|
285
|
+
' "No document open";',
|
|
286
|
+
'} else {',
|
|
287
|
+
' var doc = app.activeDocument;',
|
|
288
|
+
` if (${pageIndex} < 0 || ${pageIndex} >= doc.pages.length) {`,
|
|
289
|
+
' "Page index out of range";',
|
|
290
|
+
' } else {',
|
|
291
|
+
` var page = doc.pages[${pageIndex}];`,
|
|
292
|
+
` if (${itemIndex} < 0 || ${itemIndex} >= page.allPageItems.length) {`,
|
|
293
|
+
' "Page item index out of range";',
|
|
294
|
+
' } else {',
|
|
295
|
+
` var item = page.allPageItems[${itemIndex}];`,
|
|
296
|
+
' try {',
|
|
297
|
+
` var fillColorName = ${fillColorLiteral};`,
|
|
298
|
+
` var strokeColorName = ${strokeColorLiteral};`,
|
|
299
|
+
` var strokeWeightValue = ${strokeWeightLiteral};`,
|
|
300
|
+
` var visibleSetting = ${visibleLiteral};`,
|
|
301
|
+
` var lockedSetting = ${lockedLiteral};`,
|
|
302
|
+
'',
|
|
303
|
+
' if (fillColorName !== null) {',
|
|
304
|
+
' try {',
|
|
305
|
+
' var fillSwatch = doc.colors.itemByName(fillColorName);',
|
|
306
|
+
' if (!fillSwatch || !fillSwatch.isValid) {',
|
|
307
|
+
' throw new Error("Fill color not found: " + fillColorName);',
|
|
308
|
+
' }',
|
|
309
|
+
' item.fillColor = fillSwatch;',
|
|
310
|
+
' } catch (fillError) {',
|
|
311
|
+
' throw new Error("Unable to apply fill color: " + fillError.message);',
|
|
312
|
+
' }',
|
|
313
|
+
' }',
|
|
314
|
+
'',
|
|
315
|
+
' if (strokeColorName !== null) {',
|
|
316
|
+
' try {',
|
|
317
|
+
' var strokeSwatch = doc.colors.itemByName(strokeColorName);',
|
|
318
|
+
' if (!strokeSwatch || !strokeSwatch.isValid) {',
|
|
319
|
+
' throw new Error("Stroke color not found: " + strokeColorName);',
|
|
320
|
+
' }',
|
|
321
|
+
' item.strokeColor = strokeSwatch;',
|
|
322
|
+
' } catch (strokeError) {',
|
|
323
|
+
' throw new Error("Unable to apply stroke color: " + strokeError.message);',
|
|
324
|
+
' }',
|
|
325
|
+
' }',
|
|
326
|
+
'',
|
|
327
|
+
' if (strokeWeightValue !== null) {',
|
|
328
|
+
' item.strokeWeight = strokeWeightValue;',
|
|
329
|
+
' }',
|
|
330
|
+
'',
|
|
331
|
+
' if (visibleSetting !== null) {',
|
|
332
|
+
' item.visible = visibleSetting;',
|
|
333
|
+
' }',
|
|
334
|
+
'',
|
|
335
|
+
' if (lockedSetting !== null) {',
|
|
336
|
+
' item.locked = lockedSetting;',
|
|
337
|
+
' }',
|
|
338
|
+
'',
|
|
339
|
+
' "Page item properties updated successfully";',
|
|
340
|
+
' } catch (error) {',
|
|
341
|
+
' "Error updating page item properties: " + error.message;',
|
|
342
|
+
' }',
|
|
343
|
+
' }',
|
|
344
|
+
' }',
|
|
345
|
+
'}'
|
|
346
|
+
].join('\n');
|
|
347
|
+
|
|
348
|
+
const result = await ScriptExecutor.executeInDesignScript(script);
|
|
349
|
+
return formatResponse(result, "Set Page Item Properties");
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Duplicate a page item
|
|
354
|
+
*/
|
|
355
|
+
static async duplicatePageItem(args) {
|
|
356
|
+
const { pageIndex, itemIndex, x, y } = args;
|
|
357
|
+
|
|
358
|
+
const script = [
|
|
359
|
+
'if (app.documents.length === 0) {',
|
|
360
|
+
' "No document open";',
|
|
361
|
+
'} else {',
|
|
362
|
+
' var doc = app.activeDocument;',
|
|
363
|
+
` if (${pageIndex} >= doc.pages.length) {`,
|
|
364
|
+
' "Page index out of range";',
|
|
365
|
+
' } else {',
|
|
366
|
+
` var page = doc.pages[${pageIndex}];`,
|
|
367
|
+
` if (${itemIndex} >= page.allPageItems.length) {`,
|
|
368
|
+
' "Page item index out of range";',
|
|
369
|
+
' } else {',
|
|
370
|
+
` var item = page.allPageItems[${itemIndex}];`,
|
|
371
|
+
` var newItem = item.duplicate();`,
|
|
372
|
+
` newItem.move([${x}, ${y}]);`,
|
|
373
|
+
' "Page item duplicated successfully";',
|
|
374
|
+
' }',
|
|
375
|
+
' }',
|
|
376
|
+
'}'
|
|
377
|
+
].join('\n');
|
|
378
|
+
|
|
379
|
+
const result = await ScriptExecutor.executeInDesignScript(script);
|
|
380
|
+
return formatResponse(result, "Duplicate Page Item");
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Delete a page item
|
|
385
|
+
*/
|
|
386
|
+
static async deletePageItem(args) {
|
|
387
|
+
const { pageIndex, itemIndex } = args;
|
|
388
|
+
|
|
389
|
+
const script = [
|
|
390
|
+
'if (app.documents.length === 0) {',
|
|
391
|
+
' "No document open";',
|
|
392
|
+
'} else {',
|
|
393
|
+
' var doc = app.activeDocument;',
|
|
394
|
+
` if (${pageIndex} >= doc.pages.length) {`,
|
|
395
|
+
' "Page index out of range";',
|
|
396
|
+
' } else {',
|
|
397
|
+
` var page = doc.pages[${pageIndex}];`,
|
|
398
|
+
` if (${itemIndex} >= page.allPageItems.length) {`,
|
|
399
|
+
' "Page item index out of range";',
|
|
400
|
+
' } else {',
|
|
401
|
+
` var item = page.allPageItems[${itemIndex}];`,
|
|
402
|
+
' item.remove();',
|
|
403
|
+
' "Page item deleted successfully";',
|
|
404
|
+
' }',
|
|
405
|
+
' }',
|
|
406
|
+
'}'
|
|
407
|
+
].join('\n');
|
|
408
|
+
|
|
409
|
+
const result = await ScriptExecutor.executeInDesignScript(script);
|
|
410
|
+
return formatResponse(result, "Delete Page Item");
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Read script labels from page items using different targeting strategies.
|
|
415
|
+
*/
|
|
416
|
+
static async getPageItemScriptLabels(args) {
|
|
417
|
+
const {
|
|
418
|
+
mode = 'CURRENT_SELECTION',
|
|
419
|
+
pageIndex,
|
|
420
|
+
itemIndex,
|
|
421
|
+
pageNumber,
|
|
422
|
+
objectId
|
|
423
|
+
} = args;
|
|
424
|
+
|
|
425
|
+
const normalizedMode = String(mode || 'CURRENT_SELECTION').toUpperCase();
|
|
426
|
+
const safeMode = escapeJsxString(normalizedMode);
|
|
427
|
+
const hasPageIndex = Number.isInteger(pageIndex);
|
|
428
|
+
const hasItemIndex = Number.isInteger(itemIndex);
|
|
429
|
+
const hasPageNumber = Number.isInteger(pageNumber);
|
|
430
|
+
const hasObjectId = Number.isInteger(objectId);
|
|
431
|
+
|
|
432
|
+
const script = [
|
|
433
|
+
JSON_SERIALIZER_SNIPPET,
|
|
434
|
+
PAGE_ITEM_LABEL_HELPERS_SNIPPET,
|
|
435
|
+
'function __mcpCollectLabelEntry(item, store) {',
|
|
436
|
+
' if (!item || !item.isValid) return;',
|
|
437
|
+
' var labelValue = "";',
|
|
438
|
+
' try { labelValue = item.label; } catch (_labelErr) { labelValue = ""; }',
|
|
439
|
+
' if (!labelValue) return;',
|
|
440
|
+
' var page = null;',
|
|
441
|
+
' try { page = item.parentPage; } catch (_pageErr) { page = null; }',
|
|
442
|
+
' var pageIndexValue = null;',
|
|
443
|
+
' var pageNumberValue = null;',
|
|
444
|
+
' var pageNameValue = "";',
|
|
445
|
+
' if (page && page.isValid) {',
|
|
446
|
+
' try { pageIndexValue = page.documentOffset; pageNumberValue = pageIndexValue + 1; } catch (_offsetErr) {}',
|
|
447
|
+
' try { pageNameValue = page.name || ""; } catch (_nameErr) {}',
|
|
448
|
+
' }',
|
|
449
|
+
' var layerNameValue = "";',
|
|
450
|
+
' try { layerNameValue = (item.itemLayer && item.itemLayer.isValid) ? item.itemLayer.name : ""; } catch (_layerErr) {}',
|
|
451
|
+
' var itemTypeValue = "";',
|
|
452
|
+
' try { itemTypeValue = item.constructor ? item.constructor.name : ""; } catch (_typeErr) {}',
|
|
453
|
+
' var indexOnPage = -1;',
|
|
454
|
+
' if (page && page.isValid) {',
|
|
455
|
+
' indexOnPage = __mcpFindItemIndexOnPage(page, item.id);',
|
|
456
|
+
' }',
|
|
457
|
+
' store.push({',
|
|
458
|
+
' pageIndex: pageIndexValue,',
|
|
459
|
+
' pageNumber: pageNumberValue,',
|
|
460
|
+
' pageName: pageNameValue,',
|
|
461
|
+
' itemIndex: indexOnPage,',
|
|
462
|
+
' objectId: item.id,',
|
|
463
|
+
' itemType: itemTypeValue,',
|
|
464
|
+
' layerName: layerNameValue,',
|
|
465
|
+
' label: labelValue',
|
|
466
|
+
' });',
|
|
467
|
+
'}',
|
|
468
|
+
`var __mode = "${safeMode}";`,
|
|
469
|
+
`var __hasPageIndex = ${hasPageIndex ? 'true' : 'false'};`,
|
|
470
|
+
`var __pageIndex = ${hasPageIndex ? pageIndex : '-1'};`,
|
|
471
|
+
`var __hasItemIndex = ${hasItemIndex ? 'true' : 'false'};`,
|
|
472
|
+
`var __itemIndex = ${hasItemIndex ? itemIndex : '-1'};`,
|
|
473
|
+
`var __hasPageNumber = ${hasPageNumber ? 'true' : 'false'};`,
|
|
474
|
+
`var __pageNumber = ${hasPageNumber ? pageNumber : '-1'};`,
|
|
475
|
+
`var __hasObjectId = ${hasObjectId ? 'true' : 'false'};`,
|
|
476
|
+
`var __objectId = ${hasObjectId ? objectId : '-1'};`,
|
|
477
|
+
'var __response;',
|
|
478
|
+
'if (app.documents.length === 0) {',
|
|
479
|
+
' __response = __mcpSerializeResponse(false, null, "No document open");',
|
|
480
|
+
'} else {',
|
|
481
|
+
' try {',
|
|
482
|
+
' var doc = app.activeDocument;',
|
|
483
|
+
' var result = [];',
|
|
484
|
+
' if (__mode === "CURRENT_SELECTION") {',
|
|
485
|
+
' var seen = {};',
|
|
486
|
+
' var selection = app.selection;',
|
|
487
|
+
' if (selection && selection.length) {',
|
|
488
|
+
' for (var i = 0; i < selection.length; i++) {',
|
|
489
|
+
' var candidate = selection[i];',
|
|
490
|
+
' try { if (!candidate || !candidate.isValid) continue; } catch (_selErr) { continue; }',
|
|
491
|
+
' var key = "selection-" + i;',
|
|
492
|
+
' try { key = "id-" + candidate.id; } catch (_idErr) {}',
|
|
493
|
+
' if (seen[key]) continue;',
|
|
494
|
+
' seen[key] = true;',
|
|
495
|
+
' __mcpCollectLabelEntry(candidate, result);',
|
|
496
|
+
' }',
|
|
497
|
+
' }',
|
|
498
|
+
' } else if (__mode === "PAGE_ITEM") {',
|
|
499
|
+
' if (!__hasPageIndex || !__hasItemIndex) {',
|
|
500
|
+
' throw new Error("pageIndex and itemIndex are required for PAGE_ITEM mode");',
|
|
501
|
+
' }',
|
|
502
|
+
' if (__pageIndex < 0 || __pageIndex >= doc.pages.length) {',
|
|
503
|
+
' throw new Error("Page index out of range");',
|
|
504
|
+
' }',
|
|
505
|
+
' var page = doc.pages[__pageIndex];',
|
|
506
|
+
' var items = page.allPageItems;',
|
|
507
|
+
' if (__itemIndex < 0 || __itemIndex >= items.length) {',
|
|
508
|
+
' throw new Error("Page item index out of range");',
|
|
509
|
+
' }',
|
|
510
|
+
' __mcpCollectLabelEntry(items[__itemIndex], result);',
|
|
511
|
+
' } else if (__mode === "PAGE_NUMBER_AND_OBJECT_ID") {',
|
|
512
|
+
' if (!__hasPageNumber || !__hasObjectId) {',
|
|
513
|
+
' throw new Error("pageNumber and objectId are required for PAGE_NUMBER_AND_OBJECT_ID mode");',
|
|
514
|
+
' }',
|
|
515
|
+
' var pageByNumber = __mcpFindPageByNumber(doc, __pageNumber);',
|
|
516
|
+
' if (!pageByNumber) {',
|
|
517
|
+
' throw new Error("Page number out of range");',
|
|
518
|
+
' }',
|
|
519
|
+
' var itemById = __mcpFindItemById(pageByNumber, __objectId);',
|
|
520
|
+
' if (!itemById) {',
|
|
521
|
+
' throw new Error("No page item with objectId " + __objectId + " on page " + __pageNumber);',
|
|
522
|
+
' }',
|
|
523
|
+
' __mcpCollectLabelEntry(itemById, result);',
|
|
524
|
+
' } else if (__mode === "ALL_WITH_LABELS") {',
|
|
525
|
+
' for (var p = 0; p < doc.pages.length; p++) {',
|
|
526
|
+
' var eachPage = doc.pages[p];',
|
|
527
|
+
' var pageItems = eachPage.allPageItems;',
|
|
528
|
+
' for (var j = 0; j < pageItems.length; j++) {',
|
|
529
|
+
' __mcpCollectLabelEntry(pageItems[j], result);',
|
|
530
|
+
' }',
|
|
531
|
+
' }',
|
|
532
|
+
' } else {',
|
|
533
|
+
' throw new Error("Unsupported mode: " + __mode);',
|
|
534
|
+
' }',
|
|
535
|
+
' __response = __mcpSerializeResponse(true, result);',
|
|
536
|
+
' } catch (__err) {',
|
|
537
|
+
' __response = __mcpSerializeResponse(false, null, __err.message || String(__err));',
|
|
538
|
+
' }',
|
|
539
|
+
'}',
|
|
540
|
+
'__response;'
|
|
541
|
+
].join('\n');
|
|
542
|
+
|
|
543
|
+
try {
|
|
544
|
+
const raw = await ScriptExecutor.executeInDesignScript(script);
|
|
545
|
+
const parsed = parseJsonResult(raw, 'Get Page Item Script Labels');
|
|
546
|
+
if (!parsed.success) {
|
|
547
|
+
return formatErrorResponse(parsed.error, 'Get Page Item Script Labels');
|
|
548
|
+
}
|
|
549
|
+
return formatResponse(parsed.data, 'Get Page Item Script Labels');
|
|
550
|
+
} catch (error) {
|
|
551
|
+
return formatErrorResponse(error.message, 'Get Page Item Script Labels');
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Overwrite script labels for targeted page items.
|
|
557
|
+
*/
|
|
558
|
+
static async setPageItemScriptLabel(args) {
|
|
559
|
+
const {
|
|
560
|
+
mode = 'CURRENT_SELECTION',
|
|
561
|
+
pageIndex,
|
|
562
|
+
itemIndex,
|
|
563
|
+
pageNumber,
|
|
564
|
+
objectId,
|
|
565
|
+
label = ''
|
|
566
|
+
} = args;
|
|
567
|
+
|
|
568
|
+
const normalizedMode = String(mode || 'CURRENT_SELECTION').toUpperCase();
|
|
569
|
+
const safeMode = escapeJsxString(normalizedMode);
|
|
570
|
+
const labelValue = escapeJsxString(String(label ?? ''));
|
|
571
|
+
const hasPageIndex = Number.isInteger(pageIndex);
|
|
572
|
+
const hasItemIndex = Number.isInteger(itemIndex);
|
|
573
|
+
const hasPageNumber = Number.isInteger(pageNumber);
|
|
574
|
+
const hasObjectId = Number.isInteger(objectId);
|
|
575
|
+
|
|
576
|
+
const script = [
|
|
577
|
+
JSON_SERIALIZER_SNIPPET,
|
|
578
|
+
PAGE_ITEM_LABEL_HELPERS_SNIPPET,
|
|
579
|
+
'function __mcpApplyLabel(item, newLabel, tracker) {',
|
|
580
|
+
' if (!item || !item.isValid) return;',
|
|
581
|
+
' try { item.label = ""; } catch (_clearErr) {}',
|
|
582
|
+
' try { item.label = newLabel; } catch (_assignErr) { throw _assignErr; }',
|
|
583
|
+
' tracker.updatedCount += 1;',
|
|
584
|
+
' try { tracker.objectIds.push(item.id); } catch (_idErr) {}',
|
|
585
|
+
'}',
|
|
586
|
+
`var __mode = "${safeMode}";`,
|
|
587
|
+
`var __labelValue = "${labelValue}";`,
|
|
588
|
+
`var __hasPageIndex = ${hasPageIndex ? 'true' : 'false'};`,
|
|
589
|
+
`var __pageIndex = ${hasPageIndex ? pageIndex : '-1'};`,
|
|
590
|
+
`var __hasItemIndex = ${hasItemIndex ? 'true' : 'false'};`,
|
|
591
|
+
`var __itemIndex = ${hasItemIndex ? itemIndex : '-1'};`,
|
|
592
|
+
`var __hasPageNumber = ${hasPageNumber ? 'true' : 'false'};`,
|
|
593
|
+
`var __pageNumber = ${hasPageNumber ? pageNumber : '-1'};`,
|
|
594
|
+
`var __hasObjectId = ${hasObjectId ? 'true' : 'false'};`,
|
|
595
|
+
`var __objectId = ${hasObjectId ? objectId : '-1'};`,
|
|
596
|
+
'var __response;',
|
|
597
|
+
'if (app.documents.length === 0) {',
|
|
598
|
+
' __response = __mcpSerializeResponse(false, null, "No document open");',
|
|
599
|
+
'} else {',
|
|
600
|
+
' try {',
|
|
601
|
+
' var doc = app.activeDocument;',
|
|
602
|
+
' var tracker = { updatedCount: 0, objectIds: [], appliedLabel: __labelValue };',
|
|
603
|
+
' if (__mode === "CURRENT_SELECTION") {',
|
|
604
|
+
' var seen = {};',
|
|
605
|
+
' var selection = app.selection;',
|
|
606
|
+
' if (selection && selection.length) {',
|
|
607
|
+
' for (var i = 0; i < selection.length; i++) {',
|
|
608
|
+
' var candidate = selection[i];',
|
|
609
|
+
' try { if (!candidate || !candidate.isValid) continue; } catch (_selErr) { continue; }',
|
|
610
|
+
' var key = "selection-" + i;',
|
|
611
|
+
' try { key = "id-" + candidate.id; } catch (_idErr) {}',
|
|
612
|
+
' if (seen[key]) continue;',
|
|
613
|
+
' seen[key] = true;',
|
|
614
|
+
' __mcpApplyLabel(candidate, __labelValue, tracker);',
|
|
615
|
+
' }',
|
|
616
|
+
' }',
|
|
617
|
+
' } else if (__mode === "PAGE_ITEM") {',
|
|
618
|
+
' if (!__hasPageIndex || !__hasItemIndex) {',
|
|
619
|
+
' throw new Error("pageIndex and itemIndex are required for PAGE_ITEM mode");',
|
|
620
|
+
' }',
|
|
621
|
+
' if (__pageIndex < 0 || __pageIndex >= doc.pages.length) {',
|
|
622
|
+
' throw new Error("Page index out of range");',
|
|
623
|
+
' }',
|
|
624
|
+
' var page = doc.pages[__pageIndex];',
|
|
625
|
+
' var items = page.allPageItems;',
|
|
626
|
+
' if (__itemIndex < 0 || __itemIndex >= items.length) {',
|
|
627
|
+
' throw new Error("Page item index out of range");',
|
|
628
|
+
' }',
|
|
629
|
+
' __mcpApplyLabel(items[__itemIndex], __labelValue, tracker);',
|
|
630
|
+
' } else if (__mode === "PAGE_NUMBER_AND_OBJECT_ID") {',
|
|
631
|
+
' if (!__hasPageNumber || !__hasObjectId) {',
|
|
632
|
+
' throw new Error("pageNumber and objectId are required for PAGE_NUMBER_AND_OBJECT_ID mode");',
|
|
633
|
+
' }',
|
|
634
|
+
' var pageByNumber = __mcpFindPageByNumber(doc, __pageNumber);',
|
|
635
|
+
' if (!pageByNumber) {',
|
|
636
|
+
' throw new Error("Page number out of range");',
|
|
637
|
+
' }',
|
|
638
|
+
' var itemById = __mcpFindItemById(pageByNumber, __objectId);',
|
|
639
|
+
' if (!itemById) {',
|
|
640
|
+
' throw new Error("No page item with objectId " + __objectId + " on page " + __pageNumber);',
|
|
641
|
+
' }',
|
|
642
|
+
' __mcpApplyLabel(itemById, __labelValue, tracker);',
|
|
643
|
+
' } else {',
|
|
644
|
+
' throw new Error("Unsupported mode: " + __mode);',
|
|
645
|
+
' }',
|
|
646
|
+
' __response = __mcpSerializeResponse(true, tracker);',
|
|
647
|
+
' } catch (__err) {',
|
|
648
|
+
' __response = __mcpSerializeResponse(false, null, __err.message || String(__err));',
|
|
649
|
+
' }',
|
|
650
|
+
'}',
|
|
651
|
+
'__response;'
|
|
652
|
+
].join('\n');
|
|
653
|
+
|
|
654
|
+
try {
|
|
655
|
+
const raw = await ScriptExecutor.executeInDesignScript(script);
|
|
656
|
+
const parsed = parseJsonResult(raw, 'Set Page Item Script Label');
|
|
657
|
+
if (!parsed.success) {
|
|
658
|
+
return formatErrorResponse(parsed.error, 'Set Page Item Script Label');
|
|
659
|
+
}
|
|
660
|
+
return formatResponse(parsed.data, 'Set Page Item Script Label');
|
|
661
|
+
} catch (error) {
|
|
662
|
+
return formatErrorResponse(error.message, 'Set Page Item Script Label');
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
/**
|
|
667
|
+
* List all page items on a page
|
|
668
|
+
*/
|
|
669
|
+
static async listPageItems(args) {
|
|
670
|
+
const { pageIndex } = args;
|
|
671
|
+
|
|
672
|
+
const script = [
|
|
673
|
+
'if (app.documents.length === 0) {',
|
|
674
|
+
' "No document open";',
|
|
675
|
+
'} else {',
|
|
676
|
+
' var doc = app.activeDocument;',
|
|
677
|
+
` if (${pageIndex} >= doc.pages.length) {`,
|
|
678
|
+
' "Page index out of range";',
|
|
679
|
+
' } else {',
|
|
680
|
+
` var page = doc.pages[${pageIndex}];`,
|
|
681
|
+
' var items = page.allPageItems;',
|
|
682
|
+
' var result = "=== PAGE ITEMS ===\\n";',
|
|
683
|
+
'',
|
|
684
|
+
' for (var i = 0; i < items.length; i++) {',
|
|
685
|
+
' var item = items[i];',
|
|
686
|
+
' result += "Index: " + i + "\\n";',
|
|
687
|
+
' result += "Type: " + item.constructor.name + "\\n";',
|
|
688
|
+
' result += "Name: " + (item.name || "Unnamed") + "\\n";',
|
|
689
|
+
' result += "ID: " + item.id + "\\n";',
|
|
690
|
+
' result += "Visible: " + item.visible + "\\n";',
|
|
691
|
+
' result += "Locked: " + item.locked + "\\n";',
|
|
692
|
+
' result += "Bounds: " + item.geometricBounds.join(", ") + "\\n";',
|
|
693
|
+
' result += "---\\n";',
|
|
694
|
+
' }',
|
|
695
|
+
'',
|
|
696
|
+
' result;',
|
|
697
|
+
' }',
|
|
698
|
+
'}'
|
|
699
|
+
].join('\n');
|
|
700
|
+
|
|
701
|
+
const result = await ScriptExecutor.executeInDesignScript(script);
|
|
702
|
+
return formatResponse(result, "List Page Items");
|
|
703
|
+
}
|
|
704
|
+
}
|