clanka 0.5.2 → 0.6.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.
Files changed (76) hide show
  1. package/dist/Acp.d.ts.map +1 -1
  2. package/dist/Acp.js +195 -16
  3. package/dist/Acp.js.map +1 -1
  4. package/dist/AcpImage.test.d.ts +2 -0
  5. package/dist/AcpImage.test.d.ts.map +1 -0
  6. package/dist/AcpImage.test.js +470 -0
  7. package/dist/AcpImage.test.js.map +1 -0
  8. package/dist/Agent.d.ts +9 -2
  9. package/dist/Agent.d.ts.map +1 -1
  10. package/dist/Agent.js +43 -6
  11. package/dist/Agent.js.map +1 -1
  12. package/dist/AgentExecutor.d.ts +27 -5
  13. package/dist/AgentExecutor.d.ts.map +1 -1
  14. package/dist/AgentExecutor.js +29 -4
  15. package/dist/AgentExecutor.js.map +1 -1
  16. package/dist/AgentExecutorImage.test.d.ts +2 -0
  17. package/dist/AgentExecutorImage.test.d.ts.map +1 -0
  18. package/dist/AgentExecutorImage.test.js +63 -0
  19. package/dist/AgentExecutorImage.test.js.map +1 -0
  20. package/dist/AgentImage.test.d.ts +2 -0
  21. package/dist/AgentImage.test.d.ts.map +1 -0
  22. package/dist/AgentImage.test.js +176 -0
  23. package/dist/AgentImage.test.js.map +1 -0
  24. package/dist/AgentTools.d.ts +25 -5
  25. package/dist/AgentTools.d.ts.map +1 -1
  26. package/dist/AgentTools.js +40 -4
  27. package/dist/AgentTools.js.map +1 -1
  28. package/dist/AgentToolsImage.test.d.ts +2 -0
  29. package/dist/AgentToolsImage.test.d.ts.map +1 -0
  30. package/dist/AgentToolsImage.test.js +158 -0
  31. package/dist/AgentToolsImage.test.js.map +1 -0
  32. package/dist/Codex.js +6 -1
  33. package/dist/Codex.js.map +1 -1
  34. package/dist/Compaction.d.ts.map +1 -1
  35. package/dist/Compaction.js +16 -1
  36. package/dist/Compaction.js.map +1 -1
  37. package/dist/CompactionImage.test.d.ts +2 -0
  38. package/dist/CompactionImage.test.d.ts.map +1 -0
  39. package/dist/CompactionImage.test.js +105 -0
  40. package/dist/CompactionImage.test.js.map +1 -0
  41. package/dist/Copilot.d.ts.map +1 -1
  42. package/dist/Copilot.js +5 -1
  43. package/dist/Copilot.js.map +1 -1
  44. package/dist/Image.d.ts +192 -0
  45. package/dist/Image.d.ts.map +1 -0
  46. package/dist/Image.js +586 -0
  47. package/dist/Image.js.map +1 -0
  48. package/dist/Image.test.d.ts +2 -0
  49. package/dist/Image.test.d.ts.map +1 -0
  50. package/dist/Image.test.js +142 -0
  51. package/dist/Image.test.js.map +1 -0
  52. package/dist/fixtures/TestImages.d.ts +73 -0
  53. package/dist/fixtures/TestImages.d.ts.map +1 -0
  54. package/dist/fixtures/TestImages.js +263 -0
  55. package/dist/fixtures/TestImages.js.map +1 -0
  56. package/dist/index.d.ts +4 -0
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +4 -0
  59. package/dist/index.js.map +1 -1
  60. package/package.json +2 -1
  61. package/src/Acp.ts +274 -21
  62. package/src/AcpImage.test.ts +676 -0
  63. package/src/Agent.ts +69 -7
  64. package/src/AgentExecutor.ts +51 -3
  65. package/src/AgentExecutorImage.test.ts +103 -0
  66. package/src/AgentImage.test.ts +295 -0
  67. package/src/AgentTools.ts +78 -7
  68. package/src/AgentToolsImage.test.ts +302 -0
  69. package/src/Codex.ts +6 -1
  70. package/src/Compaction.ts +16 -1
  71. package/src/CompactionImage.test.ts +142 -0
  72. package/src/Copilot.ts +5 -1
  73. package/src/Image.test.ts +220 -0
  74. package/src/Image.ts +704 -0
  75. package/src/fixtures/TestImages.ts +287 -0
  76. package/src/index.ts +5 -0
