Skip to content

Releases: Lonely-bear/pixel-art

dotloom-mcp v1.0.0

Choose a tag to compare

@github-actions github-actions released this 04 Oct 17:11

Installing

Platform File
Windows dotloom-mcp-*-x64-setup.exe — installs to your user profile, no admin needed
Windows, no install dotloom-mcp-*-x64-portable.exe — run it from anywhere, including a USB stick
macOS, Apple Silicon dotloom-mcp-*-arm64.dmg
macOS, Intel dotloom-mcp-*-x64.dmg
Linux dotloom-mcp-*-x86_64.AppImage — run it, nothing to install; or dotloom-mcp-*-amd64.deb on Debian/Ubuntu

Nothing else is required. The MCP server is built into the same binary as the
editor, so installing the app is the whole installation. The pixel CLI is not
part of that binary — it comes from npm (npm install -g dotloom-mcp), and so does
the headless server for anyone who wants one without the editor.

First launch on macOS

This build is not signed with an Apple Developer ID, so Gatekeeper blocks it
the first time. Either right-click dotloom-mcp.app and choose Open, or run:

xattr -dr com.apple.quarantine /Applications/dotloom-mcp.app

Windows builds are unsigned too, so SmartScreen warns once; choose
More info → Run anyway. Adding code signing certificates later does not
require a change to the app itself.


What's changed in 1.0.0

The 1.0 release: a published stability contract, four stable library exports added, the
share bundle and PNG provenance, and one real compatibility change to .pixel.

Breaking changes

  • A .pixel file's version number now describes the format, not the document. The writer
    stamped sprite.rig ? PIXEL_FORMAT_VERSION : 1, so a rig-less document declared itself
    version 1 and the same document declared version 2 the moment a rig was attached, and the
    archive bytes of a rig-less document were a function of its payload rather than of its
    content. Every file is now stamped PIXEL_FORMAT_VERSION unconditionally.
    A rig-less .pixel written now is refused by npm 0.1.0 through 0.1.3 — the releases
    that predate rigs and knew only version 1. Version 1 files still load, and every release from
    0.2.0 onwards accepts version 2, so the exposure is a reader pinned four minor versions
    behind.
  • Forward compatibility of .pixel is still not promised, and docs/STABILITY.md now says
    so in the direction that costs us: a file written by a newer build is refused by an older one,
    and a future build is not obliged to open yours. What 1.0 does promise is that format version 1
    and 2 load, that a non-integer or sub-1 version is refused, and that the archive is
    byte-reproducible. If you commit .pixel sources to a game repo, pin the package version in
    the same commit as the artwork
    — a committed .pixel is a migration, not a permanent
    artefact.
  • An agent that reads only tools/list now sees less. Advertised parameter and tool
    descriptions carry their first sentence; the full text is served by describe_command and
    the pixel://guide/{command} manuals. Nothing was deleted, and a test asserts every
    advertised description is a prefix of the served one.

