@iborymagic/aseprite-mcp 0.3.6 → 0.4.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/README.md +2 -2
- package/build/index.js +60 -4
- package/build/lua/template.js +48 -0
- package/build/lua/tools.js +376 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ Supports fundamental Aseprite export workflow:
|
|
|
15
15
|
### V2 - Lua Automation
|
|
16
16
|
Adds deeper control using Aseprite Lua scripting, enabling safe AI-driven editing operations such as:
|
|
17
17
|
- `aseprite_list_lua_templates`: Lists available Lua templates
|
|
18
|
-
-
|
|
18
|
+
- Predefined safe Lua automation(templates)
|
|
19
19
|
- `remove_layer_by_name`: Removing specific layers
|
|
20
20
|
- `recolor_palette`: Palette recoloring
|
|
21
21
|
- `normalize_animation_speed`: Normalizing animation speed
|
|
@@ -23,7 +23,7 @@ Adds deeper control using Aseprite Lua scripting, enabling safe AI-driven editin
|
|
|
23
23
|
- `export_layer_only`: Exporting only a specific layer as a flattened PNG image
|
|
24
24
|
- `export_tag_frames`: Exporting all frames within a specific animation tag as individual PNG files
|
|
25
25
|
- `merge_visible_layers`: Merging all currently visible layers into a single layer
|
|
26
|
-
- `
|
|
26
|
+
- `aseprite_run_lua_script`: Executes a raw Lua script (advanced / unsafe)
|
|
27
27
|
|
|
28
28
|
## How to use
|
|
29
29
|
1) Run directly with npx
|
package/build/index.js
CHANGED
|
@@ -36,10 +36,66 @@ server.registerTool("aseprite_export_metadata", {
|
|
|
36
36
|
inputSchema: asepriteToolSchemas.aseprite_export_metadata,
|
|
37
37
|
}, asepriteToolHandlers.aseprite_export_metadata);
|
|
38
38
|
server.registerTool("aseprite_list_lua_templates", { description: "List available Aseprite Lua templates." }, luaToolHandlers.aseprite_list_lua_templates);
|
|
39
|
-
server.registerTool("
|
|
40
|
-
description: "
|
|
41
|
-
inputSchema: luaToolSchemas.
|
|
42
|
-
}, luaToolHandlers.
|
|
39
|
+
server.registerTool("auto_crop_transparent", {
|
|
40
|
+
description: "Automatically crops empty transparent borders of the sprite",
|
|
41
|
+
inputSchema: luaToolSchemas.auto_crop_transparent,
|
|
42
|
+
}, luaToolHandlers.auto_crop_transparent);
|
|
43
|
+
server.registerTool("merge_visible_layers", {
|
|
44
|
+
description: "Merges all currently visible layers into a single layer",
|
|
45
|
+
inputSchema: luaToolSchemas.merge_visible_layers,
|
|
46
|
+
}, luaToolHandlers.merge_visible_layers);
|
|
47
|
+
server.registerTool("normalize_animation_speed", {
|
|
48
|
+
description: "Normalizes all frame durations to a single target duration (in seconds)",
|
|
49
|
+
inputSchema: luaToolSchemas.normalize_animation_speed,
|
|
50
|
+
}, luaToolHandlers.normalize_animation_speed);
|
|
51
|
+
server.registerTool("recolor_palette", {
|
|
52
|
+
description: "Recolors the palette based on a mapping of from->to colors",
|
|
53
|
+
inputSchema: luaToolSchemas.recolor_palette,
|
|
54
|
+
}, luaToolHandlers.recolor_palette);
|
|
55
|
+
server.registerTool("remove_layer_by_name", {
|
|
56
|
+
description: "Removes a layer with a given name and saves to a new file (or overwrites)",
|
|
57
|
+
inputSchema: luaToolSchemas.remove_layer_by_name,
|
|
58
|
+
}, luaToolHandlers.remove_layer_by_name);
|
|
59
|
+
server.registerTool("export_layer_only", {
|
|
60
|
+
description: "Exports only the specified layer to a flattened PNG",
|
|
61
|
+
inputSchema: luaToolSchemas.export_layer_only,
|
|
62
|
+
}, luaToolHandlers.export_layer_only);
|
|
63
|
+
server.registerTool("export_tag_frames", {
|
|
64
|
+
description: "Exports frames inside a specific animation tag to PNG files",
|
|
65
|
+
inputSchema: luaToolSchemas.export_tag_frames,
|
|
66
|
+
}, luaToolHandlers.export_tag_frames);
|
|
67
|
+
server.registerTool("get_is_layer_exists", {
|
|
68
|
+
description: "Checks if a layer exists in the active sprite",
|
|
69
|
+
inputSchema: luaToolSchemas.get_is_layer_exists,
|
|
70
|
+
}, luaToolHandlers.get_is_layer_exists);
|
|
71
|
+
server.registerTool("get_is_tag_exists", {
|
|
72
|
+
description: "Checks if a tag exists in the active sprite",
|
|
73
|
+
inputSchema: luaToolSchemas.get_is_tag_exists,
|
|
74
|
+
}, luaToolHandlers.get_is_tag_exists);
|
|
75
|
+
server.registerTool("get_palette_info", {
|
|
76
|
+
description: "Gets information about the palette of the active sprite",
|
|
77
|
+
inputSchema: luaToolSchemas.get_palette_info,
|
|
78
|
+
}, luaToolHandlers.get_palette_info);
|
|
79
|
+
server.registerTool("get_selection_bounds", {
|
|
80
|
+
description: "Gets the bounds of the selection in the active sprite",
|
|
81
|
+
inputSchema: luaToolSchemas.get_selection_bounds,
|
|
82
|
+
}, luaToolHandlers.get_selection_bounds);
|
|
83
|
+
server.registerTool("get_tag_list", {
|
|
84
|
+
description: "Gets a list of all tags in the active sprite",
|
|
85
|
+
inputSchema: luaToolSchemas.get_tag_list,
|
|
86
|
+
}, luaToolHandlers.get_tag_list);
|
|
87
|
+
server.registerTool("get_layer_list", {
|
|
88
|
+
description: "Gets a list of all layers in the active sprite",
|
|
89
|
+
inputSchema: luaToolSchemas.get_layer_list,
|
|
90
|
+
}, luaToolHandlers.get_layer_list);
|
|
91
|
+
server.registerTool("get_frame_info", {
|
|
92
|
+
description: "Gets information about the current frame",
|
|
93
|
+
inputSchema: luaToolSchemas.get_frame_info,
|
|
94
|
+
}, luaToolHandlers.get_frame_info);
|
|
95
|
+
server.registerTool("get_active_sprite_info", {
|
|
96
|
+
description: "Gets information about the active sprite",
|
|
97
|
+
inputSchema: luaToolSchemas.get_active_sprite_info,
|
|
98
|
+
}, luaToolHandlers.get_active_sprite_info);
|
|
43
99
|
server.registerTool("aseprite_run_lua_script", {
|
|
44
100
|
description: "Run a raw Lua script (advanced / unsafe).",
|
|
45
101
|
inputSchema: luaToolSchemas.aseprite_run_lua_script,
|
package/build/lua/template.js
CHANGED
|
@@ -53,6 +53,54 @@ export const LUA_TEMPLATES = [
|
|
|
53
53
|
params: ["inputFile", "tag", "outputDir"],
|
|
54
54
|
optionalParams: ["filenamePrefix"],
|
|
55
55
|
scriptPath: path.join(__dirname, "templates", "export_tag_frames.lua")
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: "get_is_layer_exists",
|
|
59
|
+
description: "Checks if a layer exists in the active sprite",
|
|
60
|
+
params: ["layerName"],
|
|
61
|
+
scriptPath: path.join(__dirname, "templates", "get_is_layer_exists.lua")
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: "get_is_tag_exists",
|
|
65
|
+
description: "Checks if a tag exists in the active sprite",
|
|
66
|
+
params: ["tagName"],
|
|
67
|
+
scriptPath: path.join(__dirname, "templates", "get_is_tag_exists.lua")
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
id: "get_palette_info",
|
|
71
|
+
description: "Gets information about the palette of the active sprite",
|
|
72
|
+
params: [],
|
|
73
|
+
scriptPath: path.join(__dirname, "templates", "get_palette_info.lua")
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: "get_selection_bounds",
|
|
77
|
+
description: "Gets the bounds of the selection in the active sprite",
|
|
78
|
+
params: [],
|
|
79
|
+
scriptPath: path.join(__dirname, "templates", "get_selection_bounds.lua")
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: "get_tag_list",
|
|
83
|
+
description: "Gets a list of all tags in the active sprite",
|
|
84
|
+
params: [],
|
|
85
|
+
scriptPath: path.join(__dirname, "templates", "get_tag_list.lua")
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
id: "get_layer_list",
|
|
89
|
+
description: "Gets a list of all layers in the active sprite",
|
|
90
|
+
params: [],
|
|
91
|
+
scriptPath: path.join(__dirname, "templates", "get_layer_list.lua")
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: "get_frame_info",
|
|
95
|
+
description: "Gets information about the current frame",
|
|
96
|
+
params: [],
|
|
97
|
+
scriptPath: path.join(__dirname, "templates", "get_frame_info.lua")
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: "get_active_sprite_info",
|
|
101
|
+
description: "Gets information about the active sprite",
|
|
102
|
+
params: [],
|
|
103
|
+
scriptPath: path.join(__dirname, "templates", "get_active_sprite_info.lua")
|
|
56
104
|
}
|
|
57
105
|
];
|
|
58
106
|
export function findLuaTemplate(id) {
|
package/build/lua/tools.js
CHANGED
|
@@ -18,40 +18,319 @@ export function createToolHandlers() {
|
|
|
18
18
|
}))
|
|
19
19
|
});
|
|
20
20
|
};
|
|
21
|
-
const
|
|
21
|
+
const run_lua_template = async ({ templateId, params }) => {
|
|
22
22
|
const template = findLuaTemplate(templateId);
|
|
23
23
|
if (!template) {
|
|
24
|
-
|
|
24
|
+
throw new Error(`Unknown templateId: ${templateId}`);
|
|
25
25
|
}
|
|
26
26
|
const missing = template.params.filter(key => !params.hasOwnProperty(key));
|
|
27
27
|
if (missing.length > 0) {
|
|
28
|
-
|
|
28
|
+
throw new Error(`Missing required params: ${missing.join(", ")}`);
|
|
29
29
|
}
|
|
30
|
+
const result = await runLuaScriptFile(template.scriptPath, params);
|
|
31
|
+
if (result.timedOut) {
|
|
32
|
+
throw new Error(`Lua script timed out while executing template: ${templateId}`);
|
|
33
|
+
}
|
|
34
|
+
const stderrTrimmed = result.stderr.trim();
|
|
35
|
+
const stdoutTrimmed = result.stdout.trim();
|
|
36
|
+
if (stderrTrimmed && stderrTrimmed.includes("ERROR:")) {
|
|
37
|
+
throw new Error(`Script execution failed: ${stderrTrimmed}`);
|
|
38
|
+
}
|
|
39
|
+
if (stdoutTrimmed && stdoutTrimmed.includes("ERROR:")) {
|
|
40
|
+
throw new Error(`Script execution failed: ${stdoutTrimmed}`);
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
command: result.command,
|
|
44
|
+
stdout: stdoutTrimmed,
|
|
45
|
+
stderr: stderrTrimmed,
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
const auto_crop_transparent = async ({ saveOutput, inputFile }) => {
|
|
30
49
|
try {
|
|
31
|
-
const result = await
|
|
32
|
-
|
|
33
|
-
|
|
50
|
+
const result = await run_lua_template({
|
|
51
|
+
templateId: "auto_crop_transparent",
|
|
52
|
+
params: {
|
|
53
|
+
inputFile,
|
|
54
|
+
saveOutput: ensureSafePath(saveOutput, { createDirIfNeeded: true })
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return successResult("auto_crop_transparent", {
|
|
58
|
+
command: result.command,
|
|
59
|
+
stdout: result.stdout,
|
|
60
|
+
stderr: result.stderr
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
return errorResult("auto_crop_transparent", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const merge_visible_layers = async ({ saveOutput, inputFile }) => {
|
|
68
|
+
try {
|
|
69
|
+
const result = await run_lua_template({
|
|
70
|
+
templateId: "merge_visible_layers",
|
|
71
|
+
params: {
|
|
72
|
+
inputFile,
|
|
73
|
+
saveOutput: ensureSafePath(saveOutput, { createDirIfNeeded: true })
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return successResult("merge_visible_layers", {
|
|
77
|
+
command: result.command,
|
|
78
|
+
stdout: result.stdout,
|
|
79
|
+
stderr: result.stderr
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
return errorResult("merge_visible_layers", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const normalize_animation_speed = async ({ saveOutput, targetDuration, inputFile }) => {
|
|
87
|
+
try {
|
|
88
|
+
const result = await run_lua_template({
|
|
89
|
+
templateId: "normalize_animation_speed",
|
|
90
|
+
params: {
|
|
91
|
+
inputFile,
|
|
92
|
+
saveOutput: ensureSafePath(saveOutput, { createDirIfNeeded: true }),
|
|
93
|
+
targetDuration
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
return successResult("normalize_animation_speed", {
|
|
97
|
+
command: result.command,
|
|
98
|
+
stdout: result.stdout,
|
|
99
|
+
stderr: result.stderr
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
return errorResult("normalize_animation_speed", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const recolor_palette = async ({ saveOutput, mapping, inputFile }) => {
|
|
107
|
+
try {
|
|
108
|
+
const result = await run_lua_template({
|
|
109
|
+
templateId: "recolor_palette",
|
|
110
|
+
params: {
|
|
111
|
+
saveOutput: ensureSafePath(saveOutput, { createDirIfNeeded: true }),
|
|
112
|
+
mapping,
|
|
113
|
+
inputFile
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
return successResult("recolor_palette", {
|
|
117
|
+
command: result.command,
|
|
118
|
+
stdout: result.stdout,
|
|
119
|
+
stderr: result.stderr
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
return errorResult("recolor_palette", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const remove_layer_by_name = async ({ layerName, saveOutput, inputFile }) => {
|
|
127
|
+
try {
|
|
128
|
+
const result = await run_lua_template({
|
|
129
|
+
templateId: "remove_layer_by_name",
|
|
130
|
+
params: {
|
|
131
|
+
layerName,
|
|
132
|
+
saveOutput: ensureSafePath(saveOutput, { createDirIfNeeded: true }),
|
|
133
|
+
inputFile
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
return successResult("remove_layer_by_name", {
|
|
137
|
+
command: result.command,
|
|
138
|
+
stdout: result.stdout,
|
|
139
|
+
stderr: result.stderr
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch (err) {
|
|
143
|
+
return errorResult("remove_layer_by_name", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const export_layer_only = async ({ layerName, outputDir, inputFile }) => {
|
|
147
|
+
try {
|
|
148
|
+
const result = await run_lua_template({
|
|
149
|
+
templateId: "export_layer_only",
|
|
150
|
+
params: {
|
|
151
|
+
layerName,
|
|
152
|
+
outputDir: ensureSafePath(outputDir, { createDirIfNeeded: true }),
|
|
153
|
+
inputFile
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return successResult("export_layer_only", {
|
|
157
|
+
command: result.command,
|
|
158
|
+
stdout: result.stdout,
|
|
159
|
+
stderr: result.stderr
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
return errorResult("export_layer_only", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
const export_tag_frames = async ({ tag, outputDir, filenamePrefix, inputFile }) => {
|
|
167
|
+
try {
|
|
168
|
+
const result = await run_lua_template({
|
|
169
|
+
templateId: "export_tag_frames",
|
|
170
|
+
params: {
|
|
171
|
+
tag,
|
|
172
|
+
outputDir: ensureSafePath(outputDir, { createDirIfNeeded: true }),
|
|
173
|
+
filenamePrefix: filenamePrefix,
|
|
174
|
+
inputFile
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
return successResult("export_tag_frames", {
|
|
178
|
+
command: result.command,
|
|
179
|
+
stdout: result.stdout,
|
|
180
|
+
stderr: result.stderr
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
return errorResult("export_tag_frames", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
const get_is_layer_exists = async ({ layerName, inputFile }) => {
|
|
188
|
+
try {
|
|
189
|
+
const result = await run_lua_template({
|
|
190
|
+
templateId: "get_is_layer_exists",
|
|
191
|
+
params: { layerName, inputFile }
|
|
192
|
+
});
|
|
193
|
+
// Parse the boolean result from stdout
|
|
194
|
+
// Aseprite outputs Lua return values as JSON
|
|
195
|
+
const stdoutTrimmed = result.stdout.trim();
|
|
196
|
+
let exists;
|
|
197
|
+
if (stdoutTrimmed === "") {
|
|
198
|
+
// Empty stdout might mean false or error
|
|
199
|
+
exists = false;
|
|
34
200
|
}
|
|
35
|
-
|
|
201
|
+
else {
|
|
202
|
+
try {
|
|
203
|
+
// Aseprite outputs Lua return values as JSON
|
|
204
|
+
const parsed = JSON.parse(stdoutTrimmed);
|
|
205
|
+
exists = parsed === true;
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
// If not valid JSON, try string comparison
|
|
209
|
+
exists = stdoutTrimmed.toLowerCase() === "true" || stdoutTrimmed === "1";
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return successResult("get_is_layer_exists", exists);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
return errorResult("get_is_layer_exists", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const get_is_tag_exists = async ({ tagName, inputFile }) => {
|
|
219
|
+
try {
|
|
220
|
+
const result = await run_lua_template({
|
|
221
|
+
templateId: "get_is_tag_exists",
|
|
222
|
+
params: { tagName, inputFile }
|
|
223
|
+
});
|
|
224
|
+
// Parse the boolean result from stdout
|
|
225
|
+
// Aseprite outputs Lua return values as JSON
|
|
36
226
|
const stdoutTrimmed = result.stdout.trim();
|
|
37
|
-
|
|
38
|
-
|
|
227
|
+
let exists;
|
|
228
|
+
if (stdoutTrimmed === "") {
|
|
229
|
+
// Empty stdout might mean false or error
|
|
230
|
+
exists = false;
|
|
39
231
|
}
|
|
40
|
-
|
|
41
|
-
|
|
232
|
+
else {
|
|
233
|
+
try {
|
|
234
|
+
// Aseprite outputs Lua return values as JSON
|
|
235
|
+
const parsed = JSON.parse(stdoutTrimmed);
|
|
236
|
+
exists = parsed === true;
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// If not valid JSON, try string comparison
|
|
240
|
+
exists = stdoutTrimmed.toLowerCase() === "true" || stdoutTrimmed === "1";
|
|
241
|
+
}
|
|
42
242
|
}
|
|
43
|
-
return successResult("
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
243
|
+
return successResult("get_is_tag_exists", exists);
|
|
244
|
+
}
|
|
245
|
+
catch (err) {
|
|
246
|
+
return errorResult("get_is_tag_exists", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
const get_palette_info = async ({ inputFile }) => {
|
|
250
|
+
try {
|
|
251
|
+
const result = await run_lua_template({
|
|
252
|
+
templateId: "get_palette_info",
|
|
253
|
+
params: { inputFile }
|
|
254
|
+
});
|
|
255
|
+
// Parse the JSON result from stdout
|
|
256
|
+
const parsedResult = JSON.parse(result.stdout.trim());
|
|
257
|
+
return successResult("get_palette_info", parsedResult);
|
|
258
|
+
}
|
|
259
|
+
catch (err) {
|
|
260
|
+
return errorResult("get_palette_info", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
const get_selection_bounds = async ({ inputFile }) => {
|
|
264
|
+
try {
|
|
265
|
+
const result = await run_lua_template({
|
|
266
|
+
templateId: "get_selection_bounds",
|
|
267
|
+
params: { inputFile }
|
|
268
|
+
});
|
|
269
|
+
// Parse the JSON result from stdout
|
|
270
|
+
const parsedResult = JSON.parse(result.stdout.trim());
|
|
271
|
+
return successResult("get_selection_bounds", parsedResult);
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
return errorResult("get_selection_bounds", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
const get_tag_list = async ({ inputFile }) => {
|
|
278
|
+
try {
|
|
279
|
+
const result = await run_lua_template({
|
|
280
|
+
templateId: "get_tag_list",
|
|
281
|
+
params: { inputFile }
|
|
282
|
+
});
|
|
283
|
+
// Parse the JSON result from stdout
|
|
284
|
+
const parsedResult = JSON.parse(result.stdout.trim());
|
|
285
|
+
return successResult("get_tag_list", parsedResult);
|
|
286
|
+
}
|
|
287
|
+
catch (err) {
|
|
288
|
+
return errorResult("get_tag_list", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
const get_layer_list = async ({ inputFile }) => {
|
|
292
|
+
try {
|
|
293
|
+
const result = await run_lua_template({
|
|
294
|
+
templateId: "get_layer_list",
|
|
295
|
+
params: { inputFile }
|
|
296
|
+
});
|
|
297
|
+
// Parse the JSON result from stdout
|
|
298
|
+
const parsedResult = JSON.parse(result.stdout.trim());
|
|
299
|
+
return successResult("get_layer_list", parsedResult);
|
|
300
|
+
}
|
|
301
|
+
catch (err) {
|
|
302
|
+
return errorResult("get_layer_list", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
const get_frame_info = async ({ inputFile }) => {
|
|
306
|
+
try {
|
|
307
|
+
const result = await run_lua_template({
|
|
308
|
+
templateId: "get_frame_info",
|
|
309
|
+
params: { inputFile }
|
|
310
|
+
});
|
|
311
|
+
// Parse the JSON result from stdout
|
|
312
|
+
const parsedResult = JSON.parse(result.stdout.trim());
|
|
313
|
+
return successResult("get_frame_info", parsedResult);
|
|
314
|
+
}
|
|
315
|
+
catch (err) {
|
|
316
|
+
return errorResult("get_frame_info", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
const get_active_sprite_info = async ({ inputFile }) => {
|
|
320
|
+
try {
|
|
321
|
+
const result = await run_lua_template({
|
|
322
|
+
templateId: "get_active_sprite_info",
|
|
323
|
+
params: { inputFile }
|
|
48
324
|
});
|
|
325
|
+
// Parse the JSON result from stdout
|
|
326
|
+
const parsedResult = JSON.parse(result.stdout.trim());
|
|
327
|
+
return successResult("get_active_sprite_info", parsedResult);
|
|
49
328
|
}
|
|
50
329
|
catch (err) {
|
|
51
|
-
return errorResult("
|
|
330
|
+
return errorResult("get_active_sprite_info", `Execution failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
52
331
|
}
|
|
53
332
|
};
|
|
54
|
-
const aseprite_run_lua_script = async ({ scriptPath, scriptContent, params
|
|
333
|
+
const aseprite_run_lua_script = async ({ scriptPath, scriptContent, params }) => {
|
|
55
334
|
try {
|
|
56
335
|
let luaFilePath;
|
|
57
336
|
if (scriptPath) {
|
|
@@ -86,25 +365,97 @@ export function createToolHandlers() {
|
|
|
86
365
|
};
|
|
87
366
|
return {
|
|
88
367
|
aseprite_list_lua_templates,
|
|
89
|
-
|
|
90
|
-
|
|
368
|
+
aseprite_run_lua_script,
|
|
369
|
+
auto_crop_transparent,
|
|
370
|
+
merge_visible_layers,
|
|
371
|
+
normalize_animation_speed,
|
|
372
|
+
recolor_palette,
|
|
373
|
+
remove_layer_by_name,
|
|
374
|
+
export_layer_only,
|
|
375
|
+
export_tag_frames,
|
|
376
|
+
get_is_layer_exists,
|
|
377
|
+
get_is_tag_exists,
|
|
378
|
+
get_palette_info,
|
|
379
|
+
get_selection_bounds,
|
|
380
|
+
get_tag_list,
|
|
381
|
+
get_layer_list,
|
|
382
|
+
get_frame_info,
|
|
383
|
+
get_active_sprite_info,
|
|
91
384
|
};
|
|
92
385
|
}
|
|
93
386
|
;
|
|
94
387
|
export function createToolSchemas() {
|
|
95
388
|
return {
|
|
96
|
-
aseprite_run_lua_template: z.object({
|
|
97
|
-
templateId: z.string(),
|
|
98
|
-
params: z.record(z.string(), z.any()).optional()
|
|
99
|
-
}),
|
|
100
389
|
aseprite_run_lua_script: z
|
|
101
390
|
.object({
|
|
102
391
|
scriptPath: z.string().optional(),
|
|
103
392
|
scriptContent: z.string().optional(),
|
|
104
|
-
params: z.
|
|
393
|
+
params: z.object({
|
|
394
|
+
inputFile: z.string(),
|
|
395
|
+
}).passthrough()
|
|
105
396
|
})
|
|
106
397
|
.refine(v => !!v.scriptPath || !!v.scriptContent, {
|
|
107
398
|
message: "Either scriptPath or scriptContent is required."
|
|
108
399
|
}),
|
|
400
|
+
auto_crop_transparent: z.object({
|
|
401
|
+
saveOutput: z.string(),
|
|
402
|
+
inputFile: z.string(),
|
|
403
|
+
}),
|
|
404
|
+
merge_visible_layers: z.object({
|
|
405
|
+
saveOutput: z.string(),
|
|
406
|
+
inputFile: z.string(),
|
|
407
|
+
}),
|
|
408
|
+
normalize_animation_speed: z.object({
|
|
409
|
+
saveOutput: z.string(),
|
|
410
|
+
targetDuration: z.number(),
|
|
411
|
+
inputFile: z.string(),
|
|
412
|
+
}),
|
|
413
|
+
recolor_palette: z.object({
|
|
414
|
+
saveOutput: z.string(),
|
|
415
|
+
mapping: z.string(),
|
|
416
|
+
inputFile: z.string(),
|
|
417
|
+
}),
|
|
418
|
+
remove_layer_by_name: z.object({
|
|
419
|
+
layerName: z.string(),
|
|
420
|
+
saveOutput: z.string(),
|
|
421
|
+
inputFile: z.string(),
|
|
422
|
+
}),
|
|
423
|
+
export_layer_only: z.object({
|
|
424
|
+
layerName: z.string(),
|
|
425
|
+
outputDir: z.string(),
|
|
426
|
+
inputFile: z.string(),
|
|
427
|
+
}),
|
|
428
|
+
export_tag_frames: z.object({
|
|
429
|
+
tag: z.string(),
|
|
430
|
+
outputDir: z.string(),
|
|
431
|
+
filenamePrefix: z.string().optional(),
|
|
432
|
+
inputFile: z.string(),
|
|
433
|
+
}),
|
|
434
|
+
get_is_layer_exists: z.object({
|
|
435
|
+
layerName: z.string(),
|
|
436
|
+
inputFile: z.string(),
|
|
437
|
+
}),
|
|
438
|
+
get_is_tag_exists: z.object({
|
|
439
|
+
tagName: z.string(),
|
|
440
|
+
inputFile: z.string(),
|
|
441
|
+
}),
|
|
442
|
+
get_palette_info: z.object({
|
|
443
|
+
inputFile: z.string(),
|
|
444
|
+
}),
|
|
445
|
+
get_selection_bounds: z.object({
|
|
446
|
+
inputFile: z.string(),
|
|
447
|
+
}),
|
|
448
|
+
get_tag_list: z.object({
|
|
449
|
+
inputFile: z.string(),
|
|
450
|
+
}),
|
|
451
|
+
get_layer_list: z.object({
|
|
452
|
+
inputFile: z.string(),
|
|
453
|
+
}),
|
|
454
|
+
get_frame_info: z.object({
|
|
455
|
+
inputFile: z.string(),
|
|
456
|
+
}),
|
|
457
|
+
get_active_sprite_info: z.object({
|
|
458
|
+
inputFile: z.string(),
|
|
459
|
+
}),
|
|
109
460
|
};
|
|
110
461
|
}
|