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.
Files changed (72) hide show
  1. cli_anything/indesign/README.md +32 -0
  2. cli_anything/indesign/__init__.py +1 -0
  3. cli_anything/indesign/__main__.py +5 -0
  4. cli_anything/indesign/core/artifacts.py +57 -0
  5. cli_anything/indesign/core/catalog.py +405 -0
  6. cli_anything/indesign/core/domains.py +178 -0
  7. cli_anything/indesign/core/envelope.py +65 -0
  8. cli_anything/indesign/core/errors.py +30 -0
  9. cli_anything/indesign/core/health.py +46 -0
  10. cli_anything/indesign/core/hidden_backend.py +116 -0
  11. cli_anything/indesign/core/hidden_handler_schemas.py +223 -0
  12. cli_anything/indesign/core/mcp_backend.py +152 -0
  13. cli_anything/indesign/core/node_setup.py +35 -0
  14. cli_anything/indesign/core/paths.py +41 -0
  15. cli_anything/indesign/core/plugins/__init__.py +2 -0
  16. cli_anything/indesign/core/plugins/backend.py +90 -0
  17. cli_anything/indesign/core/plugins/discovery.py +69 -0
  18. cli_anything/indesign/core/plugins/host_actions.py +76 -0
  19. cli_anything/indesign/core/plugins/install.py +38 -0
  20. cli_anything/indesign/core/plugins/manifest.py +279 -0
  21. cli_anything/indesign/core/plugins/validate.py +181 -0
  22. cli_anything/indesign/core/router.py +217 -0
  23. cli_anything/indesign/core/runtime.py +59 -0
  24. cli_anything/indesign/core/scripts.py +44 -0
  25. cli_anything/indesign/core/session.py +68 -0
  26. cli_anything/indesign/indesign_cli.py +320 -0
  27. cli_anything/indesign/node/hidden_handler_bridge.mjs +111 -0
  28. cli_anything/indesign/server/package-lock.json +168 -0
  29. cli_anything/indesign/server/package.json +45 -0
  30. cli_anything/indesign/server/src/advanced/index.js +76 -0
  31. cli_anything/indesign/server/src/core/InDesignMCPServer.js +273 -0
  32. cli_anything/indesign/server/src/core/scriptExecutor.js +271 -0
  33. cli_anything/indesign/server/src/core/sessionManager.js +545 -0
  34. cli_anything/indesign/server/src/handlers/advancedTemplateHandlers.js +1072 -0
  35. cli_anything/indesign/server/src/handlers/bookHandlers.js +490 -0
  36. cli_anything/indesign/server/src/handlers/documentHandlers.js +1472 -0
  37. cli_anything/indesign/server/src/handlers/exportHandlers.js +208 -0
  38. cli_anything/indesign/server/src/handlers/graphicsHandlers.js +605 -0
  39. cli_anything/indesign/server/src/handlers/groupHandlers.js +358 -0
  40. cli_anything/indesign/server/src/handlers/helpHandlers.js +347 -0
  41. cli_anything/indesign/server/src/handlers/index.js +77 -0
  42. cli_anything/indesign/server/src/handlers/layerHandlers.js +75 -0
  43. cli_anything/indesign/server/src/handlers/masterSpreadHandlers.js +451 -0
  44. cli_anything/indesign/server/src/handlers/pageHandlers.js +698 -0
  45. cli_anything/indesign/server/src/handlers/pageItemHandlers.js +704 -0
  46. cli_anything/indesign/server/src/handlers/presentationHandlers.js +220 -0
  47. cli_anything/indesign/server/src/handlers/spreadHandlers.js +348 -0
  48. cli_anything/indesign/server/src/handlers/styleHandlers.js +458 -0
  49. cli_anything/indesign/server/src/handlers/textHandlers.js +431 -0
  50. cli_anything/indesign/server/src/handlers/utilityHandlers.js +83 -0
  51. cli_anything/indesign/server/src/index.js +17 -0
  52. cli_anything/indesign/server/src/types/index.js +106 -0
  53. cli_anything/indesign/server/src/types/toolDefinitionsAdvancedTemplates.js +144 -0
  54. cli_anything/indesign/server/src/types/toolDefinitionsBook.js +224 -0
  55. cli_anything/indesign/server/src/types/toolDefinitionsContent.js +353 -0
  56. cli_anything/indesign/server/src/types/toolDefinitionsDocument.js +409 -0
  57. cli_anything/indesign/server/src/types/toolDefinitionsExport.js +65 -0
  58. cli_anything/indesign/server/src/types/toolDefinitionsLayer.js +40 -0
  59. cli_anything/indesign/server/src/types/toolDefinitionsMasterSpread.js +160 -0
  60. cli_anything/indesign/server/src/types/toolDefinitionsPage.js +271 -0
  61. cli_anything/indesign/server/src/types/toolDefinitionsPageItemGroup.js +437 -0
  62. cli_anything/indesign/server/src/types/toolDefinitionsPresentation.js +83 -0
  63. cli_anything/indesign/server/src/types/toolDefinitionsSpread.js +158 -0
  64. cli_anything/indesign/server/src/types/toolDefinitionsUtility.js +40 -0
  65. cli_anything/indesign/server/src/utils/stringUtils.js +107 -0
  66. cli_anything/indesign/skills/SKILL.md +198 -0
  67. indesign_cli-0.2.0.dist-info/METADATA +267 -0
  68. indesign_cli-0.2.0.dist-info/RECORD +72 -0
  69. indesign_cli-0.2.0.dist-info/WHEEL +5 -0
  70. indesign_cli-0.2.0.dist-info/entry_points.txt +3 -0
  71. indesign_cli-0.2.0.dist-info/licenses/LICENSE +21 -0
  72. indesign_cli-0.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,347 @@