Added

  • A 1.0 stability contract, and a guard that reads it. docs/STABILITY.md
    declares exactly what is stable: the nine named exports of the published package —
    buildSprite, buildAnimation, exportAssets, getDirectionModel, buildWalkAnimation,
    exportEngineAssets, traceSvg, VERSION, API_VERSION — plus the three internal
    namespaces core, mcp and script, shipped and named as the escape hatch rather than
    promised. API_VERSION stays at '1': the four names added since it was set were additions,
    and an addition is additive.
    packages/core/test/stability-contract.test.ts checks the declaration against the real
    published entry in both directions — a declared name that is not exported fails, an
    export that is not declared fails, and deleting the contract is itself a failure.
  • The negative half is written down too. Not stable: the 32-module engine barrel behind
    core, the MCP tool list and its parameters, the CLI flag surface, command parameter schemas,
    the quality pipeline's numbers, and the share card's layout. Each entry names the guard that
    owns it, so mcp-tool-list is packages/mcp/test/tool-surface.test.ts rather than a promise
    nobody checks.
  • The published entry ships real types. A consumer compile test asserts an undeclared
    specifier does not resolve, so a wrong call is a compile error rather than a runtime surprise.
  • Four more stable library exports, all additive: getDirectionModel, buildWalkAnimation,
    exportEngineAssets and traceSvg.
  • 8-direction characters. An angle model — the base pose is drawn facing E and each cardinal
    is a whole-figure rotation about an orientation anchor or its mirror — with get_directions
    to read it and generate_walk_cycle to write a walk cycle for any of the eight directions.
    Three drawings, not eight: N, S, E and W are derived exactly, the diagonals are marked
    exact: false because a diagonal is a different drawing and no 45-degree pixel transform
    survives a pixel grid. No 45-degree transform is ever emitted.
  • trace_svg traces an SVG outline into a cel.
  • share_bundle: a share template is a command with a template, not a script with its own
    serialisation.
    A share bundle writes the same engine files and the same meta.json as any
    other export, and adds a card and provenance — it is a view of the contract, never a second
    kind of artefact. Four templates ship: bare, card, handoff, review.
    scripts/build-share.mjs builds and verifies them.
  • PNG provenance is carried, not burned. export_png and export_sheet can write it, and
    the badge travels in the file's metadata rather than into the pixels.
  • The asset contract is on all four surfaces. The same meta.json that the MCP tool wrote is
    now written by the pixel CLI and by the desktop editor's export dialog too, with the Godot,
    Unity, Phaser and Excalidraw importers behind it.
  • A generated gallery of this repository's artwork, built by scripts/build-gallery.mjs,
    with a staleness gate that fails if the committed gallery no longer matches a fresh build.

Changed

  • The advertised tool surface is 29.6% smaller: 99,994 → 70,424 bytes, with no capability
    removed.
    The 667-byte result envelope repeated on every tool is now a 226-byte shape served
    with its prose on demand, and execution no longer restates a default. The ceiling moved from
    100,000 to 71,000 bytes — a budget with 6 bytes of headroom is a countdown, not a budget.
  • One asset-bundle renderer, in core. renderAssetBundle is now the single place that builds
    a contract, validates its naming and walks an importer, instead of four surfaces each holding
    that walk. The CLI and the app call it; the MCP tool and the share command import it.
  • One issue projection. The share card and the MCP quality report now share a projection of a
    report's issues, and animationPreviewPayload moved into core — which is why a share template
    can now ask for a contact output, which share_bundle previously refused by name. The
    projection keeps the distinction the pipeline rests on: an abstention is not a pass, so
    ExcludedReason survives the move.
  • A deprecation rule, and deliberately no deprecation mechanism. Nothing is deprecated at 1.0,
    so there is no @deprecated marker to honour and none was built. The rule for when there is
    one is written down: announced in both changelogs, kept working for the rest of the major
    version, removal bumps apiVersion, never silently repurposed.
  • Nothing shipped changed a byte. build-share.mjs --verify reports byte-identical output for
    210 files across two generations, and build-gallery.mjs --check-stale reports the committed
    gallery matches a fresh build.
中文变更说明 · 1.0.0(2026-10-04)

1.0 发布:一份已发布的稳定性契约、四个新增的稳定库导出、分享包与 PNG 溯源,以及 .pixel
上唯一一处真实的兼容性变更。

破坏性变更

  • .pixel 文件的版本号现在描述的是格式,而不是文档。 写出端此前写的是
    sprite.rig ? PIXEL_FORMAT_VERSION : 1,于是一个没有 rig 的文档自称版本 1,而同一个文档
    一旦加上 rig 就自称版本 2;没有 rig 的文档,其压缩包字节取决于载荷而不取决于内容。现在每个
    文件都无条件地写入 PIXEL_FORMAT_VERSION。
    现在写出的无 rig .pixel 会被 npm 0.1.0 到 0.1.3 拒绝 —— 那些版本早于 rig,
    只认识版本 1。版本 1 的文件仍然可以加载,而从 0.2.0 起的每个版本都接受版本 2,所以受影响的
    只有把阅读端固定在四个次版本之前的用户。
  • .pixel 的向前兼容仍然不被承诺,而且 docs/STABILITY.md 现在是以对我们不利的那个
    方向写明的:更新的构建写出的文件会被更旧的构建拒绝,而未来的构建也没有义务打开你的文件。
    1.0 承诺的是:格式版本 1 与 2 可以加载,非整数或小于 1 的版本会被拒绝,以及压缩包是字节
    可复现的。如果你把 .pixel 源文件提交进游戏的仓库,请在提交美术资源的那一次提交里同时
    固定包版本
    —— 一个被提交的 .pixel 是一次迁移,不是永久产物。
  • 只读 tools/list 的 Agent 现在看到的内容变少了。 对外广告的参数描述与工具描述现在
    只带第一句;完整文本由 describe_command 与 pixel://guide/{command} 手册提供。没有删除任何
    内容,并且有一条测试断言每条对外描述都是被提供文本的前缀。