@@ -0,0 +1,142 @@
1
+ import * as Photon from "@silvia-odwyer/photon-node";
2
+ import { assert, describe, it } from "@effect/vitest";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Encoding from "effect/Encoding";
5
+ import * as Option from "effect/Option";
6
+ import { vi } from "vitest";
7
+ import * as Image from "./Image.js";
8
+ import { dimensions, encodePng, noisePixel, oversizedFrameHeaders, oversizedHeaders, supportedImages, tinyPng, } from "./fixtures/TestImages.js";
9
+ /** Optionally block decoding so crafted headers can never reach Photon. */
10
+ const withDecoderSpy = (f, blockDecoding = false) => Effect.suspend(() => {
11
+ const spy = vi.spyOn(Photon.PhotonImage, "new_from_byteslice");
12
+ if (blockDecoding) {
13
+ spy.mockImplementation(() => {
14
+ throw new Error("Header-only fixture must not reach the decoder");
15
+ });
16
+ }
17
+ return f(() => spy.mock.calls.length).pipe(Effect.ensuring(Effect.sync(() => spy.mockRestore())));
18
+ });
19
+ const base64Length = (bytes) => Encoding.encodeBase64(bytes).length;
20
+ describe("Image.prepare", () => {
21
+ it.effect("passes an in-limit image through unchanged", () => Effect.gen(function* () {
22
+ assert.strictEqual(Image.maxDimension, 2000);
23
+ assert.strictEqual(Image.maxBytes, 5 * 1024 * 1024);
24
+ const prepared = yield* Image.prepare({
25
+ data: tinyPng,
26
+ mediaType: "image/png",
27
+ });
28
+ assert.deepStrictEqual(prepared, {
29
+ data: tinyPng,
30
+ mediaType: "image/png",
31
+ });
32
+ }));
33
+ it.effect("resizes to the dimension cap while preserving aspect ratio", () => Effect.gen(function* () {
34
+ const prepared = yield* Image.prepare({
35
+ data: encodePng({ width: 2500, height: 100 }),
36
+ mediaType: "image/png",
37
+ });
38
+ assert.deepStrictEqual(dimensions(prepared.data), {
39
+ width: 2000,
40
+ height: 80,
41
+ });
42
+ assert.isAtMost(base64Length(prepared.data), Image.maxBytes);
43
+ }));
44
+ it.effect("re-encodes an image over the base64 byte cap", () => Effect.gen(function* () {
45
+ // Exercise the byte budget independently of the dimension cap, without a multi-MB fixture.
46
+ const data = encodePng({ width: 64, height: 64, pixel: noisePixel });
47
+ const limits = { maxDimension: 64, maxBytes: 2000 };
48
+ assert.isAbove(base64Length(data), limits.maxBytes);
49
+ const prepared = yield* Image.prepare({
50
+ data,
51
+ mediaType: "image/png",
52
+ limits,
53
+ });
54
+ assert.isAtMost(base64Length(prepared.data), limits.maxBytes);
55
+ const size = dimensions(prepared.data);
56
+ assert.isAtMost(size.width, limits.maxDimension);
57
+ assert.isAtMost(size.height, limits.maxDimension);
58
+ }));
59
+ it.effect("rejects an image that cannot fit even after resizing", () => Effect.gen(function* () {
60
+ const error = yield* Effect.flip(Image.prepare({
61
+ data: tinyPng,
62
+ mediaType: "image/png",
63
+ limits: { maxDimension: 2, maxBytes: 40 },
64
+ }));
65
+ assert.strictEqual(error._tag, "ImageError");
66
+ assert.strictEqual(error.reason, "TooLarge");
67
+ }));
68
+ it.effect("rejects undecodable bytes with a typed error", () => Effect.gen(function* () {
69
+ const error = yield* Effect.flip(Image.prepare({
70
+ data: new TextEncoder().encode("not a png"),
71
+ mediaType: "image/png",
72
+ }));
73
+ assert.strictEqual(error._tag, "ImageError");
74
+ assert.strictEqual(error.reason, "Decode");
75
+ }));
76
+ });
77
+ // =============================================================================
78
+ // Input budget: what may reach the decoder at all
79
+ //
80
+ // Two bounds sit in front of Photon on every path. `maxInputBytes` caps the
81
+ // encoded input (20 MiB, the same number the HTTP fetch already uses), and
82
+ // `maxInputPixels` caps the canvas declared in the image header, because a
83
+ // small, highly compressible file can expand to gigabytes of RGBA inside the
84
+ // decoder before `prepare` ever reads a width. Both checks run before any
85
+ // decoding; the fixtures below have no pixels, so a decoder call would fail.
86
+ // =============================================================================
87
+ describe("Image input budget", () => {
88
+ it("pins the shared ceilings", () => {
89
+ assert.strictEqual(Image.maxInputBytes, 20 * 1024 * 1024);
90
+ assert.strictEqual(Image.maxInputPixels, 50_000_000);
91
+ });
92
+ it.effect("reads dimensions from the header without decoding", () => withDecoderSpy((decoderCalls) => Effect.sync(() => {
93
+ for (const image of supportedImages) {
94
+ assert.deepStrictEqual(Option.getOrThrow(Image.dimensions(image.data)), dimensions(image.data), image.mediaType);
95
+ }
96
+ // `dimensions` above is the Photon-backed fixture helper; reset.
97
+ const baseline = decoderCalls();
98
+ for (const header of oversizedHeaders) {
99
+ assert.deepStrictEqual(Image.dimensions(header.data), Option.some({ width: header.width, height: header.height }), header.mediaType);
100
+ }
101
+ assert.deepStrictEqual(Image.dimensions(new TextEncoder().encode("not an image")), Option.none());
102
+ assert.strictEqual(decoderCalls(), baseline);
103
+ })));
104
+ it.effect("rejects an oversized canvas in every format before decoding", () => withDecoderSpy((decoderCalls) => Effect.gen(function* () {
105
+ const headers = [...oversizedHeaders, ...oversizedFrameHeaders];
106
+ const results = [];
107
+ for (const header of headers) {
108
+ assert.isAbove(header.width * header.height, Image.maxInputPixels);
109
+ const baseline = decoderCalls();
110
+ const error = yield* Effect.flip(Image.prepare({ data: header.data, mediaType: header.mediaType }));
111
+ results.push({
112
+ mediaType: header.mediaType,
113
+ tag: error._tag,
114
+ reason: error.reason,
115
+ decoderCalls: decoderCalls() - baseline,
116
+ });
117
+ }
118
+ assert.deepStrictEqual(results, headers.map((header) => ({
119
+ mediaType: header.mediaType,
120
+ tag: "ImageError",
121
+ reason: "TooLarge",
122
+ decoderCalls: 0,
123
+ })));
124
+ }), true));
125
+ it.effect("rejects input over the byte ceiling before decoding", () => withDecoderSpy((decoderCalls) => Effect.gen(function* () {
126
+ // A real PNG header followed by padding: over the ceiling by one byte.
127
+ const data = new Uint8Array(20 * 1024 * 1024 + 1);
128
+ data.set(tinyPng);
129
+ const error = yield* Effect.flip(Image.prepare({ data, mediaType: "image/png" }));
130
+ assert.strictEqual(error._tag, "ImageError");
131
+ assert.strictEqual(error.reason, "TooLarge");
132
+ assert.strictEqual(decoderCalls(), 0, "the decoder must not run");
133
+ })));
134
+ it.effect("does not send undecodable bytes to the decoder", () => withDecoderSpy((decoderCalls) => Effect.gen(function* () {
135
+ yield* Effect.flip(Image.prepare({
136
+ data: new TextEncoder().encode("not a png"),
137
+ mediaType: "image/png",
138
+ }));
139
+ assert.strictEqual(decoderCalls(), 0);
140
+ })));
141
+ });
142
+ //# sourceMappingURL=Image.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Image.test.js","sourceRoot":"","sources":["../src/Image.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ export declare const encodePng: (options: {
2
+ readonly width: number;
3
+ readonly height: number;
4
+ readonly pixel?: (x: number, y: number) => readonly [number, number, number];
5
+ }) => Uint8Array;
6
+ export declare const noisePixel: (x: number, y: number) => readonly [number, number, number];
7
+ export declare const tinyPng: Uint8Array<ArrayBufferLike>;
8
+ export declare const tinyJpeg: Uint8Array<ArrayBufferLike>;
9
+ export declare const tinyWebp: Uint8Array<ArrayBufferLike>;
10
+ /** Two 4x2 frames (red, then blue), each displayed for 100ms, looping forever. */
11
+ export declare const animatedGif: Uint8Array<ArrayBuffer>;
12
+ export declare const supportedImages: readonly [{
13
+ readonly fileName: "shot.png";
14
+ readonly mediaType: "image/png";
15
+ readonly data: Uint8Array<ArrayBufferLike>;
16
+ }, {
17
+ readonly fileName: "photo.jpeg";
18
+ readonly mediaType: "image/jpeg";
19
+ readonly data: Uint8Array<ArrayBufferLike>;
20
+ }, {
21
+ readonly fileName: "animated.gif";
22
+ readonly mediaType: "image/gif";
23
+ readonly data: Uint8Array<ArrayBuffer>;
24
+ }, {
25
+ readonly fileName: "picture.webp";
26
+ readonly mediaType: "image/webp";
27
+ readonly data: Uint8Array<ArrayBufferLike>;
28
+ }];
29
+ /**
30
+ * Header-only fixtures that declare canvases far over any sane pixel budget.
31
+ * They carry no pixel data, so nothing can decode them: a test that passes
32
+ * one to the decoder is a test that would decode a bomb.
33
+ */
34
+ export declare const oversizedHeaders: readonly [{
35
+ readonly mediaType: "image/png";
36
+ readonly width: 16384;
37
+ readonly height: 16384;
38
+ readonly data: Uint8Array<ArrayBuffer>;
39
+ }, {
40
+ readonly mediaType: "image/jpeg";
41
+ readonly width: 65535;
42
+ readonly height: 65535;
43
+ readonly data: Uint8Array<ArrayBuffer>;
44
+ }, {
45
+ readonly mediaType: "image/gif";
46
+ readonly width: 65535;
47
+ readonly height: 65535;
48
+ readonly data: Uint8Array<ArrayBuffer>;
49
+ }, {
50
+ readonly mediaType: "image/webp";
51
+ readonly width: 16384;
52
+ readonly height: 16384;
53
+ readonly data: Uint8Array<ArrayBuffer>;
54
+ }];
55
+ /** Small container canvases hiding 8000x8000 frames, with no pixel payload. */
56
+ export declare const oversizedFrameHeaders: readonly [{
57
+ readonly mediaType: "image/webp";
58
+ readonly width: 8000;
59
+ readonly height: 8000;
60
+ readonly data: Uint8Array<ArrayBuffer>;
61
+ }, {
62
+ readonly mediaType: "image/gif";
63
+ readonly width: 8000;
64
+ readonly height: 8000;
65
+ readonly data: Uint8Array<ArrayBuffer>;
66
+ }];
67
+ export declare const dimensions: (bytes: Uint8Array) => {
68
+ width: number;
69
+ height: number;
70
+ };
71
+ export declare const bytesOf: (data: string | Uint8Array | URL) => Uint8Array;
72
+ export declare const equalBytes: (a: Uint8Array, b: Uint8Array) => boolean;
73
+ //# sourceMappingURL=TestImages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestImages.d.ts","sourceRoot":"","sources":["../../src/fixtures/TestImages.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,SAAS,YAAa;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7E,KAAG,UAiBH,CAAA;AAED,eAAO,MAAM,UAAU,MAClB,MAAM,KACN,MAAM,KACR,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAKlC,CAAA;AAED,eAAO,MAAM,OAAO,6BAAqC,CAAA;AAYzD,eAAO,MAAM,QAAQ,6BAAe,CAAA;AACpC,eAAO,MAAM,QAAQ,6BAAe,CAAA;AAEpC,kFAAkF;AAClF,eAAO,MAAM,WAAW,yBAWtB,CAAA;AAEF,eAAO,MAAM,eAAe;aAExB,QAAQ,EAAE,UAAU;aACpB,SAAS,EAAE,WAAW;aACtB,IAAI;;aAGJ,QAAQ,EAAE,YAAY;aACtB,SAAS,EAAE,YAAY;aACvB,IAAI;;aAGJ,QAAQ,EAAE,cAAc;aACxB,SAAS,EAAE,WAAW;aACtB,IAAI;;aAGJ,QAAQ,EAAE,cAAc;aACxB,SAAS,EAAE,YAAY;aACvB,IAAI;EAEE,CAAA;AA6GV;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;aAEzB,SAAS,EAAE,WAAW;aACtB,KAAK,EAAE,KAAK;aACZ,MAAM,EAAE,KAAK;aACb,IAAI;;aAGJ,SAAS,EAAE,YAAY;aACvB,KAAK,EAAE,KAAK;aACZ,MAAM,EAAE,KAAK;aACb,IAAI;;aAGJ,SAAS,EAAE,WAAW;aACtB,KAAK,EAAE,KAAK;aACZ,MAAM,EAAE,KAAK;aACb,IAAI;;aAGJ,SAAS,EAAE,YAAY;aACvB,KAAK,EAAE,KAAK;aACZ,MAAM,EAAE,KAAK;aACb,IAAI;EAEE,CAAA;AAEV,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB;aAE9B,SAAS,EAAE,YAAY;aACvB,KAAK,EAAE,IAAI;aACX,MAAM,EAAE,IAAI;aACZ,IAAI;;aAaJ,SAAS,EAAE,WAAW;aACtB,KAAK,EAAE,IAAI;aACX,MAAM,EAAE,IAAI;aACZ,IAAI;EAaE,CAAA;AAEV,eAAO,MAAM,UAAU,UAAW,UAAU;;;CAO3C,CAAA;AAED,eAAO,MAAM,OAAO,SAAU,MAAM,GAAG,UAAU,GAAG,GAAG,KAAG,UASzD,CAAA;AAED,eAAO,MAAM,UAAU,MAAO,UAAU,KAAK,UAAU,KAAG,OACI,CAAA"}
@@ -0,0 +1,263 @@
1
+ import * as Photon from "@silvia-odwyer/photon-node";
2
+ import * as Zlib from "node:zlib";
3
+ import * as Encoding from "effect/Encoding";
4
+ export const encodePng = (options) => {
5
+ const { width, height } = options;
6
+ const pixels = new Uint8Array(width * height * 4);
7
+ for (let y = 0; y < height; y++) {
8
+ for (let x = 0; x < width; x++) {
9
+ pixels.set([...(options.pixel?.(x, y) ?? [200, 30, 30]), 255], (y * width + x) * 4);
10
+ }
11
+ }
12
+ const image = new Photon.PhotonImage(pixels, width, height);
13
+ try {
14
+ return image.get_bytes();
15
+ }
16
+ finally {
17
+ image.free();
18
+ }
19
+ };
20
+ export const noisePixel = (x, y) => {
21
+ let h = (x * 374761393 + y * 668265263) | 0;
22
+ h = Math.imul(h ^ (h >>> 13), 1274126177);
23
+ h ^= h >>> 16;
24
+ return [h & 0xff, (h >>> 8) & 0xff, (h >>> 16) & 0xff];
25
+ };
26
+ export const tinyPng = encodePng({ width: 4, height: 3 });
27
+ const encodeOtherFormats = () => {
28
+ const image = Photon.PhotonImage.new_from_byteslice(tinyPng);
29
+ try {
30
+ return { jpeg: image.get_bytes_jpeg(85), webp: image.get_bytes_webp() };
31
+ }
32
+ finally {
33
+ image.free();
34
+ }
35
+ };
36
+ const encoded = encodeOtherFormats();
37
+ export const tinyJpeg = encoded.jpeg;
38
+ export const tinyWebp = encoded.webp;
39
+ /** Two 4x2 frames (red, then blue), each displayed for 100ms, looping forever. */
40
+ export const animatedGif = new Uint8Array([
41
+ // GIF89a, logical screen, and a two-colour global palette.
42
+ 71, 73, 70, 56, 57, 97, 4, 0, 2, 0, 128, 0, 0, 255, 0, 0, 0, 0, 255,
43
+ // NETSCAPE2.0 loop extension.
44
+ 33, 255, 11, 78, 69, 84, 83, 67, 65, 80, 69, 50, 46, 48, 3, 1, 0, 0, 0,
45
+ // Frame 1: graphics control, image descriptor, and LZW pixels.
46
+ 33, 249, 4, 0, 10, 0, 0, 0, 44, 0, 0, 0, 0, 4, 0, 2, 0, 0, 2, 7, 4, 65, 16, 4,
47
+ 65, 16, 5, 0,
48
+ // Frame 2 uses the blue palette entry.
49
+ 33, 249, 4, 0, 10, 0, 0, 0, 44, 0, 0, 0, 0, 4, 0, 2, 0, 0, 2, 7, 12, 195, 48,
50
+ 12, 195, 48, 5, 0, 59,
51
+ ]);
52
+ export const supportedImages = [
53
+ {
54
+ fileName: "shot.png",
55
+ mediaType: "image/png",
56
+ data: tinyPng,
57
+ },
58
+ {
59
+ fileName: "photo.jpeg",
60
+ mediaType: "image/jpeg",
61
+ data: tinyJpeg,
62
+ },
63
+ {
64
+ fileName: "animated.gif",
65
+ mediaType: "image/gif",
66
+ data: animatedGif,
67
+ },
68
+ {
69
+ fileName: "picture.webp",
70
+ mediaType: "image/webp",
71
+ data: tinyWebp,
72
+ },
73
+ ];
74
+ const ascii = (text) => Array.from(text, (c) => c.charCodeAt(0));
75
+ const u16be = (n) => [(n >>> 8) & 0xff, n & 0xff];
76
+ const u16le = (n) => [n & 0xff, (n >>> 8) & 0xff];
77
+ const u24le = (n) => [n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff];
78
+ const u32be = (n) => [
79
+ (n >>> 24) & 0xff,
80
+ (n >>> 16) & 0xff,
81
+ (n >>> 8) & 0xff,
82
+ n & 0xff,
83
+ ];
84
+ const u32le = (n) => [
85
+ n & 0xff,
86
+ (n >>> 8) & 0xff,
87
+ (n >>> 16) & 0xff,
88
+ (n >>> 24) & 0xff,
89
+ ];
90
+ const pngHeader = (width, height) => {
91
+ const ihdr = [
92
+ ...ascii("IHDR"),
93
+ ...u32be(width),
94
+ ...u32be(height),
95
+ 8,
96
+ 6,
97
+ 0,
98
+ 0,
99
+ 0,
100
+ ];
101
+ return new Uint8Array([
102
+ 0x89,
103
+ 0x50,
104
+ 0x4e,
105
+ 0x47,
106
+ 0x0d,
107
+ 0x0a,
108
+ 0x1a,
109
+ 0x0a,
110
+ ...u32be(13),
111
+ ...ihdr,
112
+ ...u32be(Zlib.crc32(new Uint8Array(ihdr))),
113
+ ]);
114
+ };
115
+ const jpegHeader = (width, height) => new Uint8Array([
116
+ 0xff,
117
+ 0xd8,
118
+ // APP0 / JFIF, as emitted by most encoders, so the parser must skip it.
119
+ 0xff,
120
+ 0xe0,
121
+ ...u16be(16),
122
+ ...ascii("JFIF"),
123
+ 0,
124
+ 1,
125
+ 2,
126
+ 0,
127
+ 0,
128
+ 1,
129
+ 0,
130
+ 1,
131
+ 0,
132
+ 0,
133
+ // SOF0: length 17, 8-bit precision, height, width, 3 components.
134
+ 0xff,
135
+ 0xc0,
136
+ ...u16be(17),
137
+ 8,
138
+ ...u16be(height),
139
+ ...u16be(width),
140
+ 3,
141
+ 1,
142
+ 0x22,
143
+ 0,
144
+ 2,
145
+ 0x11,
146
+ 1,
147
+ 3,
148
+ 0x11,
149
+ 1,
150
+ ]);
151
+ const gifHeader = (width, height) => new Uint8Array([
152
+ ...ascii("GIF89a"),
153
+ ...u16le(width),
154
+ ...u16le(height),
155
+ 0,
156
+ 0,
157
+ 0,
158
+ ]);
159
+ /** Extended (VP8X) container, the only WebP form that carries a canvas size. */
160
+ const webpHeader = (width, height) => new Uint8Array([
161
+ ...ascii("RIFF"),
162
+ ...u32le(22),
163
+ ...ascii("WEBP"),
164
+ ...ascii("VP8X"),
165
+ ...u32le(10),
166
+ 0,
167
+ 0,
168
+ 0,
169
+ 0,
170
+ ...u24le(width - 1),
171
+ ...u24le(height - 1),
172
+ ]);
173
+ /**
174
+ * Header-only fixtures that declare canvases far over any sane pixel budget.
175
+ * They carry no pixel data, so nothing can decode them: a test that passes
176
+ * one to the decoder is a test that would decode a bomb.
177
+ */
178
+ export const oversizedHeaders = [
179
+ {
180
+ mediaType: "image/png",
181
+ width: 16384,
182
+ height: 16384,
183
+ data: pngHeader(16384, 16384),
184
+ },
185
+ {
186
+ mediaType: "image/jpeg",
187
+ width: 65535,
188
+ height: 65535,
189
+ data: jpegHeader(65535, 65535),
190
+ },
191
+ {
192
+ mediaType: "image/gif",
193
+ width: 65535,
194
+ height: 65535,
195
+ data: gifHeader(65535, 65535),
196
+ },
197
+ {
198
+ mediaType: "image/webp",
199
+ width: 16384,
200
+ height: 16384,
201
+ data: webpHeader(16384, 16384),
202
+ },
203
+ ];
204
+ /** Small container canvases hiding 8000x8000 frames, with no pixel payload. */
205
+ export const oversizedFrameHeaders = [
206
+ {
207
+ mediaType: "image/webp",
208
+ width: 8000,
209
+ height: 8000,
210
+ data: new Uint8Array([
211
+ ...ascii("RIFF"),
212
+ ...u32le(36),
213
+ ...webpHeader(1, 1).subarray(8),
214
+ ...ascii("VP8L"),
215
+ ...u32le(5),
216
+ 0x2f,
217
+ // VP8L packs width-1 and height-1 into 14 bits each.
218
+ ...u32le(7999 | (7999 << 14)),
219
+ 0, // RIFF chunk padding, not pixel data.
220
+ ]),
221
+ },
222
+ {
223
+ mediaType: "image/gif",
224
+ width: 8000,
225
+ height: 8000,
226
+ data: new Uint8Array([
227
+ ...gifHeader(1, 1),
228
+ 0x2c, // Image descriptor.
229
+ ...u16le(0),
230
+ ...u16le(0),
231
+ ...u16le(8000),
232
+ ...u16le(8000),
233
+ 0, // No local colour table.
234
+ 2,
235
+ 0, // LZW minimum code size and empty data sub-block.
236
+ 0x3b, // Trailer.
237
+ ]),
238
+ },
239
+ ];
240
+ export const dimensions = (bytes) => {
241
+ const image = Photon.PhotonImage.new_from_byteslice(bytes);
242
+ try {
243
+ return { width: image.get_width(), height: image.get_height() };
244
+ }
245
+ finally {
246
+ image.free();
247
+ }
248
+ };
249
+ export const bytesOf = (data) => {
250
+ if (data instanceof Uint8Array)
251
+ return data;
252
+ if (data instanceof URL)
253
+ throw new Error(`Expected inline data, got ${data}`);
254
+ const base64 = data.startsWith("data:")
255
+ ? data.slice(data.indexOf(",") + 1)
256
+ : data;
257
+ const decoded = Encoding.decodeBase64(base64);
258
+ if (decoded._tag === "Failure")
259
+ throw new Error("Invalid base64 image data");
260
+ return decoded.success;
261
+ };
262
+ export const equalBytes = (a, b) => a.length === b.length && a.every((byte, i) => byte === b[i]);
263
+ //# sourceMappingURL=TestImages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TestImages.js","sourceRoot":"","sources":["../../src/fixtures/TestImages.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -31,6 +31,10 @@ export * as CodeChunker from "./CodeChunker.ts";
31
31
  * @since 1.0.0
