Repository navigation
Releases: Lonely-bear/pixel-art
Release list
dotloom-mcp v1.0.0
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
.pixelfile's version number now describes the format, not the document. The writer
stampedsprite.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 stampedPIXEL_FORMAT_VERSIONunconditionally.
A rig-less.pixelwritten now is refused by npm0.1.0through0.1.3— the releases
that predate rigs and knew only version 1. Version 1 files still load, and every release from
0.2.0onwards accepts version 2, so the exposure is a reader pinned four minor versions
behind. - Forward compatibility of
.pixelis still not promised, anddocs/STABILITY.mdnow 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.pixelsources to a game repo, pin the package version in
the same commit as the artwork — a committed.pixelis a migration, not a permanent
artefact. - An agent that reads only
tools/listnow sees less. Advertised parameter and tool
descriptions carry their first sentence; the full text is served bydescribe_commandand
thepixel://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
namespacescore,mcpandscript, shipped and named as the escape hatch rather than
promised.API_VERSIONstays at'1': the four names added since it was set were additions,
and an addition is additive.
packages/core/test/stability-contract.test.tschecks 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, somcp-tool-listispackages/mcp/test/tool-surface.test.tsrather 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,
exportEngineAssetsandtraceSvg. - 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 — withget_directions
to read it andgenerate_walk_cycleto 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: falsebecause a diagonal is a different drawing and no 45-degree pixel transform
survives a pixel grid. No 45-degree transform is ever emitted. trace_svgtraces 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 samemeta.jsonas 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.mjsbuilds and verifies them.- PNG provenance is carried, not burned.
export_pngandexport_sheetcan 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.jsonthat the MCP tool wrote is
now written by thepixelCLI 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, andexecutionno 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.
renderAssetBundleis 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, andanimationPreviewPayloadmoved into core — which is why a share template
can now ask for acontactoutput, whichshare_bundlepreviously refused by name. The
projection keeps the distinction the pipeline rests on: an abstention is not a pass, so
ExcludedReasonsurvives the move. - A deprecation rule, and deliberately no deprecation mechanism. Nothing is deprecated at 1.0,
so there is no@deprecatedmarker 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 bumpsapiVersion, never silently repurposed. - Nothing shipped changed a byte.
build-share.mjs --verifyreports byte-identical output for
210 files across two generations, andbuild-gallery.mjs --check-stalereports 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会被 npm0.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,而不是一个没人检查的承诺。 - 已发布的入口现在提供真实类型。 一个消费者的编译测试断言未声明的 ...
dotloom-mcp v0.5.0
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
anditem-iconsjoinplatformerinrecipes/, 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_recipeserves them (noidlists the catalogue), andpixel://recipesand
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: anevaluatecommand, an
evaluateMCP tool, apixel://quality/{doc}resource, and a quality gate on
finalize_documentthat refuses a failing asset and leaves a notice when it is bypassed. A
fixcommand 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. -
noiseis 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 replayableops.json, a
per-call measurement manifest, and PNGs that are byte-reproducible on every run.
scripts/showcase-build.mjsdrives 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.tsplus
recipes/platformer.recipe.jsonanddocs/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/,
withdocs/CLIENTS.mdand its Chinese mirror. -
An asset metadata contract.
docs/ASSET-CONTRACT.mdandpackages/core/src/asset/define
onemeta.jsonthat 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
calledevaluate; 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-palettefired 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. -
meanSatQwas 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 scorednoise200 of 1000 with all four measures reading
exactly zero. It was also wrong by a band.pnpm testis green and every declared clean control
now scores 1000. -
ditherMaskcould 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
isolatedanddiagOnly
unsatisfiable and gavespursthe wrong shape: one-pixel antennas were invisible and two of the
dimension's five codes had never been emitted once. -
colourOrphansfired 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-mcpmatches none of its branches: OpenCode read it as a server named
serverswith notypeand nocommand, and never configured anything — silently. The same bug
was indocs/REFERENCE.md, which is what a registry reviewer copies. -
npx.cmdis not a working command on Windows for this server:EINVALon every Node version
the package supports. The Windows configuration goes throughcmd+/c. -
Two OpenCode claims that could not be verified have been removed rather than hedged — the
non-interactiveopencode mcp add <name> -- <cmd>form, and the/mcpsslash 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. ThereachQgate 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,p9016..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-keeperhas 8 regions per
bucket,dusk-lake-valley-agent95,autumn-dusk-lake-256519, andsunset-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.
reachQturns 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 readreachQ max1000, 1000 and 996, and
those are the three with a measuredformQ), 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'sditherMask— specified, unimplemented, and declared asnoise's consumer. Until it
lands, the report'sgatedcolumn givescurvatureandreachas 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...
dotloom-mcp v0.4.2
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 anidle
tag, 33 commands — through the real command bus, writes an upscaled PNG and the editable
.pixelsource 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.pixelit 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.
--outand--sizeare 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 adevDependency, with no GUI, no MCP client and no editor running.
buildSprite(spec),buildAnimation(spec)andexportAssets(sprite, plan)are that
entry point, next toVERSIONandAPI_VERSION;core,mcpandscriptship beside
them as the documented escape hatch.exportAssetsreturns bytes and never writes to
disk — where they go belongs to the build system, not to this package.
docs/API.mdis the authority anddocs/API-ZH.md
mirrors it, andAPI_VERSIONis 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 is1here, and the eight exports are asserted by a test. -
The published entry is typechecked, and its surface is asserted.
pnpm typechecknow
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 onmix32andmulberry32rather 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 truncatedscatterseed,
Math.hypoton a result path, and aserializeSpritethat was never byte-reproducible
in the first place.deterministicIdFactoryis the opt-in for documents that have to come
out byte-identical. -
A
.pixelfile 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 withDate.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/failverdict, and a compile-time guard that fails the build if a
dimension id is added without its weights row.silhouetteandvalueare 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 never0,
because0is silently averaged in by every caller that trusted the field. The first
silhouetteimplementation scored ten full-bleed scenes a confident 800 with a blocking
shape-clippedissue, 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 —compactnessQ269 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 intothicknessPxandthicknessQ, which
is the shape of the thing: blade and horizon differ by 91 while every shape reading
stays identical. valuecan 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 — andkeyLight
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 beforequality_reportwas 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_documentrefusing, 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. - Applicability is declared per dimension, not per document class. A full-bleed
-
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 noexpectfield 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...
dotloom-mcp v0.4.1
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
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