新增

  • 一份 1.0 稳定性契约,以及一个会读它的守卫。 docs/STABILITY.md
    声明了究竟什么是稳定的:已发布包的九个具名导出 —— buildSprite、buildAnimation、
    exportAssets、getDirectionModel、buildWalkAnimation、exportEngineAssets、
    traceSvg、VERSION、API_VERSION —— 外加三个内部命名空间 core、mcp 与 script,
    它们已经发布,并被明确标记为逃生通道而不是承诺。API_VERSION 保持为 '1':自它设定以来
    新增的四个名字都是新增,而新增就是增量变更。
    packages/core/test/stability-contract.test.ts 双向对照真实的已发布入口检查这份声明 ——
    声明了却没有导出会失败,有导出却没有声明会失败,而删掉契约本身就是失败。
  • 反过来那一半也写下来了。 不稳定的有:core 背后的 32 个模块组成的引擎桶、MCP 工具
    列表及其参数、CLI 的参数面、命令的参数 schema、质量流水线的数值,以及分享卡片的版式。
    每一项都指明了负责它的守卫,所以 mcp-tool-list 是
    packages/mcp/test/tool-surface.test.ts,而不是一个没人检查的承诺。
  • 已发布的入口现在提供真实类型。 一个消费者的编译测试断言未声明的 ...
Read more

dotloom-mcp v0.5.0

Choose a tag to compare

@github-actions github-actions released this 03 Oct 21:09

Installing

Platform File
Windows dotloom-mcp-*-x64-setup.exe — installs to your user profile, no admin needed
Windows, no install dotloom-mcp-*-x64-portable.exe — run it from anywhere, including a USB stick
macOS, Apple Silicon dotloom-mcp-*-arm64.dmg
macOS, Intel dotloom-mcp-*-x64.dmg
Linux dotloom-mcp-*-x86_64.AppImage — run it, nothing to install; or dotloom-mcp-*-amd64.deb on Debian/Ubuntu

Nothing else is required. The MCP server is built into the same binary as the
editor, so installing the app is the whole installation. The pixel CLI is not
part of that binary — it comes from npm (npm install -g dotloom-mcp), and so does
the headless server for anyone who wants one without the editor.

First launch on macOS

This build is not signed with an Apple Developer ID, so Gatekeeper blocks it
the first time. Either right-click dotloom-mcp.app and choose Open, or run:

xattr -dr com.apple.quarantine /Applications/dotloom-mcp.app

Windows builds are unsigned too, so SmartScreen warns once; choose
More info → Run anyway. Adding code signing certificates later does not
require a change to the app itself.


What's changed in 0.5.0