32
32
  */
33
33
  export * as Compaction from "./Compaction.ts";
34
+ /**
35
+ * @since 1.0.0
36
+ */
37
+ export * as Image from "./Image.ts";
34
38
  /**
35
39
  * @since 1.0.0
36
40
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAE/B;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAE3D;;GAEG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AAEvD;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AAEvD;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAE/B;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAE3D;;GAEG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AAEvD;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AAEvD;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA"}
package/dist/index.js CHANGED
@@ -31,6 +31,10 @@ export * as CodeChunker from "./CodeChunker.js";
31
31
  * @since 1.0.0
32
32
  */
33
33
  export * as Compaction from "./Compaction.js";
34
+ /**
35
+ * @since 1.0.0
36
+ */
37
+ export * as Image from "./Image.js";
34
38
  /**
35
39
  * @since 1.0.0
36
40
  */
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAE/B;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAE3D;;GAEG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AAEvD;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AAEvD;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAE/B;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA;AAE/C;;GAEG;AACH,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAE7C;;GAEG;AACH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAEnC;;GAEG;AACH,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC;;GAEG;AACH,OAAO,KAAK,iBAAiB,MAAM,wBAAwB,CAAA;AAE3D;;GAEG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AAEvD;;GAEG;AACH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAA;AAErD;;GAEG;AACH,OAAO,KAAK,eAAe,MAAM,sBAAsB,CAAA;AAEvD;;GAEG;AACH,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "clanka",
3
3
  "type": "module",
4
- "version": "0.5.2",
4
+ "version": "0.6.0",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -26,6 +26,7 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@modelcontextprotocol/sdk": "^1.30.0",
29
+ "@silvia-odwyer/photon-node": "^0.3.4",
29
30
  "@vscode/ripgrep": "^1.18.0",
30
31
  "chalk": "^6.0.0",
31
32
  "glob": "^13.0.6",