@koda-sl/baker-cli 0.35.0 → 0.36.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/README.md +123 -0
- package/dist/cli.js +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/commands/images/crop.d.ts +33 -0
- package/dist/commands/images/crop.d.ts.map +1 -0
- package/dist/commands/images/crop.js +90 -0
- package/dist/commands/images/crop.js.map +1 -0
- package/dist/commands/images/dimensions.d.ts +8 -0
- package/dist/commands/images/dimensions.d.ts.map +1 -0
- package/dist/commands/images/dimensions.js +56 -0
- package/dist/commands/images/dimensions.js.map +1 -0
- package/dist/commands/images/index.d.ts.map +1 -1
- package/dist/commands/images/index.js +20 -2
- package/dist/commands/images/index.js.map +1 -1
- package/dist/commands/images/normalize.d.ts +54 -0
- package/dist/commands/images/normalize.d.ts.map +1 -0
- package/dist/commands/images/normalize.js +252 -0
- package/dist/commands/images/normalize.js.map +1 -0
- package/dist/commands/images/upscale.d.ts +13 -0
- package/dist/commands/images/upscale.d.ts.map +1 -0
- package/dist/commands/images/upscale.js +73 -0
- package/dist/commands/images/upscale.js.map +1 -0
- package/dist/lib/image/color-changer.d.ts +16 -0
- package/dist/lib/image/color-changer.d.ts.map +1 -0
- package/dist/lib/image/color-changer.js +366 -0
- package/dist/lib/image/color-changer.js.map +1 -0
- package/dist/lib/image/color-changer.test.d.ts +2 -0
- package/dist/lib/image/color-changer.test.d.ts.map +1 -0
- package/dist/lib/image/color-changer.test.js +131 -0
- package/dist/lib/image/color-changer.test.js.map +1 -0
- package/dist/lib/image/crop-sprite.d.ts +9 -0
- package/dist/lib/image/crop-sprite.d.ts.map +1 -0
- package/dist/lib/image/crop-sprite.js +13 -0
- package/dist/lib/image/crop-sprite.js.map +1 -0
- package/dist/lib/image/dimensions.d.ts +9 -0
- package/dist/lib/image/dimensions.d.ts.map +1 -0
- package/dist/lib/image/dimensions.js +13 -0
- package/dist/lib/image/dimensions.js.map +1 -0
- package/dist/lib/image/image-processor.d.ts +26 -0
- package/dist/lib/image/image-processor.d.ts.map +1 -0
- package/dist/lib/image/image-processor.js +185 -0
- package/dist/lib/image/image-processor.js.map +1 -0
- package/dist/lib/image/io.d.ts +29 -0
- package/dist/lib/image/io.d.ts.map +1 -0
- package/dist/lib/image/io.js +90 -0
- package/dist/lib/image/io.js.map +1 -0
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -1595,6 +1595,10 @@ Each external source is its own subcommand. Pick the verb that matches the sourc
|
|
|
1595
1595
|
| `baker images get <id>` | Single record | n/a |
|
|
1596
1596
|
| `baker images upload <file\|url>` | Upload a local file OR remote URL to the library | always on |
|
|
1597
1597
|
| `baker images delete <id>` | Delete a record | n/a |
|
|
1598
|
+
| `baker images normalize <files>` | Local recolor + bg removal + trim + resize | n/a (operates on disk, no upload) |
|
|
1599
|
+
| `baker images upscale <imageId>` | Real-ESRGAN super-resolution via backend ($0.05/image, cost-tracked) | n/a (operates on library image) |
|
|
1600
|
+
| `baker images crop <file>` | Coordinate-based rectangular extract — local file or URL | n/a |
|
|
1601
|
+
| `baker images dimensions <file\|url>` | Read width / height / aspect / format without decoding | n/a |
|
|
1598
1602
|
|
|
1599
1603
|
**Auto-ingest** runs the full `processImage` pipeline (Gemini describe + Voyage multimodal embed + OpenRouter text embed) on every hit. Override with `--auto-ingest N` (turn on) or `--no-auto-ingest` (turn off where default is on). After auto-ingest the next `baker images library` query for the same concept hits the local row.
|
|
1600
1604
|
|
|
@@ -1975,6 +1979,125 @@ baker images delete j571abc123def --dry-run
|
|
|
1975
1979
|
baker images delete j571abc123def
|
|
1976
1980
|
```
|
|
1977
1981
|
|
|
1982
|
+
### `baker images normalize <files> [options]`
|
|
1983
|
+
|
|
1984
|
+
Local-file image normalization for logos and brand assets. Declarative — describe the desired final state via flags and the pipeline runs the needed stages in order. Operates on files in the sandbox; pair with `baker images upload` to ship results to the library. For super-resolution, upload first then use `baker images upscale <imageId>` (runs on the Convex backend, cost-tracked).
|
|
1985
|
+
|
|
1986
|
+
```bash
|
|
1987
|
+
# Recolor a logo row to white, height-normalize for a "trusted by" strip
|
|
1988
|
+
baker images normalize "logos/*.png" --color '#FFFFFF' --height 200
|
|
1989
|
+
|
|
1990
|
+
# Strip background only, in-place
|
|
1991
|
+
baker images normalize logo.png --remove-bg --shrink-to-content
|
|
1992
|
+
|
|
1993
|
+
# Uniform 200x200 grid tiles, contain by default
|
|
1994
|
+
baker images normalize "a.png,b.png,c.png" --size 200x200 --output ./out
|
|
1995
|
+
|
|
1996
|
+
# Resolve the pipeline without writing files
|
|
1997
|
+
baker images normalize "logos/*.png" --color '#000' --height 100 --dry-run
|
|
1998
|
+
```
|
|
1999
|
+
|
|
2000
|
+
Inputs accept a single path, a quoted glob, or a comma-separated list. Writes in-place by default; `--output` accepts a file (single input) or a directory (multiple inputs).
|
|
2001
|
+
|
|
2002
|
+
Pipeline stages, each opt-in via flag presence and idempotent on already-correct input:
|
|
2003
|
+
|
|
2004
|
+
1. Rasterize SVG (only when raster ops are requested — pure resize keeps SVG)
|
|
2005
|
+
2. `--remove-bg` → two-pass background removal with gradient/solid branching (skipped when the source is already transparent)
|
|
2006
|
+
3. `--color <hex>` → alpha-preserving recolor that maps every foreground pixel to the target color while varying alpha to preserve the original tonal variation
|
|
2007
|
+
4. `--shrink-to-content` → trim transparent borders
|
|
2008
|
+
5. Resize:
|
|
2009
|
+
- `--height N` / `--width N` → preserve aspect ratio (e.g. logo row)
|
|
2010
|
+
- `--size WxH [--fit contain|cover]` → fit into a box (`contain` letterboxes to transparent, `cover` crops)
|
|
2011
|
+
|
|
2012
|
+
Success response includes the resolved `stages` array per file so the agent can verify its declaration took effect:
|
|
2013
|
+
|
|
2014
|
+
```json
|
|
2015
|
+
{
|
|
2016
|
+
"ok": true,
|
|
2017
|
+
"data": {
|
|
2018
|
+
"processed": [{
|
|
2019
|
+
"input": "logo.svg",
|
|
2020
|
+
"output": "logo.png",
|
|
2021
|
+
"format": "png",
|
|
2022
|
+
"width": 264,
|
|
2023
|
+
"height": 200,
|
|
2024
|
+
"sizeBytes": 11510,
|
|
2025
|
+
"stages": ["rasterize-svg", "recolor", "trim", "resize"]
|
|
2026
|
+
}]
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
```
|
|
2030
|
+
|
|
2031
|
+
Validation errors return `VALIDATION_ERROR`:
|
|
2032
|
+
|
|
2033
|
+
- `--height`/`--width` together with `--size` (mutually exclusive)
|
|
2034
|
+
- `--fit` without `--size`
|
|
2035
|
+
- Malformed `--color` (must be `#RGB` or `#RRGGBB`)
|
|
2036
|
+
- Empty file pattern or no matches
|
|
2037
|
+
|
|
2038
|
+
### `baker images upscale <imageId>`
|
|
2039
|
+
|
|
2040
|
+
Super-resolution via the Convex backend (Replicate, cost-tracked at $0.05/image). Operates on a library image by ID — upload the file first via `baker images upload`, then upscale.
|
|
2041
|
+
|
|
2042
|
+
Waits for completion by default (polls every 1.5s, up to 2 min). Use `--max-wait 0` for fire-and-forget.
|
|
2043
|
+
|
|
2044
|
+
```bash
|
|
2045
|
+
baker images normalize logo.png --color '#FFFFFF' --remove-bg --height 100
|
|
2046
|
+
baker images upload logo.png --source uploaded
|
|
2047
|
+
# returns imageId — pass it to upscale
|
|
2048
|
+
baker images upscale j571abc123def
|
|
2049
|
+
baker images upscale j571abc123def --max-wait 0 # fire-and-forget
|
|
2050
|
+
```
|
|
2051
|
+
|
|
2052
|
+
Response on success:
|
|
2053
|
+
|
|
2054
|
+
```json
|
|
2055
|
+
{
|
|
2056
|
+
"ok": true,
|
|
2057
|
+
"data": {
|
|
2058
|
+
"imageId": "j571abc123def",
|
|
2059
|
+
"status": "completed",
|
|
2060
|
+
"image": { "_id": "...", "upscaledStorageKey": "...", "width": 400, "height": 400, ... }
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
```
|
|
2064
|
+
|
|
2065
|
+
Errors: `BAD_REQUEST` (not ready / not raster), `CONFLICT` (already upscaled / already processing), `TIMEOUT` (not complete within `--max-wait`).
|
|
2066
|
+
|
|
2067
|
+
### `baker images crop <file> --x N --y N --width N --height N`
|
|
2068
|
+
|
|
2069
|
+
Coordinate-based rectangular extract. Local file or remote URL. Writes a PNG.
|
|
2070
|
+
|
|
2071
|
+
```bash
|
|
2072
|
+
baker images crop sprite.png --x 0 --y 0 --width 64 --height 64 --output icon.png
|
|
2073
|
+
baker images crop https://example.com/sheet.png --x 128 --y 0 --width 128 --height 128 --output tile.png
|
|
2074
|
+
```
|
|
2075
|
+
|
|
2076
|
+
### `baker images dimensions <file-or-url>`
|
|
2077
|
+
|
|
2078
|
+
Width, height, aspect ratio, and format — read from the image header without full decode.
|
|
2079
|
+
|
|
2080
|
+
```bash
|
|
2081
|
+
baker images dimensions ./logo.png
|
|
2082
|
+
baker images dimensions https://acme.com/hero.png
|
|
2083
|
+
```
|
|
2084
|
+
|
|
2085
|
+
Response:
|
|
2086
|
+
|
|
2087
|
+
```json
|
|
2088
|
+
{
|
|
2089
|
+
"ok": true,
|
|
2090
|
+
"data": {
|
|
2091
|
+
"target": "./logo.png",
|
|
2092
|
+
"source": "file",
|
|
2093
|
+
"width": 553,
|
|
2094
|
+
"height": 419,
|
|
2095
|
+
"aspectRatio": 1.3198,
|
|
2096
|
+
"format": "png"
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
```
|
|
2100
|
+
|
|
1978
2101
|
### `baker videos search <query>`
|
|
1979
2102
|
|
|
1980
2103
|
Semantic search videos.
|
package/dist/cli.js
CHANGED
|
@@ -13,7 +13,7 @@ import { videosCommand } from "./commands/videos/index.js";
|
|
|
13
13
|
const main = defineCommand({
|
|
14
14
|
meta: {
|
|
15
15
|
name: "baker",
|
|
16
|
-
version: "0.
|
|
16
|
+
version: "0.36.0",
|
|
17
17
|
description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, and ad platform data in Baker.
|
|
18
18
|
|
|
19
19
|
Auth: Set BAKER_API_KEY (starts with bk_) and BAKER_API_URL environment variables.
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type ErrorCode = "UNAUTHORIZED" | "NOT_FOUND" | "VALIDATION_ERROR" | "RATE_LIMITED" | "INTERNAL_ERROR" | "NETWORK_ERROR" | "TIMEOUT";
|
|
1
|
+
type ErrorCode = "UNAUTHORIZED" | "NOT_FOUND" | "VALIDATION_ERROR" | "RATE_LIMITED" | "INTERNAL_ERROR" | "NETWORK_ERROR" | "TIMEOUT" | "IMAGE_PROCESSING_ERROR";
|
|
2
2
|
export declare class ApiError extends Error {
|
|
3
3
|
code: ErrorCode;
|
|
4
4
|
constructor(code: ErrorCode, message: string);
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AA6BA,KAAK,SAAS,GACV,cAAc,GACd,WAAW,GACX,kBAAkB,GAClB,cAAc,GACd,gBAAgB,GAChB,eAAe,GACf,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AA6BA,KAAK,SAAS,GACV,cAAc,GACd,WAAW,GACX,kBAAkB,GAClB,cAAc,GACd,gBAAgB,GAChB,eAAe,GACf,SAAS,GACT,wBAAwB,CAAC;AAE7B,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,EAAE,SAAS,CAAC;gBAEJ,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM;CAK7C;AAqBD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAIjD;AAsDD,wBAAsB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CA4BzF;AAED,wBAAsB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAuBvG"}
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AACjC,MAAM,iBAAiB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAExC,KAAK,UAAU,uBAAuB,CAAC,GAAW,EAAE,IAAiB;IACnE,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,sBAAsB,EAAE,OAAO,EAAE,EAAE,CAAC;QACnE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAExC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,OAAO,IAAI,sBAAsB,EAAE,CAAC;YACjE,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,OAAO,CAAC;QAExF,IAAI,WAAW,GAAG,MAAM,GAAG,iBAAiB,EAAE,CAAC;YAC7C,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,WAAW,IAAI,MAAM,CAAC;QACtB,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AAC1B,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare const cropCommand: import("citty").CommandDef<{
|
|
2
|
+
readonly file: {
|
|
3
|
+
readonly type: "positional";
|
|
4
|
+
readonly description: "Local file path or remote http(s) URL";
|
|
5
|
+
readonly required: false;
|
|
6
|
+
};
|
|
7
|
+
readonly x: {
|
|
8
|
+
readonly type: "string";
|
|
9
|
+
readonly description: "Left coordinate (px)";
|
|
10
|
+
readonly required: false;
|
|
11
|
+
};
|
|
12
|
+
readonly y: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly description: "Top coordinate (px)";
|
|
15
|
+
readonly required: false;
|
|
16
|
+
};
|
|
17
|
+
readonly width: {
|
|
18
|
+
readonly type: "string";
|
|
19
|
+
readonly description: "Region width (px)";
|
|
20
|
+
readonly required: false;
|
|
21
|
+
};
|
|
22
|
+
readonly height: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
readonly description: "Region height (px)";
|
|
25
|
+
readonly required: false;
|
|
26
|
+
};
|
|
27
|
+
readonly output: {
|
|
28
|
+
readonly type: "string";
|
|
29
|
+
readonly description: "Output path";
|
|
30
|
+
readonly required: false;
|
|
31
|
+
};
|
|
32
|
+
}>;
|
|
33
|
+
//# sourceMappingURL=crop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crop.d.ts","sourceRoot":"","sources":["../../../src/commands/images/crop.ts"],"names":[],"mappings":"AA+DA,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCtB,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import { cropSprite } from "../../lib/image/crop-sprite.js";
|
|
3
|
+
import { atomicWrite, isRemoteUrl, readImageBuffer, resolveOutputPath } from "../../lib/image/io.js";
|
|
4
|
+
import { writeJson } from "../../output.js";
|
|
5
|
+
import { registerSchema } from "../../schemas.js";
|
|
6
|
+
registerSchema({
|
|
7
|
+
command: "images.crop",
|
|
8
|
+
description: "Crop a rectangular region from a local image or remote URL. Coordinate-based extract.",
|
|
9
|
+
args: {
|
|
10
|
+
file: { type: "string", description: "Local file path or remote http(s) URL", required: true },
|
|
11
|
+
x: { type: "number", description: "Left coordinate (px)", required: true },
|
|
12
|
+
y: { type: "number", description: "Top coordinate (px)", required: true },
|
|
13
|
+
width: { type: "number", description: "Region width (px)", required: true },
|
|
14
|
+
height: { type: "number", description: "Region height (px)", required: true },
|
|
15
|
+
output: {
|
|
16
|
+
type: "string",
|
|
17
|
+
description: "Output path. Default: in-place for local files, ./crop.png for URLs.",
|
|
18
|
+
required: false,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
class ValidationError extends Error {
|
|
23
|
+
constructor(message) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.name = "ValidationError";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function parseRegion(args) {
|
|
29
|
+
const result = { x: 0, y: 0, width: 0, height: 0 };
|
|
30
|
+
for (const key of ["x", "y", "width", "height"]) {
|
|
31
|
+
const raw = args[key];
|
|
32
|
+
const n = typeof raw === "number" ? raw : raw !== undefined && raw !== "" ? Number(raw) : Number.NaN;
|
|
33
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
34
|
+
throw new ValidationError(`--${key} must be a non-negative number`);
|
|
35
|
+
}
|
|
36
|
+
result[key] = n;
|
|
37
|
+
}
|
|
38
|
+
if (result.width === 0 || result.height === 0) {
|
|
39
|
+
throw new ValidationError("--width and --height must be > 0");
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
function emitError(err) {
|
|
44
|
+
if (err instanceof ValidationError) {
|
|
45
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: err.message } });
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const message = err instanceof Error ? err.message : "Unexpected error";
|
|
49
|
+
writeJson({ ok: false, error: { code: "IMAGE_PROCESSING_ERROR", message } });
|
|
50
|
+
}
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
export const cropCommand = defineCommand({
|
|
54
|
+
meta: {
|
|
55
|
+
name: "crop",
|
|
56
|
+
description: "Crop a rectangular region from an image.\n\nExample: baker images crop sprite.png --x 0 --y 0 --width 64 --height 64 --output icon.png",
|
|
57
|
+
},
|
|
58
|
+
args: {
|
|
59
|
+
file: { type: "positional", description: "Local file path or remote http(s) URL", required: false },
|
|
60
|
+
x: { type: "string", description: "Left coordinate (px)", required: false },
|
|
61
|
+
y: { type: "string", description: "Top coordinate (px)", required: false },
|
|
62
|
+
width: { type: "string", description: "Region width (px)", required: false },
|
|
63
|
+
height: { type: "string", description: "Region height (px)", required: false },
|
|
64
|
+
output: { type: "string", description: "Output path", required: false },
|
|
65
|
+
},
|
|
66
|
+
run: async ({ args }) => {
|
|
67
|
+
try {
|
|
68
|
+
const file = args.file;
|
|
69
|
+
if (!file) {
|
|
70
|
+
throw new ValidationError("file argument is required");
|
|
71
|
+
}
|
|
72
|
+
const region = parseRegion(args);
|
|
73
|
+
const outputArg = typeof args.output === "string" && args.output.length > 0 ? args.output : undefined;
|
|
74
|
+
const inputBuffer = await readImageBuffer(file);
|
|
75
|
+
const output = await cropSprite(inputBuffer, region);
|
|
76
|
+
const outputPath = isRemoteUrl(file)
|
|
77
|
+
? (outputArg ?? "./crop.png")
|
|
78
|
+
: await resolveOutputPath(file, outputArg, { multipleInputs: false, newExtension: ".png" });
|
|
79
|
+
await atomicWrite(outputPath, output);
|
|
80
|
+
writeJson({
|
|
81
|
+
ok: true,
|
|
82
|
+
data: { input: file, output: outputPath, sizeBytes: output.length, region },
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
emitError(err);
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=crop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crop.js","sourceRoot":"","sources":["../../../src/commands/images/crop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const dimensionsCommand: import("citty").CommandDef<{
|
|
2
|
+
readonly target: {
|
|
3
|
+
readonly type: "positional";
|
|
4
|
+
readonly description: "Local file path or remote http(s) URL";
|
|
5
|
+
readonly required: false;
|
|
6
|
+
};
|
|
7
|
+
}>;
|
|
8
|
+
//# sourceMappingURL=dimensions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dimensions.d.ts","sourceRoot":"","sources":["../../../src/commands/images/dimensions.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,iBAAiB;;;;;;EA2C5B,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { defineCommand } from "citty";
|
|
2
|
+
import { getDimensionsFromBuffer } from "../../lib/image/dimensions.js";
|
|
3
|
+
import { isRemoteUrl, readImageBuffer } from "../../lib/image/io.js";
|
|
4
|
+
import { writeJson } from "../../output.js";
|
|
5
|
+
import { registerSchema } from "../../schemas.js";
|
|
6
|
+
registerSchema({
|
|
7
|
+
command: "images.dimensions",
|
|
8
|
+
description: "Return width, height, aspect ratio, and format for a local file or remote URL.",
|
|
9
|
+
args: {
|
|
10
|
+
target: { type: "string", description: "Local file path or remote http(s) URL", required: true },
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
export const dimensionsCommand = defineCommand({
|
|
14
|
+
meta: {
|
|
15
|
+
name: "dimensions",
|
|
16
|
+
description: "Read image dimensions without decoding the full file.\n\nExample: baker images dimensions ./logo.png\nExample: baker images dimensions https://acme.com/hero.png",
|
|
17
|
+
},
|
|
18
|
+
args: {
|
|
19
|
+
target: { type: "positional", description: "Local file path or remote http(s) URL", required: false },
|
|
20
|
+
},
|
|
21
|
+
run: async ({ args }) => {
|
|
22
|
+
try {
|
|
23
|
+
const target = args.target;
|
|
24
|
+
if (!target) {
|
|
25
|
+
writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "target argument is required" } });
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const buffer = await readImageBuffer(target);
|
|
29
|
+
const dims = getDimensionsFromBuffer(buffer);
|
|
30
|
+
if (!dims) {
|
|
31
|
+
writeJson({
|
|
32
|
+
ok: false,
|
|
33
|
+
error: { code: "IMAGE_PROCESSING_ERROR", message: `Could not extract dimensions from ${target}` },
|
|
34
|
+
});
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
writeJson({
|
|
38
|
+
ok: true,
|
|
39
|
+
data: {
|
|
40
|
+
target,
|
|
41
|
+
source: isRemoteUrl(target) ? "url" : "file",
|
|
42
|
+
width: dims.width,
|
|
43
|
+
height: dims.height,
|
|
44
|
+
aspectRatio: Math.round(dims.aspectRatio * 10000) / 10000,
|
|
45
|
+
format: dims.format,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
const message = err instanceof Error ? err.message : "Unexpected error";
|
|
51
|
+
writeJson({ ok: false, error: { code: "IMAGE_PROCESSING_ERROR", message } });
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=dimensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dimensions.js","sourceRoot":"","sources":["../../../src/commands/images/dimensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,cAAc,CAAC;IACb,OAAO,EAAE,mBAAmB;IAC5B,WAAW,EAAE,gFAAgF;IAC7F,IAAI,EAAE;QACJ,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uCAAuC,EAAE,QAAQ,EAAE,IAAI,EAAE;KACjG;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC;IAC7C,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,WAAW,EACT,kKAAkK;KACrK;IACD,IAAI,EAAE;QACJ,MAAM,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,uCAAuC,EAAE,QAAQ,EAAE,KAAK,EAAE;KACtG;IACD,GAAG,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACtB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,MAA4B,CAAC;YACjD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,6BAA6B,EAAE,EAAE,CAAC,CAAC;gBACtG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,SAAS,CAAC;oBACR,EAAE,EAAE,KAAK;oBACT,KAAK,EAAE,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,qCAAqC,MAAM,EAAE,EAAE;iBAClG,CAAC,CAAC;gBACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,SAAS,CAAC;gBACR,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE;oBACJ,MAAM;oBACN,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;oBAC5C,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,GAAG,KAAK;oBACzD,MAAM,EAAE,IAAI,CAAC,MAAM;iBACpB;aACF,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC;YACxE,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YAC7E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/images/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/images/index.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,aAAa,qDA0DxB,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { defineCommand } from "citty";
|
|
2
|
+
import { cropCommand } from "./crop.js";
|
|
2
3
|
import { deleteCommand } from "./delete.js";
|
|
4
|
+
import { dimensionsCommand } from "./dimensions.js";
|
|
3
5
|
import { extractCommand } from "./extract.js";
|
|
4
6
|
import { findCommand } from "./find.js";
|
|
5
7
|
import { getCommand } from "./get.js";
|
|
@@ -9,16 +11,18 @@ import { iconCommand } from "./icon.js";
|
|
|
9
11
|
import { ingestCommand } from "./ingest.js";
|
|
10
12
|
import { libraryCommand } from "./library.js";
|
|
11
13
|
import { logoCommand } from "./logo.js";
|
|
14
|
+
import { normalizeCommand } from "./normalize.js";
|
|
12
15
|
import { screenshotCommand } from "./screenshot.js";
|
|
13
16
|
import { searchCommand } from "./search.js";
|
|
14
17
|
import { stickerCommand } from "./sticker.js";
|
|
15
18
|
import { stockCommand } from "./stock.js";
|
|
16
19
|
import { uploadCommand } from "./upload.js";
|
|
20
|
+
import { upscaleCommand } from "./upscale.js";
|
|
17
21
|
import { useCommand } from "./use.js";
|
|
18
22
|
export const imagesCommand = defineCommand({
|
|
19
23
|
meta: {
|
|
20
24
|
name: "images",
|
|
21
|
-
description: `Find and
|
|
25
|
+
description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
|
|
22
26
|
|
|
23
27
|
Library + search:
|
|
24
28
|
baker images library <q> Search the company library (replaces search)
|
|
@@ -39,7 +43,17 @@ Ingest + management:
|
|
|
39
43
|
baker images use <url> Ingest and wait for ready
|
|
40
44
|
baker images upload ./file Upload local file
|
|
41
45
|
baker images get <id> Get a single record
|
|
42
|
-
baker images delete <id> Delete a record
|
|
46
|
+
baker images delete <id> Delete a record
|
|
47
|
+
|
|
48
|
+
Local transforms (operate on files in the sandbox, before upload):
|
|
49
|
+
baker images normalize <files> [--color …] [--remove-bg] [--height N | --width N | --size WxH]
|
|
50
|
+
Declarative recolor + bg removal + trim + resize
|
|
51
|
+
baker images crop <file> --x N --y N --width N --height N
|
|
52
|
+
Coordinate-based rectangular extract
|
|
53
|
+
baker images dimensions <file-or-url> Width / height / aspect / format without decoding the full image
|
|
54
|
+
|
|
55
|
+
Paid transforms (run on the Convex backend, cost-tracked):
|
|
56
|
+
baker images upscale <imageId> Real-ESRGAN super-resolution ($0.05/image, waits for completion)`,
|
|
43
57
|
},
|
|
44
58
|
subCommands: {
|
|
45
59
|
get: getCommand,
|
|
@@ -58,6 +72,10 @@ Ingest + management:
|
|
|
58
72
|
search: searchCommand,
|
|
59
73
|
upload: uploadCommand,
|
|
60
74
|
delete: deleteCommand,
|
|
75
|
+
normalize: normalizeCommand,
|
|
76
|
+
crop: cropCommand,
|
|
77
|
+
dimensions: dimensionsCommand,
|
|
78
|
+
upscale: upscaleCommand,
|
|
61
79
|
},
|
|
62
80
|
});
|
|
63
81
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/images/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IACzC,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/images/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IACzC,IAAI,EAAE;QACJ,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wHA+BuG;KACrH;IACD,WAAW,EAAE;QACX,GAAG,EAAE,UAAU;QACf,OAAO,EAAE,cAAc;QACvB,IAAI,EAAE,WAAW;QACjB,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,aAAa;QACrB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,UAAU;QACf,OAAO,EAAE,cAAc;QACvB,OAAO,EAAE,cAAc;QACvB,UAAU,EAAE,iBAAiB;QAC7B,MAAM,EAAE,aAAa;QACrB,GAAG,EAAE,UAAU;QACf,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,aAAa;QACrB,MAAM,EAAE,aAAa;QACrB,SAAS,EAAE,gBAAgB;QAC3B,IAAI,EAAE,WAAW;QACjB,UAAU,EAAE,iBAAiB;QAC7B,OAAO,EAAE,cAAc;KACxB;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export declare const normalizeCommand: import("citty").CommandDef<{
|
|
2
|
+
readonly files: {
|
|
3
|
+
readonly type: "positional";
|
|
4
|
+
readonly description: "Single path, glob (quote it), or comma-separated list";
|
|
5
|
+
readonly required: false;
|
|
6
|
+
};
|
|
7
|
+
readonly color: {
|
|
8
|
+
readonly type: "string";
|
|
9
|
+
readonly description: "Recolor target as hex";
|
|
10
|
+
readonly required: false;
|
|
11
|
+
};
|
|
12
|
+
readonly "remove-bg": {
|
|
13
|
+
readonly type: "boolean";
|
|
14
|
+
readonly description: "Two-pass background removal";
|
|
15
|
+
readonly required: false;
|
|
16
|
+
};
|
|
17
|
+
readonly "shrink-to-content": {
|
|
18
|
+
readonly type: "boolean";
|
|
19
|
+
readonly description: "Trim transparent borders";
|
|
20
|
+
readonly required: false;
|
|
21
|
+
};
|
|
22
|
+
readonly height: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
readonly description: "Resize to N px tall, width auto";
|
|
25
|
+
readonly required: false;
|
|
26
|
+
};
|
|
27
|
+
readonly width: {
|
|
28
|
+
readonly type: "string";
|
|
29
|
+
readonly description: "Resize to N px wide, height auto";
|
|
30
|
+
readonly required: false;
|
|
31
|
+
};
|
|
32
|
+
readonly size: {
|
|
33
|
+
readonly type: "string";
|
|
34
|
+
readonly description: "Fit into a WxH box (e.g. 200x200)";
|
|
35
|
+
readonly required: false;
|
|
36
|
+
};
|
|
37
|
+
readonly fit: {
|
|
38
|
+
readonly type: "string";
|
|
39
|
+
readonly description: "contain (default) or cover (with --size)";
|
|
40
|
+
readonly required: false;
|
|
41
|
+
};
|
|
42
|
+
readonly output: {
|
|
43
|
+
readonly type: "string";
|
|
44
|
+
readonly description: "Output path or directory";
|
|
45
|
+
readonly required: false;
|
|
46
|
+
};
|
|
47
|
+
readonly "dry-run": {
|
|
48
|
+
readonly type: "boolean";
|
|
49
|
+
readonly description: "Preview without writing";
|
|
50
|
+
readonly required: false;
|
|
51
|
+
readonly default: false;
|
|
52
|
+
};
|
|
53
|
+
}>;
|
|
54
|
+
//# sourceMappingURL=normalize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/commands/images/normalize.ts"],"names":[],"mappings":"AAsQA,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmD3B,CAAC"}
|