Added

  • Four more recipes, and a way to read one. topdown-rpg, dungeon-tileset, ui-icons
    and item-icons join platformer in recipes/, each a full brief rather than a stub:
    canvas sizes with what each buys, palette ramps and a colour budget the ramps can reach,
    a layer stack, tone planes against one light, production order, ten mistakes with an action
    for each, and read-only checks. A recipe lands as a file — there is no registry to edit.
    describe_recipe serves them (no id lists the catalogue), and pixel://recipes and
    pixel://recipe/{id} serve the same bytes without a tool call.

  • The judgement layer is reachable. All six quality dimensions are registered (silhouette,
    value, palette, noise, outline, motion) and all six are now usable: an evaluate command, an
    evaluate MCP tool, a pixel://quality/{doc} resource, and a quality gate on
    finalize_document that refuses a failing asset and leaves a notice when it is bypassed. A
    fix command turns issues into executable ops where a safe repair exists, and into prose
    where one does not.

  • palette is the fourth dimension. Colour discipline over the composite. Two known false
    positives are recorded rather than loosened, because their remedies are upstream: quantize before
    evaluating, or declare the palette.

  • noise is the third quality dimension, and it is registered. Speckle, stray pixels and near
    duplicate ramp entries, over the worst frame. docs/EVALUATION.md §4.4 is the specification.

  • A showcase, generated through the advertised tool surface only.
    showcase/ironhold-knight/ carries the complete 14-call recipe as replayable ops.json, a
    per-call measurement manifest, and PNGs that are byte-reproducible on every run.
    scripts/showcase-build.mjs drives the real MCP server over stdio and imports nothing from
    @pixel/core — which is the point.

  • A recipe format, with a reference recipe. packages/core/src/recipes.ts plus
    recipes/platformer.recipe.json and docs/RECIPES.md. A recipe is guidance an agent reads and
    then executes through the existing tools, not a script. There is deliberately no field in it for
    a score: a format that can carry a target becomes one.

  • Copy-paste client configuration for claude, cursor, opencode and windsurf, in clients/,
    with docs/CLIENTS.md and its Chinese mirror.

  • An asset metadata contract. docs/ASSET-CONTRACT.md and packages/core/src/asset/ define
    one meta.json that the Godot, Unity, Phaser and Excalidraw importers can all consume. Identity
    is a content hash rather than a document id, because ids are clock-based and two identical
    sprites drawn a second apart must not have two identities.

  • scripts/baseline-rowdiff.mjs — a row-keyed diff of the calibration baseline, so a change
    reads as this subject, these columns, this direction rather than as a count of lines.

Fixed

  • A name collision that took the whole MCP server down. A core command and a session tool both
    called evaluate; the SDK throws on a duplicate registration, and in eager mode every server failed
    to start. 132 tests were failing for this. Both paths are guarded now.

  • off-palette fired a tenth as late as specified. The specification writes its thresholds in
    hundredths and the pipeline is per-mille, so a sprite 25% off its palette produced no issue at all.
    A silent miss is the worst direction available.

  • meanSatQ was scaled by 1000 twice, so it ran in a different dimension from every other ratio.

  • noise's dimension band table was written in descending-bound order and read in that order,
    which inverted it.
    A ratio of zero matched the loosest row and returned the worst sub-score,
    so every clean negative control scored noise 200 of 1000 with all four measures reading
    exactly zero. It was also wrong by a band. pnpm test is green and every declared clean control
    now scores 1000.

  • ditherMask could never return anything. The alternation scan exited on the first pixel it
    found, so the counter was capped at 1 and the ratio could not clear its own gate — on all 67
    corpus cases, including a perfect 50% checkerboard. It reported "no dither anywhere" while
    meaning "this counter cannot exceed 1".

  • The neighbour counts included the pixel itself, which made isolated and diagOnly
    unsatisfiable and gave spurs the wrong shape: one-pixel antennas were invisible and two of the
    dimension's five codes had never been emitted once.

  • colourOrphans fired on the repository's own clean work. It asked whether a pixel has a
    same-bucket 4-neighbour, and on a 1px staircase outline the answer is no at every corner — so a
    declared negative control read 31/1000 against a trigger of 8, and the ten committed scenes read
    9..153 because in a gradient the neighbours are the steps either side. Two replacements were
    measured and refuted before a third survived: the measure now asks whether anything within
    Chebyshev 2 agrees and whether the pixel's own lightness sits inside the range its
    surroundings span.

  • The OpenCode configuration in the README was invalid. Validated against the client's published
    schema, mcp.servers.dotloom-mcp matches none of its branches: OpenCode read it as a server named
    servers with no type and no command, and never configured anything — silently. The same bug
    was in docs/REFERENCE.md, which is what a registry reviewer copies.

  • npx.cmd is not a working command on Windows for this server: EINVAL on every Node version
    the package supports. The Windows configuration goes through cmd + /c.

  • Two OpenCode claims that could not be verified have been removed rather than hedged — the
    non-interactive opencode mcp add <name> -- <cmd> form, and the /mcps slash command.

  • Four committed scenes have no judged plane because their tone field is dithered, and the gate that
    was supposed to be at fault is not.
    The reachQ gate closes the last of the full-bleed scenes and
    reads its denominator as the subject's bounding box, which on a full-bleed document is the whole canvas
    — so a plane has to span half the picture to be judged. That is the same shape of error the previous two
    entries fixed for curvature, and the obvious move is to normalise against the form the plane cuts
    instead. Measured, that move is wrong, and this entry records why rather than making it.
    Plane extents are small everywhere: median 6..10px against a body of 64..512, p90 16..33. On
    artwork/sunset-lighthouse-512.pixel — 512², 1008 terminators — the largest plane is 110px where
    the gate wants 256. A region-relative denominator opens 110 planes there, and they are water ripples
    and sky sparks: a short plane inside a small region scores high on that ratio, so the change admits
    texture rather than form.
    Counting 4-connected same-bucket regions says what the pictures are: lantern-keeper has 8 regions per
    bucket, dusk-lake-valley-agent 95, autumn-dusk-lake-256 519, and sunset-lighthouse-512
    2,880 — 46,079 regions, 98.8% of them 16 pixels or smaller, in a painting with 16 tones. A
    hard-edged painting with 16 tones has tens of regions. That is a dithered and gradient tone field, and
    §4.2's plane definition — both sides an area — finds no plane across a dithered transition at all, so
    the sun's limb and the water's horizon there were never planes to gate.
    reachQ turns out to be an accidental dither detector pointing the right way: the scenes it opens are
    the least fragmented ones (95, 519 and 632 regions per bucket read reachQ max 1000, 1000 and 996, and
    those are the three with a measured formQ), and the two most fragmented read 215 and 236. So no gate
    changed.
    What is missing is the ability to say that a picture is dithered, and the quantity that
    would is §3.3's ditherMask — specified, unimplemented, and declared as noise's consumer. Until it
    lands, the report's gated column gives curvature and reach as reasons on pictures whose real reason
    is neither, and all four of those scenes have both gates closing something. The state is pinned by a
    test, so a future change that suddenly judges th...