1
+ import { formatResponse, formatErrorResponse } from '../utils/stringUtils.js';
2
+
3
+ /**
4
+ * Help Handlers
5
+ * Provides comprehensive help information for the InDesign MCP Server
6
+ */
7
+ export class HelpHandlers {
8
+
9
+ // Tool categories and their descriptions
10
+ static toolCategories = {
11
+ document: {
12
+ name: 'Document Management',
13
+ description: 'Create, open, save, and manage InDesign documents',
14
+ tools: ['create_document', 'open_document', 'save_document', 'close_document', 'get_document_info']
15
+ },
16
+ page: {
17
+ name: 'Page Operations',
18
+ description: 'Add, delete, navigate, and manage pages',
19
+ tools: ['add_page', 'delete_page', 'navigate_to_page', 'get_page_info', 'set_page_background']
20
+ },
21
+ text: {
22
+ name: 'Text & Typography',
23
+ description: 'Create and edit text frames, apply styles',
24
+ tools: ['create_text_frame', 'edit_text_frame', 'get_text_info', 'apply_paragraph_style', 'apply_character_style']
25
+ },
26
+ graphics: {
27
+ name: 'Graphics & Images',
28
+ description: 'Create shapes and place images with scaling',
29
+ tools: ['create_rectangle', 'create_ellipse', 'create_polygon', 'place_image', 'get_image_info']
30
+ },
31
+ styles: {
32
+ name: 'Styles & Colors',
33
+ description: 'Create and manage colors, paragraph, character, and object styles',
34
+ tools: ['create_color_swatch', 'list_color_swatches', 'create_paragraph_style', 'create_character_style', 'create_object_style', 'list_styles']
35
+ },
36
+ layout: {
37
+ name: 'Layout & Positioning',
38
+ description: 'Group objects, create master spreads, manage positioning',
39
+ tools: ['create_group', 'ungroup', 'create_master_spread', 'apply_master_spread']
40
+ },
41
+ export: {
42
+ name: 'Export & Utilities',
43
+ description: 'Export documents and run custom code',
44
+ tools: ['export_pdf', 'export_images', 'execute_indesign_code']
45
+ }
46
+ };
47
+
48
+ // Tool definitions with detailed information
49
+ static toolDefinitions = {
50
+ create_document: {
51
+ name: 'create_document',
52
+ description: 'Create a new InDesign document',
53
+ parameters: {
54
+ name: 'Document name',
55
+ width: 'Page width in mm (default: 210)',
56
+ height: 'Page height in mm (default: 297)',
57
+ facingPages: 'Enable facing pages (default: false)',
58
+ pageOrientation: 'PORTRAIT or LANDSCAPE (default: PORTRAIT)',
59
+ marginTop: 'Top margin in mm (default: 25)',
60
+ marginBottom: 'Bottom margin in mm (default: 25)',
61
+ marginLeft: 'Left margin in mm (default: 25)',
62
+ marginRight: 'Right margin in mm (default: 25)'
63
+ },
64
+ example: {
65
+ name: 'My Document',
66
+ width: 210,
67
+ height: 297,
68
+ facingPages: false,
69
+ pageOrientation: 'PORTRAIT'
70
+ }
71
+ },
72
+ create_text_frame: {
73
+ name: 'create_text_frame',
74
+ description: 'Create a text frame with content',
75
+ parameters: {
76
+ content: 'Text content to display',
77
+ x: 'X position in mm (default: 10)',
78
+ y: 'Y position in mm (default: 10)',
79
+ width: 'Frame width in mm',
80
+ height: 'Frame height in mm',
81
+ fontSize: 'Font size in points (default: 12)',
82
+ fontName: 'Font name in format "FontName\\tStyle" (default: "Arial\\tRegular")',
83
+ textColor: 'Text color name (default: "Black")',
84
+ alignment: 'Text alignment: LEFT, CENTER, RIGHT, JUSTIFY (default: LEFT)',
85
+ paragraphStyle: 'Paragraph style name to apply (optional)',
86
+ characterStyle: 'Character style name to apply (optional)'
87
+ },
88
+ example: {
89
+ content: 'Hello World',
90
+ x: 25,
91
+ y: 25,
92
+ width: 160,
93
+ height: 50,
94
+ fontSize: 24,
95
+ fontName: 'Arial\\tBold',
96
+ alignment: 'CENTER'
97
+ }
98
+ },
99
+ place_image: {
100
+ name: 'place_image',
101
+ description: 'Place an image on the active page with scaling options',
102
+ parameters: {
103
+ filePath: 'Absolute path to the image file (required)',
104
+ x: 'X position in mm (default: 10)',
105
+ y: 'Y position in mm (default: 10)',
106
+ width: 'Frame width in mm',
107
+ height: 'Frame height in mm',
108
+ scale: 'Scale percentage 1-1000 (default: 100)',
109
+ fitMode: 'Fitting mode: PROPORTIONALLY, FILL_FRAME, FIT_CONTENT, FIT_FRAME (default: PROPORTIONALLY)',
110
+ linkImage: 'Link the image (default: true)'
111
+ },
112
+ example: {
113
+ filePath: '/path/to/image.jpg',
114
+ x: 25,
115
+ y: 25,
116
+ width: 100,
117
+ height: 75,
118
+ scale: 150,
119
+ fitMode: 'PROPORTIONALLY'
120
+ }
121
+ },
122
+ create_color_swatch: {
123
+ name: 'create_color_swatch',
124
+ description: 'Create a custom color swatch',
125
+ parameters: {
126
+ name: 'Color name (required)',
127
+ colorType: 'Color type: PROCESS or SPOT (default: PROCESS)',
128
+ red: 'Red value 0-255 (required)',
129
+ green: 'Green value 0-255 (required)',
130
+ blue: 'Blue value 0-255 (required)'
131
+ },
132
+ example: {
133
+ name: 'Brand Blue',
134
+ colorType: 'PROCESS',
135
+ red: 0,
136
+ green: 114,
137
+ blue: 198
138
+ }
139
+ },
140
+ create_paragraph_style: {
141
+ name: 'create_paragraph_style',
142
+ description: 'Create a paragraph style for consistent typography',
143
+ parameters: {
144
+ name: 'Style name (required)',
145
+ fontName: 'Font name in format "FontName\\tStyle" (default: "Arial\\tRegular")',
146
+ fontSize: 'Font size in points (default: 12)',
147
+ fillColor: 'Text color name (default: "Black")',
148
+ alignment: 'Text alignment: LEFT, CENTER, RIGHT, JUSTIFY (default: LEFT)',
149
+ leading: 'Line spacing in points (optional)',
150
+ spaceBefore: 'Space before paragraph in points (optional)',
151
+ spaceAfter: 'Space after paragraph in points (optional)'
152
+ },
153
+ example: {
154
+ name: 'Heading 1',
155
+ fontName: 'Arial\\tBold',
156
+ fontSize: 32,
157
+ fillColor: 'Brand Blue',
158
+ alignment: 'CENTER'
159
+ }
160
+ },
161
+ set_page_background: {
162
+ name: 'set_page_background',
163
+ description: 'Set the background color of a page',
164
+ parameters: {
165
+ pageIndex: 'Page index (0-based) (required)',
166
+ backgroundColor: 'Color swatch name (default: "White")',
167
+ opacity: 'Opacity percentage 0-100 (default: 100)'
168
+ },
169
+ example: {
170
+ pageIndex: 0,
171
+ backgroundColor: 'Brand Blue',
172
+ opacity: 50
173
+ }
174
+ }
175
+ };
176
+
177
+ /**
178
+ * Get help information
179
+ */
180
+ static async getHelp(args) {
181
+ const { tool, category, format } = args;
182
+
183
+ try {
184
+ // If specific tool requested
185
+ if (tool) {
186
+ return this.getToolHelp(tool, format);
187
+ }
188
+
189
+ // If category requested
190
+ if (category && category !== 'all') {
191
+ return this.getCategoryHelp(category, format);
192
+ }
193
+
194
+ // Default: show all tools summary
195
+ return this.getAllToolsHelp(format);
196
+
197
+ } catch (error) {
198
+ return formatErrorResponse(`Error getting help: ${error.message}`, 'Get Help');
199
+ }
200
+ }
201
+
202
+ /**
203
+ * Get help for a specific tool
204
+ */
205
+ static getToolHelp(toolName, format = 'summary') {
206
+ const toolDef = this.toolDefinitions[toolName];
207
+
208
+ if (!toolDef) {
209
+ return formatErrorResponse(`Tool '${toolName}' not found. Use 'help' without parameters to see all available tools.`, 'Get Help');
210
+ }
211
+
212
+ let helpText = `# ${toolDef.name}\n\n`;
213
+ helpText += `**Description:** ${toolDef.description}\n\n`;
214
+
215
+ if (format === 'detailed' || format === 'examples') {
216
+ helpText += `## Parameters\n\n`;
217
+ for (const [param, desc] of Object.entries(toolDef.parameters)) {
218
+ helpText += `- **${param}**: ${desc}\n`;
219
+ }
220
+ helpText += '\n';
221
+ }
222
+
223
+ if (format === 'examples') {
224
+ helpText += `## Example\n\n`;
225
+ helpText += '```javascript\n';
226
+ helpText += `await tools.call("${toolName}", ${JSON.stringify(toolDef.example, null, 2)});\n`;
227
+ helpText += '```\n\n';
228
+ }
229
+
230
+ return formatResponse(helpText, 'Get Help');
231
+ }
232
+
233
+ /**
234
+ * Get help for a specific category
235
+ */
236
+ static getCategoryHelp(category, format = 'summary') {
237
+ const catInfo = this.toolCategories[category];
238
+
239
+ if (!catInfo) {
240
+ return formatErrorResponse(`Category '${category}' not found. Available categories: ${Object.keys(this.toolCategories).join(', ')}`, 'Get Help');
241
+ }
242
+
243
+ let helpText = `# ${catInfo.name}\n\n`;
244
+ helpText += `${catInfo.description}\n\n`;
245
+
246
+ helpText += `## Available Tools\n\n`;
247
+ for (const toolName of catInfo.tools) {
248
+ const toolDef = this.toolDefinitions[toolName];
249
+ if (toolDef) {
250
+ helpText += `- **${toolName}**: ${toolDef.description}\n`;
251
+ } else {
252
+ helpText += `- **${toolName}**: Tool available\n`;
253
+ }
254
+ }
255
+
256
+ if (format === 'detailed') {
257
+ helpText += '\n## Detailed Information\n\n';
258
+ for (const toolName of catInfo.tools) {
259
+ const toolDef = this.toolDefinitions[toolName];
260
+ if (toolDef) {
261
+ helpText += `### ${toolName}\n`;
262
+ helpText += `${toolDef.description}\n\n`;
263
+ helpText += '**Parameters:**\n';
264
+ for (const [param, desc] of Object.entries(toolDef.parameters)) {
265
+ helpText += `- ${param}: ${desc}\n`;
266
+ }
267
+ helpText += '\n';
268
+ }
269
+ }
270
+ }
271
+
272
+ return formatResponse(helpText, 'Get Help');
273
+ }
274
+
275
+ /**
276
+ * Get help for all tools
277
+ */
278
+ static getAllToolsHelp(format = 'summary') {
279
+ let helpText = `# InDesign MCP Server - Available Tools\n\n`;
280
+ helpText += `This server provides programmatic access to Adobe InDesign through Model Context Protocol (MCP).\n\n`;
281
+
282
+ helpText += `## Quick Start\n\n`;
283
+ helpText += `1. **Create a document**: \`create_document\`\n`;
284
+ helpText += `2. **Add text**: \`create_text_frame\`\n`;
285
+ helpText += `3. **Add images**: \`place_image\`\n`;
286
+ helpText += `4. **Create styles**: \`create_paragraph_style\`, \`create_color_swatch\`\n`;
287
+ helpText += `5. **Save**: \`save_document\`\n\n`;
288
+
289
+ helpText += `## Tool Categories\n\n`;
290
+
291
+ for (const [category, info] of Object.entries(this.toolCategories)) {
292
+ helpText += `### ${info.name}\n`;
293
+ helpText += `${info.description}\n\n`;
294
+
295
+ if (format === 'summary') {
296
+ helpText += `**Tools:** ${info.tools.join(', ')}\n\n`;
297
+ } else {
298
+ for (const toolName of info.tools) {
299
+ const toolDef = this.toolDefinitions[toolName];
300
+ if (toolDef) {
301
+ helpText += `- **${toolName}**: ${toolDef.description}\n`;
302
+ } else {
303
+ helpText += `- **${toolName}**: Tool available\n`;
304
+ }
305
+ }
306
+ helpText += '\n';
307
+ }
308
+ }
309
+
310
+ helpText += `## Usage Examples\n\n`;
311
+ helpText += `### Basic Document Creation\n`;
312
+ helpText += '```javascript\n';
313
+ helpText += '// Create document\n';
314
+ helpText += 'await tools.call("create_document", {\n';
315
+ helpText += ' name: "My Document",\n';
316
+ helpText += ' width: 210,\n';
317
+ helpText += ' height: 297\n';
318
+ helpText += '});\n\n';
319
+ helpText += '// Add text\n';
320
+ helpText += 'await tools.call("create_text_frame", {\n';
321
+ helpText += ' content: "Hello World",\n';
322
+ helpText += ' x: 25, y: 25,\n';
323
+ helpText += ' width: 160, height: 50,\n';
324
+ helpText += ' fontSize: 24,\n';
325
+ helpText += ' fontName: "Arial\\\\tBold"\n';
326
+ helpText += '});\n\n';
327
+ helpText += '// Save\n';
328
+ helpText += 'await tools.call("save_document", { filePath: "./output.indd" });\n';
329
+ helpText += '```\n\n';
330
+
331
+ helpText += `## Help Options\n\n`;
332
+ helpText += `- \`help()\` - Show this overview\n`;
333
+ helpText += `- \`help({ tool: "create_document" })\` - Get help for specific tool\n`;
334
+ helpText += `- \`help({ category: "text" })\` - Get help for tool category\n`;
335
+ helpText += `- \`help({ format: "detailed" })\` - Get detailed information\n`;
336
+ helpText += `- \`help({ format: "examples" })\` - Get examples\n\n`;
337
+
338
+ helpText += `## Important Notes\n\n`;
339
+ helpText += `- **Font Names**: Use format "FontName\\\\tStyle" (e.g., "Arial\\\\tBold")\n`;
340
+ helpText += `- **Colors**: RGB values (0-255) for color swatches\n`;
341
+ helpText += `- **Positioning**: x, y coordinates in millimeters\n`;
342
+ helpText += `- **Image Paths**: Use absolute file paths\n`;
343
+ helpText += `- **Scaling**: 1-1000% for images\n`;
344
+
345
+ return formatResponse(helpText, 'Get Help');
346
+ }
347
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Handlers Index - Central export for all InDesign MCP Server handlers
3
+ *
4
+ * This file provides a centralized way to import all handler classes
5
+ * and serves as documentation for available handlers.
6
+ */
7
+
8
+ // Core Document and Page Management
9
+ export { DocumentHandlers } from './documentHandlers.js';
10
+ export { PageHandlers } from './pageHandlers.js';
11
+
12
+ // Content Creation and Management
13
+ export { TextHandlers } from './textHandlers.js';
14
+ export { GraphicsHandlers } from './graphicsHandlers.js';
15
+ export { StyleHandlers } from './styleHandlers.js';
16
+
17
+ // Advanced Layout and Organization
18
+ export { MasterSpreadHandlers } from './masterSpreadHandlers.js';
19
+ export { SpreadHandlers } from './spreadHandlers.js';
20
+ export { LayerHandlers } from './layerHandlers.js';
21
+ export { PageItemHandlers } from './pageItemHandlers.js';
22
+ export { GroupHandlers } from './groupHandlers.js';
23
+
24
+ // Multi-Document and Production
25
+ export { BookHandlers } from './bookHandlers.js';
26
+ export { ExportHandlers } from './exportHandlers.js';
27
+
28
+ // System and Utility
29
+ export { UtilityHandlers } from './utilityHandlers.js';
30
+ export { HelpHandlers } from './helpHandlers.js';
31
+
32
+ // Presentation
33
+ export { PresentationHandlers } from './presentationHandlers.js';
34
+
35
+ /**
36
+ * Handler Categories Overview:
37
+ *
38
+ * 📄 Document & Page Management (2 handlers)
39
+ * - DocumentHandlers: Document lifecycle, preferences, grid settings
40
+ * - PageHandlers: Page operations, layout, content placement
41
+ *
42
+ * ✍️ Content Creation (3 handlers)
43
+ * - TextHandlers: Text frames, tables, find/replace
44
+ * - GraphicsHandlers: Shapes, images, object styles
45
+ * - StyleHandlers: Paragraph/character styles, colors
46
+ *
47
+ * 🎯 Advanced Layout (3 handlers)
48
+ * - MasterSpreadHandlers: Master page templates
49
+ * - PageItemHandlers: Individual page item control
50
+ * - GroupHandlers: Object grouping and organization
51
+ *
52
+ * 📚 Production & Export (2 handlers)
53
+ * - BookHandlers: Multi-document book management
54
+ * - ExportHandlers: PDF, images, packaging
55
+ *
56
+ * 🛠️ System Utilities (1 handler)
57
+ * - UtilityHandlers: Code execution, session management
58
+ *
59
+ * Total: 13 handler classes covering 135+ tools
60
+ */
61
+
62
+ /**
63
+ * Session Management Integration:
64
+ *
65
+ * The following handlers are integrated with session management:
66
+ * - DocumentHandlers: Stores page dimensions and document info
67
+ * - TextHandlers: Uses smart positioning for content placement
68
+ * - GraphicsHandlers: Uses smart positioning for shapes and images
69
+ * - UtilityHandlers: Provides session info and cleanup
70
+ *
71
+ * Session management is transparent and doesn't require separate calls.
72
+ * It automatically:
73
+ * - Tracks page dimensions when documents are created/opened
74
+ * - Provides smart positioning when coordinates aren't specified
75
+ * - Maintains state across operations
76
+ * - Prevents content from being placed off-page
77
+ */
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Layer management handlers
3
+ */
4
+ import { ScriptExecutor } from '../core/scriptExecutor.js';
5
+ import { formatResponse, escapeJsxString } from '../utils/stringUtils.js';
6
+
7
+ export class LayerHandlers {
8
+ static async createLayer(args) {
9
+ const { name, visible = true, locked = false, color = 'BLUE' } = args;
10
+ const escapedName = escapeJsxString(name);
11
+ const normalizedColor = typeof color === 'string' ? color.trim().toUpperCase() : 'BLUE';
12
+ const safeColor = /^[A-Z_]+$/.test(normalizedColor) ? normalizedColor : 'BLUE';
13
+ const escapedColor = escapeJsxString(safeColor);
14
+ const script = [
15
+ 'if (app.documents.length === 0) {',
16
+ ' "No document open";',
17
+ '} else {',
18
+ ' var doc = app.activeDocument;',
19
+ ' try {',
20
+ ` var layer = doc.layers.add({name: "${escapedName}"});`,
21
+ ` layer.visible = ${!!visible};`,
22
+ ` layer.locked = ${!!locked};`,
23
+ ` try { layer.layerColor = UIColors["${escapedColor}"]; } catch(e) {}`,
24
+ ` "Layer created: ${escapedName}";`,
25
+ ' } catch (e) {',
26
+ ' "Error creating layer: " + e.message;',
27
+ ' }',
28
+ '}'
29
+ ].join('\n');
30
+ const result = await ScriptExecutor.executeInDesignScript(script);
31
+ return formatResponse(result, 'Create Layer');
32
+ }
33
+
34
+ static async setActiveLayer(args) {
35
+ const { layerName } = args;
36
+ const escaped = escapeJsxString(layerName);
37
+ const script = [
38
+ 'if (app.documents.length === 0) {',
39
+ ' "No document open";',
40
+ '} else {',
41
+ ' var doc = app.activeDocument;',
42
+ ` var layer = doc.layers.itemByName("${escaped}");`,
43
+ ' if (!layer.isValid) {',
44
+ ` "Layer not found: ${escaped}";`,
45
+ ' } else {',
46
+ ' doc.activeLayer = layer;',
47
+ ` "Active layer set: ${escaped}";`,
48
+ ' }',
49
+ '}'
50
+ ].join('\n');
51
+ const result = await ScriptExecutor.executeInDesignScript(script);
52
+ return formatResponse(result, 'Set Active Layer');
53
+ }
54
+
55
+ static async listLayers() {
56
+ const script = [
57
+ 'if (app.documents.length === 0) {',
58
+ ' "No document open";',
59
+ '} else {',
60
+ ' var doc = app.activeDocument;',
61
+ ' var info = "=== LAYERS ===\\n";',
62
+ ' for (var i=0;i<doc.layers.length;i++){',
63
+ ' var l = doc.layers[i];',
64
+ ' info += "Index: " + i + "\\n";',
65
+ ' info += "Name: " + l.name + "\\n";',
66
+ ' info += "Visible: " + l.visible + "\\n";',
67
+ ' info += "Locked: " + l.locked + "\\n---\\n";',
68
+ ' }',
69
+ ' info;',
70
+ '}'
71
+ ].join('\n');
72
+ const result = await ScriptExecutor.executeInDesignScript(script);
73
+ return formatResponse(result, 'List Layers');
74
+ }
75
+ }