Skip to content

Releases: with-pebbly/aseprite-ai-artist

v0.8.2

Choose a tag to compare

@fedorovvvv fedorovvvv released this 12 Oct 15:26

Fixed

  • The OpenCode plugin loads from a git install. opencode plugin add …::path:opencode keeps only the plugin subdirectory in its cache, so the
    plugin failed on ../hooks/shared.mjs and found no skills. It now resolves
    both from the published package (declared dependency) when the sibling tree
    is absent, and the install command names the #main ref it needs.

0.8.1 — OpenCode support

Choose a tag to compare

@fedorovvvv fedorovvvv released this 11 Oct 22:38

Changed

  • lua.run is gated on both sides. The Aseprite extension refuses the
    escape hatch unless the Aseprite process was started with
    ASEPRITE_AI_ALLOW_LUA=1, so the capability itself — not just the tool entry
    — is off by default. Headless sessions inherit the variable from the server
    when --allowLua is set.

  • Git-install bootstrap pins its lockfile. bin/aseprite-ai-artist.mjs
    builds first-run installs with npm ci --ignore-scripts, so a plugin
    installed from git cannot execute dependency lifecycle scripts.

  • README hero in 3D. The rainy bookshop is redrawn in two-point perspective
    as a 16-second multiplane shot at 24 fps (384 frames): 24 layers, the depth
    planes swaying with the camera, rain falling at three depths with every drop
    splashing on whatever it hits, a maple that sways and sheds leaves with the
    utility pole passing through its crown, light
    shafts and puddle reflections moving against the facade, and the lightning
    throwing long shadows. Same shop, same story; a girl in a big knit sweater
    now reads inside.

  • Benchmark score: craft counts most. The composite is now 50% craft from
    human judges, 35% criteria passed, 15% speed (was 50% criteria, 35% craft,
    15% speed). A rating may carry the judge's own overall (0–10 integer), which
    replaces the axis mean as their craft score — the 0–4 axes could not hold a
    0–10 score without merging neighbours (4 and 5, 7 and 8). The existing
    human:fedorovvvv overall scores are migrated to it.

  • Packs sort by score. A pack's cards, and so its cover, are ordered
    best-first by score; the order in pack.yaml no longer matters.

Added

  • OpenCode install target. install opencode writes the MCP server into
    OpenCode 2.x's config (~/.config/opencode/opencode.json, native
    mcp.servers shape — OpenCode 1.x cannot read it), with MCP prompts off so
    the plugin's /aseprite:* commands do not double.
  • OpenCode plugin. /aseprite:* commands, skills, bridge status and the
    look nudge for OpenCode V2, loaded from the repo (checkout path or
    github:...::path:opencode).
  • Gallery pack: the rainy bookshop, before and after. The old hero
    (plugin 0.2.0) and the 3D cut (0.8.0), both by Claude Opus 5.5, with their
    sources and prompts.
  • Site: sound effects. Every control on the site now clicks, selects,
    toggles or opens with a short retro sound, and opening a pack has a
    soundtrack cued by its animation: the shake, the foil tearing, the cards
    rising and each ring of the fan being dealt. The effects are Kenney's CC0
    sounds picked from soundcn (credits in apps/web/static/sounds/CREDITS.txt).
    A speaker switch in the header (and the phone menu) turns them off; with no
    choice made, they start off for visitors whose system asks for reduced
    motion. Nothing plays before the first click or key press on a page.

Fixed

  • sprite_info is valid under strict output validation. The extension
    reports modified; the declared output schema did not allow it. OpenCode's
    MCP client rejects any result with undeclared properties, so the tool failed
    there while every other harness never noticed — the field is now declared.

  • Gallery prompts in English. The blacksmith generation now keeps its
    Russian prompt in original and the English rendering in text, like the
    others.

0.8.0 — review by fresh eyes

Choose a tag to compare

@fedorovvvv fedorovvvv released this 07 Oct 08:52