Read more

dotloom-mcp v0.4.2

Choose a tag to compare

@github-actions github-actions released this 27 Sep 11:03

Installing

Platform File
Windows dotloom-mcp-*-x64-setup.exe — installs to your user profile, no admin needed
Windows, no install dotloom-mcp-*-x64-portable.exe — run it from anywhere, including a USB stick
macOS, Apple Silicon dotloom-mcp-*-arm64.dmg
macOS, Intel dotloom-mcp-*-x64.dmg
Linux dotloom-mcp-*-x86_64.AppImage — run it, nothing to install; or dotloom-mcp-*-amd64.deb on Debian/Ubuntu

Nothing else is required. The MCP server is built into the same binary as the
editor, so installing the app is the whole installation. The pixel CLI is not
part of that binary — it comes from npm (npm install -g dotloom-mcp), and so does
the headless server for anyone who wants one without the editor.

First launch on macOS

This build is not signed with an Apple Developer ID, so Gatekeeper blocks it
the first time. Either right-click dotloom-mcp.app and choose Open, or run:

xattr -dr com.apple.quarantine /Applications/dotloom-mcp.app

Windows builds are unsigned too, so SmartScreen warns once; choose
More info → Run anyway. Adding code signing certificates later does not
require a change to the app itself.


What's changed in 0.4.2

