@pixelvibing/cli 0.52.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/pixel-vibing-cli.js
CHANGED
|
@@ -4967,7 +4967,7 @@ const GENERATED = {
|
|
|
4967
4967
|
"ui-sketch": { references: 3, words: "a UI" }
|
|
4968
4968
|
};
|
|
4969
4969
|
const KIND_NAMES = { ui: "ui-sketch", [OLD_CONCEPT_ART]: CONCEPT_ART };
|
|
4970
|
-
const WORDS_ONLY = ["size", "transparent", "pixel-art", "no-pixel-art", "tag", "names", "purpose", "tiles", "sketch"];
|
|
4970
|
+
const WORDS_ONLY = ["size", "transparent", "pixel-art", "no-pixel-art", "tag", "mask", "names", "purpose", "tiles", "sketch"];
|
|
4971
4971
|
const MORE_REFERENCES = 3;
|
|
4972
4972
|
const ENRICHED = /* @__PURE__ */ new Set(["animate", "pose", "rotate", "terrain-animation"]);
|
|
4973
4973
|
function listOf(given2, what) {
|
|
@@ -5075,17 +5075,17 @@ function sizeOf(given2, what) {
|
|
|
5075
5075
|
if (match === null) throw new CliError(`${what} is <cols>x<rows>, such as 2x1, not ${given2}`);
|
|
5076
5076
|
return { cols: Number(match[1]), rows: Number(match[2]) };
|
|
5077
5077
|
}
|
|
5078
|
-
async function referenceOf(context, path) {
|
|
5078
|
+
async function referenceOf(context, path, what = "reference") {
|
|
5079
5079
|
const file = resolve(context.io.cwd, path);
|
|
5080
5080
|
let size;
|
|
5081
5081
|
try {
|
|
5082
5082
|
size = (await stat(file)).size;
|
|
5083
5083
|
} catch {
|
|
5084
|
-
throw new CliError(`the
|
|
5084
|
+
throw new CliError(`the ${what} ${path} cannot be read`);
|
|
5085
5085
|
}
|
|
5086
|
-
if (size > MAX_REFERENCE_BYTES) throw new CliError(`the
|
|
5086
|
+
if (size > MAX_REFERENCE_BYTES) throw new CliError(`the ${what} ${path} is ${size} bytes, and one is at most ${MAX_REFERENCE_BYTES}`);
|
|
5087
5087
|
const bytes = new Uint8Array(await readFile(file));
|
|
5088
|
-
if (!isPng(bytes)) throw new CliError(`the
|
|
5088
|
+
if (!isPng(bytes)) throw new CliError(`the ${what} ${path} is not a PNG`);
|
|
5089
5089
|
return bytes;
|
|
5090
5090
|
}
|
|
5091
5091
|
async function requestOf(context, asked, args) {
|
|
@@ -5126,6 +5126,7 @@ async function shapedRequest(context, asked, args) {
|
|
|
5126
5126
|
if (kind !== CONCEPT_ART) {
|
|
5127
5127
|
for (const flag of ["pixel-art", "transparent"]) if (flagOf(args, flag)) throw new CliError(`--${flag} is a concept art's`);
|
|
5128
5128
|
if (stringsOf(args, "tag").length > 0) throw new CliError("--tag is a concept art's");
|
|
5129
|
+
if (stringOf(args, "mask") !== void 0) throw new CliError("--mask is a concept art's");
|
|
5129
5130
|
}
|
|
5130
5131
|
if (kind === "ui-sketch") {
|
|
5131
5132
|
for (const flag of ["names", "purpose", "size", "tiles"])
|
|
@@ -5153,7 +5154,15 @@ async function shapedRequest(context, asked, args) {
|
|
|
5153
5154
|
for (const path of paths) references.push(await referenceOf(context, path));
|
|
5154
5155
|
if (kind === CONCEPT_ART) {
|
|
5155
5156
|
const { fields, words: words2 } = conceptFields(args, asked, instruction);
|
|
5156
|
-
|
|
5157
|
+
const maskPath = stringOf(args, "mask");
|
|
5158
|
+
const mask = maskPath === void 0 ? void 0 : await referenceOf(context, maskPath, "mask");
|
|
5159
|
+
const images = { ...references.length > 0 ? { references } : {}, ...mask === void 0 ? {} : { mask } };
|
|
5160
|
+
return {
|
|
5161
|
+
kind,
|
|
5162
|
+
body: { instruction, ...fields },
|
|
5163
|
+
...Object.keys(images).length > 0 ? { images } : {},
|
|
5164
|
+
words: mask === void 0 ? words2 : words2.replace(/^(a concept art [^:]*?)(:)/, "$1, within its mask$2")
|
|
5165
|
+
};
|
|
5157
5166
|
}
|
|
5158
5167
|
const body = { instruction };
|
|
5159
5168
|
let words = `${known.words}: ${instruction}`;
|
|
@@ -5195,7 +5204,7 @@ async function followed(context, platform, jobId) {
|
|
|
5195
5204
|
const generate = {
|
|
5196
5205
|
name: "generate",
|
|
5197
5206
|
summary: "Generate an asset, a change of a picture, terrain or a sound on the platform, then pull it, keep it or write it",
|
|
5198
|
-
usage: "<object|creature|concept-art|icons|ui|variant|edit|animate|pose|rotate|state|terrain|terrain-animation|sfx|speech|music> [--instruction <text>] [--source <image id>] [--state <state>] [--into <sprite> --name <name>] [--upper <ground> --lower <ground>] [--terrain <asset>] [--text <text> --voice <voice>] [--out <file>] [--size <c>x<r>|<w>x<h>|<px>] [--transparent] [--pixel-art] [--tiles <c>x<r>] [--tag <tag>]… [--names <list>] [--purpose skill|item] [--sketch <json>] [--reference <png>]… [--no-enrich] [--yes]",
|
|
5207
|
+
usage: "<object|creature|concept-art|icons|ui|variant|edit|animate|pose|rotate|state|terrain|terrain-animation|sfx|speech|music> [--instruction <text>] [--source <image id>] [--state <state>] [--into <sprite> --name <name>] [--upper <ground> --lower <ground>] [--terrain <asset>] [--text <text> --voice <voice>] [--out <file>] [--size <c>x<r>|<w>x<h>|<px>] [--transparent] [--pixel-art] [--tiles <c>x<r>] [--tag <tag>]… [--mask <png>] [--names <list>] [--purpose skill|item] [--sketch <json>] [--reference <png>]… [--no-enrich] [--yes]",
|
|
5199
5208
|
options: {
|
|
5200
5209
|
instruction: {
|
|
5201
5210
|
type: "string",
|
|
@@ -5215,6 +5224,11 @@ const generate = {
|
|
|
5215
5224
|
value: "<tag>",
|
|
5216
5225
|
description: "what a concept art is for, such as anchor, ui, character, environment, prop or level-design; at most 8"
|
|
5217
5226
|
},
|
|
5227
|
+
mask: {
|
|
5228
|
+
type: "string",
|
|
5229
|
+
value: "<png>",
|
|
5230
|
+
description: "where a concept art is drawn: an opaque black-and-white PNG in its shape, up to 1536 px a side, white drawn and black left empty"
|
|
5231
|
+
},
|
|
5218
5232
|
names: { type: "string", value: "<list>", description: `an icon set's icons, comma-separated, at most ${MAX_ICONS}` },
|
|
5219
5233
|
purpose: { type: "string", value: "skill|item", description: "whether an icon set is skills on badges or items alone; item unless given" },
|
|
5220
5234
|
tiles: { type: "string", value: "<cols>x<rows>", description: "how many tiles a pixel-art concept art is across, 6x4 unless given" },
|
|
@@ -5725,7 +5739,7 @@ const move = {
|
|
|
5725
5739
|
);
|
|
5726
5740
|
}
|
|
5727
5741
|
};
|
|
5728
|
-
const version = "0.
|
|
5742
|
+
const version = "0.53.0";
|
|
5729
5743
|
const manifest = {
|
|
5730
5744
|
version
|
|
5731
5745
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pixelvibing/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.0",
|
|
4
4
|
"description": "PixelVibing: pixel art game assets from the command line, and the Skills that teach coding assistants to make them.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://pixelvibing.com",
|
|
@@ -16,7 +16,7 @@ reference to what follows.
|
|
|
16
16
|
`pixel-vibing-cli generate --help` lists every option `generate` takes, with what each is for: read it for any option this Skill does not name, rather than guessing one.
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
pixel-vibing-cli generate concept-art --instruction "<the picture>" [--size <w>x<h>] [--transparent] [--tag <tag>]... [--reference <png>]... [--no-enrich] --yes --json
|
|
19
|
+
pixel-vibing-cli generate concept-art --instruction "<the picture>" [--size <w>x<h>] [--transparent] [--mask <png>] [--tag <tag>]... [--reference <png>]... [--no-enrich] --yes --json
|
|
20
20
|
pixel-vibing-cli generate concept-art --instruction "<the area>" --pixel-art --tiles <cols>x<rows> [--no-enrich] --yes --json
|
|
21
21
|
```
|
|
22
22
|
|
|
@@ -25,7 +25,7 @@ pixel-vibing-cli generate concept-art --instruction "<the area>" --pixel-art --t
|
|
|
25
25
|
```json
|
|
26
26
|
{ "project": "<id>", "kind": "concept-art", "instruction": "<the picture>",
|
|
27
27
|
"size": { "width": 1536, "height": 1024 }, "background": "transparent", "tags": ["anchor"],
|
|
28
|
-
"reference_images": ["<image id>"], "enrich": false, "max_percent": 40 }
|
|
28
|
+
"reference_images": ["<image id>"], "mask_image": "<image id>", "enrich": false, "max_percent": 40 }
|
|
29
29
|
{ "project": "<id>", "kind": "concept-art", "instruction": "<the area>", "pixel_art": true,
|
|
30
30
|
"tiles": { "cols": 6, "rows": 4 }, "max_percent": 40 }
|
|
31
31
|
```
|
|
@@ -45,6 +45,15 @@ which every other generation takes as `reference_images`.
|
|
|
45
45
|
`level-design`, `ui`, `character`, `environment`, `prop`, or one of the project's own
|
|
46
46
|
(`list_tags`). `pixel-vibing-cli tag` (MCP `tag_asset`) changes them later.
|
|
47
47
|
- **References.** Up to 8 to draw from, such as the anchor itself.
|
|
48
|
+
- **A mask.** Keeps the drawing to a shape you choose: an island's coastline, a
|
|
49
|
+
character's silhouette, a frame for a menu, the open middle of a scene. It is an opaque
|
|
50
|
+
PNG of black and white only, white where the art is drawn and black where the drawing is
|
|
51
|
+
left empty, in the drawing's shape: the `--size` (`1536x1024` unless given), or for pixel
|
|
52
|
+
art the `--tiles` in proportion, such as 3:2 for `6x4`. Any size in that shape is scaled
|
|
53
|
+
to fit, up to 1536 px a side, so a small one drawn by hand or by a script is enough. A soft edge is fine; grey
|
|
54
|
+
shading, colour or transparency is refused with the reason before anything is spent.
|
|
55
|
+
Pass it as `--mask <png>` (MCP: keep it with `upload_image`, then give its id as
|
|
56
|
+
`mask_image`). With `--transparent`, the black part comes back transparent as well.
|
|
48
57
|
- **A level design.** `--pixel-art --tiles <c>x<r>` (MCP `pixel_art`, `tiles`) draws an area
|
|
49
58
|
of the map as pixel art some tiles across, `6x4` unless given, tagged `level-design`; the
|
|
50
59
|
editor takes it apart into objects and terrain.
|