Added

  • Review by fresh eyes. studio now hands everything it drew to the
    pixel-critic agent, which runs on Opus and starts with a cold read — what
    the picture shows to someone never told what it is — and checks for murky
    value. A draft ships when the critique has no BLOCKING finding and scores
    7/10 or more; below that, each round makes one named fix, at most three
    rounds. A round snapshots what it touches, a fix that changes more than
    about a quarter of a layer counts as a redraw and is restored, and a fix is
    kept only if one critic call, shown the old and new versions blind, picks
    the new one — scores from separate calls proved not to share a scale.
    animate draws objects that grow on screen at three or four hand-made
    sizes, and the critic inspects key frames at full zoom. The effect on
    quality is not established: thirteen single-run experiments, all in the
    gallery beside the benchmark rows.

  • Site: a knowledge base. /knowledge shows the pixel-art rulebook the
    agents follow — every rule, grouped by band, with its ```grid templates
    drawn as pixel pictures beside their legend and source — plus every skill,
    agent and bundled palette, with search across all of them. Each document has
    its own page with a sidebar of the whole base, an outline, and previous/next;
    rules:// references in the text link to the rule they name. The pages are
    in the sitemap and /llms.txt, and the plugin page's skill and agent cards
    link to them.

  • About 2000 bundled palettes. knowledge/palettes.json grows from six
    presets to 2006: the hand-written classics plus Lospec's 2000 most-downloaded
    palettes, each with its author and source URL
    (docs/PALETTES.md;
    scripts/fetch-lospec-palettes.ts refreshes them). palette op preset
    still loads by key; a key that does not exist is now a search, answering
    with up to 20 matching keys instead of the whole list. The site lists them
    all at /knowledge/palettes, searchable by name, author, tag and size, with
    infinite scroll; the catalogue loads as a separate JSON file.

  • Site: 8-bit toggle group. A port of 8bitcn's ToggleGroup on bits-ui
    (keyboard and pressed state included), now used by the palette size filter
    and the compare page's Slider/Grid switch; the knowledge base's section links
    share its look.

  • Gallery: packs. gallery/packs/<slug>/pack.yaml groups related
    generations under one title (ADR-0012). On
    the gallery and home walls a pack is one sealed booster tile in place of its
    pieces, matched by a filter when any piece inside matches. /packs/<slug>
    opens it: the pack shakes, the seal tears and the cards deal out into a fan,
    with every card listed below; reduced motion shows the fan already open. Each
    piece's page links back to its pack. pnpm gallery:check rejects a pack with
    an unknown or invalid member or a piece in two packs, and packs are
    maintainer-only like benchmark prompts. The benchmark runs now come in four
    packs, one per prompt.

  • README: a live leaderboard. "Which model?" embeds
    /leaderboard/{light,dark}.svg from the site instead of a hand-written
    table — the same ranking as /benchmarks, redrawn on every deploy, in
    GitHub's light or dark theme to match the reader.

Changed

  • Site: the header fits every width. Below 1024 px the section links, the
    GitHub count and the theme switch move into a burger menu — a sheet from the
    right edge that traps focus, closes on Escape, a backdrop click or
    navigation, and hands focus back to the button. Knowledge joins the links.
  • Site: a redesign pass over every page. The site sits in a faint lavender
    wash (with CRT scanlines in the dark theme) under a glass
    header. Every page opens with the same hero — a spaced-caps eyebrow, a title
    with a one-pixel arcade drop shadow, a lead — and sections carry a stepped
    accent marker. One orange call to action per screen; cards and framed
    buttons lift a step on hover. The leaderboard gets gold, silver and bronze
    rank gems; the install and contribute pages get a numbered stepper with
    framed terminals; the compare page a control deck; the knowledge base, piece
    pages, 404 and the 8-bit controls (inputs, selects, toggles, tables,
    sliders, toasts, the mobile menu) are restyled to match.
  • Site: a pack flies to its page. Opening a pack from the gallery or home
    wall carries the sealed booster across the screen into the pack page through
    a view transition, and the opening waits for it to land before it shakes
    and tears.

0.7.0 — the pixel-art knowledge base

Choose a tag to compare

@fedorovvvv fedorovvvv released this 06 Oct 11:09

Added

  • A subject-by-subject pixel-art rulebook
    (ADR-0011). rules/ grows from
    eight general files to sixty-two, in numbered bands: technique (lines,
    clusters, anti-aliasing, dithering, readability), colour and materials,
    characters (proportions, anatomy, heads and faces, eyes and expressions,
    hands and feet, hair and clothing, design, views, portraits), animation
    (timing, idle, walk and run, jumps, attacks, secondary motion, subpixel,
    top-down), creatures, environments, objects and isometric, effects and UI,
    and style (platform eras, composition, tells of generated art). Each file
    has size budgets, procedures, mistakes, a review list and ```grid
    templates in the exact shape draw op grid takes — hands at 8–64 px, eye
    ladders, walk and run key poses, quadrupeds, circles and isometric cubes,
    tiles, flames. Written in our own words. rules://index groups them by
    band, studio maps each
    subject to its files, and the drawing skills and agents read them.
    tests/rules.test.ts compiles every template through the grid compiler,
    scripts/rule-templates.ts renders them to PNG for review, and a server
    test fails on any rules:// link that names no rule.

  • Site: score charts. Each benchmark page has a Run by run chart —
    every model's runs of that prompt, all models on one set of axes — and the
    benchmarks index has Score over time under the leaderboard: each model's
    leaderboard score on every day it ran, ending exactly on today's table.
    Both are drawn against dates: the window runs from just before the first
    run to today, a year at most, with days, weeks or months on the axis to
    suit. A marker is a run; the line is solid between runs and dashed across
    gaps of more than a week and before the first and after the last run. A
    model keeps one colour and marker shape on every chart; point at a run (or
    arrow-key through them) for every model's value that day, and pick a model
    in the legend to bring its line forward. The gallery now exports each
    leaderboard entry's history.