Added

  • pixel demo: the whole product, in one command. Someone who has just installed the
    package has nothing but Node, so this one takes no input file, no palette and no required
    arguments. It authors a 32×32 sprite — ten colours, six layers, two frames on an idle
    tag, 33 commands — through the real command bus, writes an upscaled PNG and the editable
    .pixel source beside it, and prints exactly one JSON object like every other command,
    so it composes with a shell script. The artwork is drawn the way a pixel artist blocks
    one in — one flat silhouette, a hue-shifted ramp, tonal planes that follow the form,
    light from a single direction, a consistent 1px contour — because a demo that looks
    procedural teaches people the wrong thing, and every mutation goes through
    Editor.execute, so the .pixel it leaves behind is a genuine document with a real undo
    history behind it. That is the proof this is a tool and not a texture generator.
    --out and --size are the only flags.

  • A build-time library API, for the half of the pipeline with nobody in the loop. An
    agent drives this product over MCP; a game's build script has to be able to drive it
    from code, as a devDependency, with no GUI, no MCP client and no editor running.
    buildSprite(spec), buildAnimation(spec) and exportAssets(sprite, plan) are that
    entry point, next to VERSION and API_VERSION; core, mcp and script ship beside
    them as the documented escape hatch. exportAssets returns bytes and never writes to
    disk — where they go belongs to the build system, not to this package.
    docs/API.md is the authority and docs/API-ZH.md
    mirrors it, and API_VERSION is the versioned contract: inside one major version of it
    only additive changes are permitted, so a build script can pin it and mean something.
    It is 1 here, and the eight exports are asserted by a test.

  • The published entry is typechecked, and its surface is asserted. pnpm typecheck now
    compiles the npm entry along with everything else (tsconfig.npm.json). It had no
    typecheck coverage at all, which meant a broken entry failed in a consumer's pipeline
    rather than in this one.

  • Determinism is a guarantee rather than an assumption. Every "random-looking" thing
    the engine draws — noise fields, scatter points, terrain variant choices, reflection
    wobble — now comes from one seeded source, built on mix32 and mulberry32 rather than
    an inlined hash of unknown provenance. What that buys is small and specific: a committed
    baseline diff means the artwork changed, not the run changed, and those are
    indistinguishable after the fact. Fields are position-addressed, so evaluation order is
    irrelevant and adding a pixel does not disturb its neighbours; streams are for sequential
    work, because a stream is order-dependent and skipping one draw shifts everything after
    it. Chasing this turned up three real defects — a truncated scatter seed,
    Math.hypot on a result path, and a serializeSprite that was never byte-reproducible
    in the first place. deterministicIdFactory is the opt-in for documents that have to come
    out byte-identical.

  • A .pixel file is byte-reproducible. The same ops, run twice, produce the same
    archive. Cel entries are named by position (cels/0_1.png) rather than embedding the
    layer id inside the filename, because an id comes from the clock and real entropy, and a
    filename that changes on every run makes "the source did not change" an uncheckable
    claim. The zip timestamp is pinned to 1980-01-01 local — fflate had been stamping
    every entry with Date.now(), so even a fully deterministic document produced a
    different archive on every save, and pinning the instant in UTC would instead have made
    the bytes depend on the machine's timezone. The rename is non-breaking in both
    directions, because the reader always resolved paths through the manifest, so the
    container version is deliberately not bumped.

  • A quality-analysis contract, an aggregator, and the first two of six dimensions.
    packages/core/src/quality/ freezes six dimensions with per-mille integer scores, a
    pass / warn / fail verdict, and a compile-time guard that fails the build if a
    dimension id is added without its weights row. silhouette and value are implemented
    and measured against this repository's own artwork, which is where the interesting part
    is:

    • Applicability is declared per dimension, not per document class. A full-bleed
      scene has no silhouette and no outline, and does have value structure and a palette —
      so a dimension that cannot measure a document contributes no number at all: its key
      is absent from the report and the reason is recorded, never a sentinel and never 0,
      because 0 is silently averaged in by every caller that trusted the field. The first
      silhouette implementation scored ten full-bleed scenes a confident 800 with a blocking
      shape-clipped issue, since for a scene whose ink runs to the frame the alpha boundary
      is the canvas edge. Ten confident wrong numbers are worse than none. The "is there a
      subject" test is deliberately a pixel margin rather than a per-mille quantity: a 1px
      margin is 234/1000 on a 16² canvas and 7/1000 at 2px on a 1024² one, and no single
      threshold serves both ends.
    • The threshold did not move; the measurement did. The only real character sprite in
      this repository was being penalised — compactnessQ 269 against a gate of 300 — and
      the dimension returned an identical 800 for artwork that had been rejected twice and
      artwork that had been accepted. The cause was the measurement, not the gate: compactness
      was computed over the whole mask, so a subject was paying for its own scattered pixels,
      and it was scale-invariant, so a 32² blade edge and a 1024² horizon scored the same. It
      is now computed per subject part and split into thicknessPx and thicknessQ, which
      is the shape of the thing: blade and horizon differ by 91 while every shape reading
      stays identical.
    • value can tell a bad shadow from a good one. A hard straight-diagonal band and
      correctly nested contours were 0.014 apart in the report total. They are now 385‰ apart
      in the dimension and 0.179 in the total — a whole verdict grade, which is the difference
      between a scorer and a mood ring.
    • Two findings are recorded and deliberately left unfixed, because the honest fix in
      each case is a new shared quantity rather than a threshold: the curvature gate reads
      nothing on a full-bleed subject, so the form sub-term is a perfect 1000 on all twelve
      real assets — a straight shadow band across the mountains passes today — and keyLight
      is a subject-level check being applied to scenes.

    None of this is an MCP tool, and none of it is on the advertised surface. A number an
    agent can see becomes the target instead of the artwork — that is how a lake got sanded
    into a dark flat rectangle before quality_report was deleted in 0.3.1 — so what ships
    here is a library, a specification and a calibration harness. The command, the tool and
    the gate that would consume them are later work, and the gate belongs in
    finalize_document refusing, not in a tool that advises. The lesson that produced
    AGENTS.md's "do not show an agent a number to optimise" section is written down rather
    than left as tribal knowledge.

  • A calibration corpus with ground truth by construction. 63 cases in three tiers:
    48 synthetic, each carrying a declared defect and what it must not fire on, because
    an analyzer that cries wolf on clean work is worse than one that misses a defect;
    12 real — this repository's committed artwork, which may assert quietness but never taste;
    and 3 awaiting a human rating, a tier whose type has no expect field at all, so no code
    path can compare an unrated image against an expectation. The tier boundaries are
    enforced by four loader rules rather than by a comment. Cases are declarative descriptions
    materialised deterministically a...

