@cerebriline/core 4.100.248 → 4.100.250

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.
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Resize, crop and convert an image that is already a file.
3
+ *
4
+ * Asked for by the first person to generate images with this in earnest: "the
5
+ * harness needs the ability to dynamically change the image size", and to crop.
6
+ * An image model draws at the sizes it knows, a README wants 1200 pixels across
7
+ * and an installer wants an `.ico`, and until now the model's only way from one
8
+ * to the other was a shell command for a program that might not be installed.
9
+ *
10
+ * The work is done by the browser `render_image` already uses: it decodes
11
+ * every format a page can show and encodes the three that matter. So there is
12
+ * no image library here, and nothing new to ship.
13
+ */
14
+ import { type AgentTool } from "@cerebriline/shared";
15
+ import { type RenderDriver, type RenderRegion, type RenderResult } from "./render-image";
16
+ export declare const TRANSFORM_IMAGE_TOOL_NAME = "transform_image";
17
+ export declare const TRANSFORM_IMAGE_TOOL_DESCRIPTION = "Resize, crop or convert an image file in the workspace and save the result as a new file. Use it to change an image's dimensions, cut a region out of it, change its format, or make an icon file from it. The source is never modified.\n\n- `image` \u2014 workspace path of the source: PNG, JPEG, WebP, GIF, BMP, AVIF, ICO or SVG.\n- `path` \u2014 where to save, relative to the workspace. The extension chooses the format: `.png`, `.jpg`, `.webp`, `.ico` or `.icns`. Optional; defaults to a file beside the source with the new size in its name.\n- `width`, `height` \u2014 the new size in pixels. Give one and the other follows the proportions.\n- `fit` \u2014 with both given: `inside` (default; the whole image, within the box, proportions kept), `cover` (fills the box, the overflow cut off), `pad` (the whole image, padded to exactly the box) or `stretch`.\n- `crop` \u2014 `\"x,y,width,height\"` in pixels of the source, taken before resizing.\n- `background` \u2014 a CSS colour for padding and for what was transparent. Optional; transparency is kept where the format has it, and JPEG gets white.\n- `quality` \u2014 1 to 100 for `.jpg` and `.webp`, default 90.\n- `sizes` \u2014 for `.ico` and `.icns`, the sizes to hold, e.g. `\"16,32,48,256\"`. Optional; the usual set when left out.";
18
+ export declare const TRANSFORM_IMAGE_TOOL_INPUT_SCHEMA: {
19
+ readonly type: "object";
20
+ readonly properties: {
21
+ readonly image: {
22
+ readonly type: "string";
23
+ readonly description: "Workspace path of the source image.";
24
+ };
25
+ readonly path: {
26
+ readonly type: "string";
27
+ readonly description: "Where to save (.png, .jpg, .webp, .ico or .icns), relative to the workspace. Optional.";
28
+ };
29
+ readonly width: {
30
+ readonly type: "number";
31
+ readonly description: "New width in pixels. Optional.";
32
+ };
33
+ readonly height: {
34
+ readonly type: "number";
35
+ readonly description: "New height in pixels. Optional.";
36
+ };
37
+ readonly fit: {
38
+ readonly type: "string";
39
+ readonly enum: readonly ["inside", "cover", "pad", "stretch"];
40
+ readonly description: "How the image meets a box of both sizes. Optional.";
41
+ };
42
+ readonly crop: {
43
+ readonly type: "string";
44
+ readonly description: "\"x,y,width,height\" in source pixels. Optional.";
45
+ };
46
+ readonly background: {
47
+ readonly type: "string";
48
+ readonly description: "A CSS colour. Optional.";
49
+ };
50
+ readonly quality: {
51
+ readonly type: "number";
52
+ readonly description: "1 to 100, for .jpg and .webp. Optional.";
53
+ };
54
+ readonly sizes: {
55
+ readonly type: "string";
56
+ readonly description: "For .ico and .icns: sizes to hold, e.g. \"16,32,48,256\".";
57
+ };
58
+ };
59
+ readonly required: readonly ["image"];
60
+ };
61
+ export type ImageFit = "inside" | "cover" | "pad" | "stretch";
62
+ export interface TransformPlan {
63
+ /** The part of the source that is drawn. */
64
+ sx: number;
65
+ sy: number;
66
+ sw: number;
67
+ sh: number;
68
+ /** The size of the result. */
69
+ width: number;
70
+ height: number;
71
+ /** Where the source lands in it. */
72
+ dx: number;
73
+ dy: number;
74
+ dw: number;
75
+ dh: number;
76
+ }
77
+ /**
78
+ * Where a source of this size goes in a result of that one.
79
+ *
80
+ * Written to stand alone, with nothing declared outside it and no function
81
+ * inside it: the page that draws the image runs this same text.
82
+ */
83
+ export declare function planTransform(sourceWidth: number, sourceHeight: number, crop: {
84
+ x: number;
85
+ y: number;
86
+ width: number;
87
+ height: number;
88
+ } | null, width: number | null, height: number | null, fit: string): TransformPlan | null;
89
+ export interface TransformSpec {
90
+ crop?: RenderRegion;
91
+ width?: number;
92
+ height?: number;
93
+ fit: ImageFit;
94
+ /** Painted under the image, over the whole result. */
95
+ background?: string;
96
+ }
97
+ /** The page that draws one image at its new size. */
98
+ export declare function buildTransformDocument(sourceUrl: string, spec: TransformSpec): string;
99
+ /** One image, drawn at a new size by the host's browser. */
100
+ export declare function transformWithDriver(driver: RenderDriver, input: {
101
+ sourcePath: string;
102
+ baseDir: string;
103
+ spec: TransformSpec;
104
+ format?: "png" | "jpeg" | "webp";
105
+ quality?: number;
106
+ signal?: AbortSignal;
107
+ }): Promise<RenderResult>;
108
+ /** An `.ico`: a directory of images, each one a PNG. */
109
+ export declare function encodeIco(images: {
110
+ size: number;
111
+ png: Buffer;
112
+ }[]): Buffer;
113
+ /** An `.icns`: the same idea, with a name per size. */
114
+ export declare function encodeIcns(images: {
115
+ size: number;
116
+ png: Buffer;
117
+ }[]): Buffer;
118
+ export declare const ICO_SIZES: number[];
119
+ export declare const ICNS_SIZES: number[];
120
+ /** The sizes an icon file is asked to hold, or why not those. */
121
+ export declare function parseIconSizes(value: unknown, container: "ico" | "icns"): number[] | {
122
+ error: string;
123
+ };
124
+ /** Every size of an icon, from one source, as square PNGs. */
125
+ export declare function renderIconSizes(driver: RenderDriver, input: {
126
+ sourcePath: string;
127
+ baseDir: string;
128
+ sizes: number[];
129
+ crop?: RenderRegion;
130
+ background?: string;
131
+ signal?: AbortSignal;
132
+ }): Promise<{
133
+ size: number;
134
+ png: Buffer;
135
+ }[]>;
136
+ export declare class UnreadableImageError extends Error {
137
+ constructor();
138
+ }
139
+ export interface TransformImageToolOptions {
140
+ cwd: string;
141
+ createDriver: () => RenderDriver | Promise<RenderDriver>;
142
+ /** Whether the source is there: the browser says nothing useful about a missing file. */
143
+ fileExists: (absolutePath: string) => Promise<boolean>;
144
+ writeFile: (absolutePath: string, data: Buffer) => Promise<void>;
145
+ onError?: (message: string, error: unknown) => void;
146
+ }
147
+ /** Create the `transform_image` tool. */
148
+ export declare function createTransformImageTool(options: TransformImageToolOptions): AgentTool;