I salute your efforts, linking cels is one of those things that seems easy but there’s no clear explanation anywhere on how to do it.
The trick that I found is that in order to link cels, or even select them to be in the active range you need to specify BOTH - layers and frames, cels are on their intersection. With this knowledge you can write a script like this:
app.transaction(function()
local sprite = app.activeSprite
-- Create a new layer
local newLayer = sprite:newLayer()
newLayer.isContinuous = true
-- Creat a cel in the first frame of the layer, without this cels won't link
sprite:newCel(newLayer, 1)
-- Get all of the frame numbers into a table/array
local frames = {}
for frameNumber, _ in ipairs(sprite.frames) do
table.insert(frames, frameNumber)
end
-- In order to select cels in range we need to specify both layers and frame - cels are their intersection
app.range.frames = frames
app.range.layers = {newLayer}
app.command.LinkCels()
app.range:clear()
end)
No need for a new sprite in this approach which means no risk of losing data.
Definitely, you should add the feature where the new layer is above the current one and not on top of the stack - it will mimic how native Aseprite functionality for adding layers behaves, making it more intuitive for users. I’d suggest looking into Layer.stackIndex to achieve that.