Read more

dotloom-mcp v0.4.1

Choose a tag to compare

@github-actions github-actions released this 26 Sep 11:16

Installing

Platform File
Windows dotloom-mcp-*-x64-setup.exe — installs to your user profile, no admin needed
Windows, no install dotloom-mcp-*-x64-portable.exe — run it from anywhere, including a USB stick
macOS, Apple Silicon dotloom-mcp-*-arm64.dmg
macOS, Intel dotloom-mcp-*-x64.dmg
Linux dotloom-mcp-*-x86_64.AppImage — run it, nothing to install; or dotloom-mcp-*-amd64.deb on Debian/Ubuntu

Nothing else is required. The CLI and the MCP server are built into the same
binary as the editor, so installing the app is the whole installation.

First launch on macOS

This build is not signed with an Apple Developer ID, so Gatekeeper blocks it
the first time. Either right-click dotloom-mcp.app and choose Open, or run:

xattr -dr com.apple.quarantine /Applications/dotloom-mcp.app

Windows builds are unsigned too, so SmartScreen warns once; choose
More info → Run anyway. Adding code signing certificates later does not
require a change to the app itself.

Full Changelog: v0.4.0...v0.4.1

dotloom-mcp v0.4.0

Choose a tag to compare

@github-actions github-actions released this 26 Sep 08:20

Installing

Platform File
Windows dotloom-mcp-*-x64-setup.exe — installs to your user profile, no admin needed
Windows, no install dotloom-mcp-*-x64-portable.exe — run it from anywhere, including a USB stick
macOS, Apple Silicon dotloom-mcp-*-arm64.dmg
macOS, Intel dotloom-mcp-*-x64.dmg
Linux dotloom-mcp-*-x86_64.AppImage — run it, nothing to install; or dotloom-mcp-*-amd64.deb on Debian/Ubuntu

Nothing else is required. The CLI and the MCP server are built into the same
binary as the editor, so installing the app is the whole installation.

First launch on macOS

This build is not signed with an Apple Developer ID, so Gatekeeper blocks it
the first time. Either right-click dotloom-mcp.app and choose Open, or run:

xattr -dr com.apple.quarantine /Applications/dotloom-mcp.app

Windows builds are unsigned too, so SmartScreen warns once; choose
More info → Run anyway. Adding code signing certificates later does not
require a change to the app itself.

Full Changelog: https://github.com/Lonely-bear/pixel-art/commits/v0.4.0