Changed

  • Site: the benchmark hero is a podium. It shows the top three models;
    the rest are in the full ranking below.

Fixed

  • palette op ramp and recolor op shade shifted hue the wrong way
    for half the wheel.
    Shading rotated hue in a fixed direction, so a red
    ramp's shadows went toward orange and its highlights toward magenta. Shadows
    now rotate toward blue and highlights toward yellow along the shorter arc,
    in both the server and the Lua extension.
  • validate with no checks skipped antialiasing, although the schema
    says omitting runs everything. Its description also listed odd-pixel
    asymmetry and cross-frame volume drift, which no check implements; it now
    says to judge those with look.
  • draw op ellipse drew even-sized boxes two pixels short — a 4×4 box
    gave a 2×2 square, 6×6 a 4×4 square — because the radius was measured to
    pixel corners. It now samples pixel centres against half the box, which
    reaches every edge of the box and matches the canonical small-circle and
    2:1 floor-ellipse tables in rules://72-3d-forms.

0.6.0

Choose a tag to compare

@fedorovvvv fedorovvvv released this 05 Oct 19:34

Added

  • Site: a page for the plugin at /plugin: what it is, repository and
    npm numbers, every skill and agent with its description, and the README as
    GitHub renders it. /plugin/install is the install guide — a three-step
    quick start with copy buttons, then docs/INSTALL.md in full. Header,
    footer and the contribute page link to both. Both pages refresh their GitHub
    data every two hours (Vercel ISR), and so does the header's star count;
    when GitHub cannot be reached, the page links there instead.
  • Site: SEO. Every page has its own title, description, Open Graph and
    Twitter card, plus JSON-LD where it fits (SoftwareApplication, HowTo,
    VisualArtwork, WebSite). New sitemap.xml — an index over per-section
    sitemaps for pages, benchmarks and the gallery — robots.txt pointing at
    it, a web manifest, and a share card. /llms.txt and /llms-full.txt give
    language models the site and the plugin in markdown.
  • Site: a full favicon set — .ico, SVG, 96 px, Apple touch and manifest
    icons — generated from the 16×16 Pebbly icon by
    pnpm --filter @pebbly/web run generate:icons (RealFaviconGenerator), every
    size an integer multiple of the pixel grid.
  • Site: a holographic accent (text-holo) for the few words that must
    pull the eye — the Plugin link, the GitHub star count now shown in the
    header, "agents" and "AI" in the page titles, and "by pebbly". The header
    logo hops and ripples into it on hover.

Changed

  • look op ascii and diff: glyphs are bound to palette indices. Glyph
    n is palette entry n on every read of a sprite, so a large sprite read in
    pieces has one legend, and rows from one piece draw back correctly in
    another. Before, glyphs were assigned per read, and the same letter could be
    two different colours in neighbouring regions. Colours outside the palette
    take the slots after it and are listed in the new offPalette field — the
    only glyphs that can change between reads. The alphabet grew from 72 to 261
    characters (Latin-1 and Latin Extended-A letters after ASCII), enough for a
    full 256-colour palette.
  • Text grids are bounded by the canvas, not by fixed sizes. look op
    ascii reads the whole canvas (was 4096 cells), and draw kind grid
    accepts up to the canvas size on each side (was 256).
  • Site: SvelteKit 3, adapter-vercel 7, and every other dependency at its
    latest, except TypeScript, held at 6: SvelteKit 3.0 and svelte-check still
    need TypeScript's JavaScript API, which TypeScript 7 no longer ships. The
    configuration moved from svelte.config.js into vite.config.ts, and the
    FSD layer aliases ($shared/…) became package.json subpath imports
    (#shared/….js). Vercel Web Analytics is wired through $app/state,
    because @vercel/analytics/sveltekit still imports the removed
    $app/stores.
  • Site: borders and corners. Borders step down with nesting — 6px outside,
    4px inside, 2px deeper — and every stepped corner gets the inner corner pixel
    the 8-bit components draw, instead of edges that stop short of each other.
    The lightbox closes with the site's pixel icon button.
  • Site: benchmark previews show the best-crafted run, not the
    highest-scoring one; score and date break ties.
  • Site: "Add your art". A button in the header on every page and one
    beside the gallery's title, both leading to the contribute page.
  • Benchmark: only human craft ratings count. Ratings from model judges
    stay valid in generation.yaml but are ignored — not shown, not scored —
    until they are re-evaluated.
  • Benchmark: a run with no recorded time is not penalised for speed. Its
    score is criteria and craft alone, rescaled to 0–100, instead of counting
    speed as 0.
  • Site: the benchmark page leads with the results. Each ranked model's
    best piece, winner first; the prompt and criteria close the page.

v0.5.0 — pixels as text

Choose a tag to compare

@fedorovvvv fedorovvvv released this 01 Oct 22:06

Added

  • Benchmark runs on 0.5.0. All three benchmarks re-run with Claude Opus 5.5
    using grid: the mage scores 14/15, the tree 12/13 and the road 13/14, and
    each can be set against its 0.4.0 run on the new compare page.

  • Site: compare runs of one benchmark. /benchmarks/<prompt>/compare,
    linked as Compare runs from a benchmark with two or more runs. Pick an
    image — any step's still, animation or filmstrip — then either drag a
    divider between two runs drawn at the same scale, so the same art pixel
    sits under the same screen pixel on both sides, or lay any number of runs
    out as a grid. Animations are decoded and played on one shared clock,
    each stretched to the longest loop, so they start and end together; a
    scrubber pauses and steps through them, and each run shows its own loop
    length and the speed it plays at. Filmstrips are shown raw — untimed,
    uncropped — as full-screen-width rows at a fixed height. The mode, image
    and runs are kept in the URL, so a comparison can be linked.

  • Site: renamed Pixeli, at pixeli.pebbly.space,
    with a pin-board gallery.
    Running text is set in Pixelify Sans, headings
    stay in Press Start 2P, and every page carries a canonical link to the
    deployed address. A new footer links the site, the plugin's docs and
    pebbly, signed with the pebbly logo redrawn in pixels. The home page's
    newest pieces and the gallery share one full-width wall. The gallery spans the
    whole screen in up to six masonry columns. Cards are drawn like pixel game
    cards — a stepped pixel frame, a name plate with the score as a gem, the
    art in its own framed window, a text plate — over a blurred glow of the
    art itself; benchmark cards share the design. Art everywhere fills its
    width edge to edge with the height following, and only art too wide to
    reach a minimum height gets space above and below. Images, the compare
    slider and grid tiles open full screen; page changes cross-fade through
    the View Transitions API, and a piece's art moves from its card to its
    page.

  • draw kind grid — draw by writing the picture. A legend (one
    character → colour, . transparent) and rows of text, one character per
    pixel, compiled on the server into ordinary draw ops. The model sees the
    whole silhouette while it writes it instead of composing it from shapes.
    transparent: "erase" (default) makes the rectangle exactly the grid;
    "skip" stamps over existing art. Ragged rows and undeclared characters are
    refused with their row and column. See ADR-0010.

  • look op ascii is the readable half of that round trip. It now returns
    gridRows and origin alongside legend, and rulers: false prints the
    bare rows: read a layer, edit the rows, send them back as a grid at the same
    origin. The draw, fix and animate skills use this for pixel-level
    edits and for redrawing a part from one key pose to the next.

  • Benchmark: craft ratings and run metrics. A generation can carry blind
    ratings — one per judge, 0–4 on read, form, motion, cohesion and
    appeal against the anchors in gallery/RUBRIC.md — and per-step
    metrics (minutes, tool calls, output tokens, cost). Compliance still ranks
    first; craft breaks ties and has its own column; cost is shown, never
    ranked. The checker refuses a model rating a run it took part in and a
    missing motion score on an animated run.

  • Gallery: references on every generation. Required, no default:
    source (none, generated by an image model, or supplied by the
    author), imageModels, kinds (concept-sheet, storyboard, …) and the
    optional image-model prompt, plus a reference file role. The benchmark
    ranks concept-assisted runs on their own row (model · concept by gpt-image-2), and the site shows the source on every generation page.
    aseprite:submit fills it in.

  • Gallery: steps[].original. A prompt sent in another language can be
    shown in English while the verbatim text is kept; benchmark runs cannot use
    it. The Pebbly generation's prompts now read in English with the Russian
    originals kept.

Changed

  • Benchmarks: the knight is retired; three fully specified prompts replace
    it.
    boombox-mage (a street-mage, then an anime sound-blast attack with
    an impact frame and effect layers confined to their beats), tree-growth
    (a cherry tree, then its growth from a seed built backwards from that exact
    final frame) and winding-road (a deep-perspective valley road, then a
    24-frame seamless ambient loop with a wagon travelling it). Each step text
    fixes size, palette, layout, colours, layer names, frame counts and timing,
    so runs on different models answer the same task. The eval guide moved to
    docs/evals/benchmarks.md.

Fixed

  • frame reorder keeps a tag that covers only the moved frame. Deleting
    the original frame took such a tag with it; it is now rebuilt with its name,
    colour, direction and repeats.
  • Erasing on an indexed sprite writes its transparent index. Region and
    selection clear — and so every . in a grid — wrote index 0, which is
    opaque on a sprite whose transparent index is something else.
  • draw selectionOnly clipped only pixels. The schema promised every
    op; rect, line, polyline, ellipse, fill, replace, dither,
    gradient, clear and blit painted straight through the selection. The
    clip now lives in the one function every primitive writes through, so a new
    op cannot miss it, and a contiguous fill no longer spreads across the
    selection edge.
  • frame op reorder always failed with command 'MoveFrame' not found
    — Aseprite 1.3 has no such command. It now moves the frame's cels and
    duration to toIndex through the sprite API and leaves tag ranges where
    they were.
  • draw op fill ignored tolerance. Every fill was exact. On RGB
    sprites tolerance is now the largest per-channel difference still counted
    as the clicked colour; indexed and grayscale fills stay exact.
  • look ops onion and filmstrip ignored layer. Over an opaque
    background the target frame covered every ghost, so onion skin of a moving
    prop in a scene showed nothing. Both now render only the named layer when
    one is given.
  • export ignored layers and tags. Both were in the schema and never
    read, so every export wrote every layer and frame. layers now limits png,
    gif, frames and spritesheet to those layers; tags limits gif, frames and
    spritesheet to the frames the tags cover. aseprite (and png for tags)
    refuses them instead of ignoring them.
  • look op ascii/diff with layer read the composite. The layer was
    passed through but the read stayed flattened, so a per-layer diff silently
    diffed the whole image. Naming a layer now reads that layer's cel.
  • Site: wide art no longer loses its left edge. An image wider than its
    box (a long filmstrip) was centred inside a scroll container, which pushed
    its left part out of reach; it now starts at the left and scrolls right.

v0.4.0

Choose a tag to compare

@fedorovvvv fedorovvvv released this 29 Sep 18:24

Added

  • Headless mode (serve --headless, ASEPRITE_AI_HEADLESS=1). The server
    runs one long-lived batch Aseprite (aseprite -b + headless/runner.lua)
    instead of driving an open window — for CI, scripted asset builds and
    machines without a display. Same tools and the same Lua command table;
    documents stay in memory until save/save_as/export. Chosen at startup
    or per session with preflight mode="headless"|"live" — aseprite:studio
    picks it from the request, --headless/--live force it; never a fallback.
    Refuses to open or write a file the user's attached
    Aseprite window has open (file_open_in_editor). preflight reports
    mode; doctor shows which executable headless would run; install --headless writes the flag, --aseprite the path.
    ADR-0008.
  • aseprite:concept skill — design with an image model, draw with the
    agent.
    Writes the art spec (scenario, palette hexes, view, key poses),
    turns it into a ready-to-paste prompt for a concept sheet or storyboard, and
    offers the user one choice: send references back or continue without. Then
    reads the reference into a PixelSpec and imports it. studio, brief,
    draw, animate, review, fix, animation-director and pixel-critic
    use it. ADR-0009.
  • reference op import takes region, grid and frame. region crops
    one panel of a sheet (also for sample_palette); grid cuts a storyboard into
    panels and puts panel i on frame i of one reference layer. frame was read by
    the extension but never reachable through the schema.
  • look op compare. The reference layer at full opacity beside the art
    without any reference layer, same frame and scale — rendered from a scratch
    copy, so nothing in the document changes. Needs install-extension and an
    Aseprite restart.
  • aseprite:submit skill. Turns a finished sprite into a gallery pull
    request: exports the .aseprite, cover, GIF and filmstrip with export,
    writes generation.yaml with the prompts verbatim and the model per step,
    scores benchmark criteria only from evidence it looked at, runs
    pnpm gallery:check, and opens the PR with gh — after asking.
  • The gallery (gallery/). A store of generations, each with its files,
    prompt sequence, models, harness and plugin version, validated by one zod
    schema (pnpm gallery:check, also in CI). The benchmark is derived from it:
    prompt × model × plugin version, scored against the prompt's criteria. The
    knight benchmark moved to gallery/prompts/knight/prompt.yaml.
    ADR-0006.
  • The site (apps/web). SvelteKit + shadcn-svelte with components ported
    from 8bitcn/ui and icons from pixelarticons: the benchmark as one block per
    prompt with a model × version matrix, a filterable gallery, a page per
    generation with downloads and copy-the-prompt buttons. Deploys to Vercel
    from main only. Generation files are linked from GitHub at the deployed
    commit rather than copied into the deployment.
  • Pebbly, the mascot — a pebble with a paintbrush sprouting from its head,
    drawn with the plugin itself: a 48×48 eight-frame idle for the site, and a
    brushless 12×9 pebble for the logo and favicon. It is the gallery's first
    generation.

Fixed

  • export ops spritesheet and frames honour scale. Both accepted it
    and wrote 1× files. They now export from a nearest-neighbour upscaled scratch
    copy — the source sprite is untouched and the copy is closed — so the atlas
    JSON describes the scaled texture. Needs install-extension and an Aseprite
    restart to take effect.

Changed

  • The repository is a pnpm workspace driven by turborepo. The plugin stays the
    root package and the published tarball is unchanged; contributors run
    pnpm install instead of npm install. The root package-lock.json stays,
    for the plugin launcher's first-run npm install on git installs, and CI
    fails when it drifts.

0.3.2

Choose a tag to compare

@fedorovvvv fedorovvvv released this 29 Sep 08:33

Changed

  • draw skill: text is its own step instead of a subsection of outlining, and
    the outline step explains side and diagonals. Fixed a garbled sentence in
    the animate skill.

0.3.1 — skills use the new tools

Choose a tag to compare

@fedorovvvv fedorovvvv released this 29 Sep 08:29

Changed

  • Skills, agents and rules now use the 0.3 tools. review, animate,
    animation-director and pixel-critic check in-betweens with look op
    onion and close with validate expect; fix reads changedBounds and
    routes labels to draw kind text; palette-smith knows palette op
    extract; rig-builder addresses twin layers by group path and reuses parts
    with layer duplicate toSprite; studio routes text and slice requests;
    the outline and review rules cover side/diagonals, onion and overlap
    checks.
  • README folds the 0.3 features into the skill guide instead of a separate
    what's-new list, and tells upgraders to reinstall the extension.

0.3.0 — onion skin, tweens, text and slices

Choose a tag to compare

@fedorovvvv fedorovvvv released this 29 Sep 08:18

Added

  • look op onion — the target frame at full opacity over ghosted
    neighbouring frames, oldest-first. For checking in-betweens and spacing
    while animating without stepping through frames one at a time.
  • look op diff reports changedBounds and percentChanged alongside
    the existing text grid, so a caller can read the size of a change without
    parsing the glyphs.
  • draw op kind text. Lays out a string from a bitmap font
    (knowledge/fonts/, one ships: pixel5x7) and expands it to plain pixels
    in TypeScript before it reaches Aseprite, so it shares the batch's palette
    lock and undo step. measureOnly returns each op's ink bounds without
    touching the sprite, for centring a label or sizing a panel first. See
    ADR-0005.
  • cel ops tween and oscillate. tween interpolates a cel's
    position or opacity between two frames with an easing curve; oscillate
    adds a sinusoidal position offset over a frame range. Both fill in any
    missing in-between cels from the start cel, in one transaction — for
    secondary motion like a bob, a breath, or a float.
  • sprite_manage ops slice_create, slice_update, slice_delete.
    Slices name a rectangular region of the canvas for an engine to read back:
    a 9-patch panel's center, or a hotspot's pivot. sprite_info's
    slices array now reports center/pivot when set, and they carry
    through into the spritesheet atlas on export.
  • palette op extract. Replaces the palette with one quantized from
    the art itself (RGB sprites only) — for deriving a curated palette from a
    reference image imported at full colour.
  • validate input expect. The animation contract you already know:
    layerFrames flags art outside a layer's expected frame ranges (or a
    missing cel inside one); mustNotOverlap flags any frame where two named
    layers' opaque pixels intersect. Runs independently of checks.
  • transform op outline gains side and diagonals. side: "inside"
    recolours opaque pixels touching transparency instead of growing the cel;
    diagonals switches 4- to 8-neighbour. Default behaviour (outside,
    4-neighbour) is unchanged.
  • layer op duplicate gains toSprite. Copies the layer's cels into
    another OPEN sprite by frame index; frames past the target's frame count
    are dropped and reported.
  • docs/evals/knight-benchmark.md — our own two-prompt benchmark (a
    still 32×32 knight, a windup-to-follow-through sword slash) with a fixed
    setup, a procedure, pass criteria and a results log.

Changed

  • Every layer parameter accepts a group/child path, and a name or
    path that matches more than one layer now fails with invalid_args naming
    every match, instead of silently resolving to one of them. Duplicate layer
    names were always possible in Aseprite; only ambiguous lookups now error —
    pass a group path to disambiguate.
  • Users must reinstall the extension. New ops (onion, text,
    tween/oscillate, slice_*, extract) need the extension side of this
    release: npx @pebbly/aseprite-ai-artist install-extension, then quit and
    reopen Aseprite.

Fixed

  • export op spritesheet no longer blocks on an overwrite prompt when
    the target files already exist
    (the call used to time out).