@cyanheads/pixoo-mcp-server 1.1.4 → 1.2.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/AGENTS.md +6 -2
- package/CLAUDE.md +6 -2
- package/README.md +14 -13
- package/changelog/1.2.x/1.2.0.md +28 -0
- package/dist/mcp-server/resources/definitions/pixoo-design-guide.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/pixoo-design-guide.resource.js +1 -0
- package/dist/mcp-server/resources/definitions/pixoo-design-guide.resource.js.map +1 -1
- package/dist/mcp-server/tools/definitions/pixoo-compose-scene.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/pixoo-compose-scene.tool.js +25 -41
- package/dist/mcp-server/tools/definitions/pixoo-compose-scene.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/pixoo-design-brief.tool.d.ts +3 -3
- package/dist/mcp-server/tools/definitions/pixoo-design-brief.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/pixoo-design-brief.tool.js +56 -44
- package/dist/mcp-server/tools/definitions/pixoo-design-brief.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/pixoo-display-text.tool.d.ts +1 -0
- package/dist/mcp-server/tools/definitions/pixoo-display-text.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/pixoo-display-text.tool.js +121 -32
- package/dist/mcp-server/tools/definitions/pixoo-display-text.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/pixoo-overlay-text.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/pixoo-overlay-text.tool.js +17 -3
- package/dist/mcp-server/tools/definitions/pixoo-overlay-text.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/pixoo-push-image.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/pixoo-push-image.tool.js +9 -8
- package/dist/mcp-server/tools/definitions/pixoo-push-image.tool.js.map +1 -1
- package/dist/mcp-server/tools/device-push.d.ts +24 -0
- package/dist/mcp-server/tools/device-push.d.ts.map +1 -0
- package/dist/mcp-server/tools/device-push.js +50 -0
- package/dist/mcp-server/tools/device-push.js.map +1 -0
- package/dist/renderer/preview.d.ts +17 -19
- package/dist/renderer/preview.d.ts.map +1 -1
- package/dist/renderer/preview.js +55 -34
- package/dist/renderer/preview.js.map +1 -1
- package/dist/renderer/remote-image.d.ts +6 -2
- package/dist/renderer/remote-image.d.ts.map +1 -1
- package/dist/renderer/remote-image.js +9 -1
- package/dist/renderer/remote-image.js.map +1 -1
- package/dist/renderer/scene-renderer.d.ts +14 -9
- package/dist/renderer/scene-renderer.d.ts.map +1 -1
- package/dist/renderer/scene-renderer.js +29 -31
- package/dist/renderer/scene-renderer.js.map +1 -1
- package/dist/renderer/text-engine.d.ts +14 -1
- package/dist/renderer/text-engine.d.ts.map +1 -1
- package/dist/renderer/text-engine.js +22 -4
- package/dist/renderer/text-engine.js.map +1 -1
- package/dist/services/pixoo/pixoo-service.js +1 -1
- package/dist/services/pixoo/pixoo-service.js.map +1 -1
- package/package.json +1 -1
- package/server.json +3 -3
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
6
|
import { JsonRpcErrorCode, validationError } from '@cyanheads/mcp-ts-core/errors';
|
|
7
7
|
import { resolveColor } from '@cyanheads/pixoo-toolkit';
|
|
8
|
+
import { getServerConfig } from '../../../config/server-config.js';
|
|
8
9
|
import { classifyDeviceFailure, getPixooService } from '../../../services/pixoo/pixoo-service.js';
|
|
9
10
|
export const pixooOverlayText = tool('pixoo_overlay_text', {
|
|
10
11
|
title: 'pixoo_overlay_text',
|
|
@@ -25,14 +26,14 @@ export const pixooOverlayText = tool('pixoo_overlay_text', {
|
|
|
25
26
|
.min(0)
|
|
26
27
|
.max(64)
|
|
27
28
|
.default(0)
|
|
28
|
-
.describe('X start position on display
|
|
29
|
+
.describe('X start position, 0 to display size − 1 (63 on a 64px display; default: 0).'),
|
|
29
30
|
y: z
|
|
30
31
|
.number()
|
|
31
32
|
.int()
|
|
32
33
|
.min(0)
|
|
33
34
|
.max(64)
|
|
34
35
|
.default(0)
|
|
35
|
-
.describe('Y start position on display
|
|
36
|
+
.describe('Y start position, 0 to display size − 1 (63 on a 64px display; default: 0).'),
|
|
36
37
|
font: z
|
|
37
38
|
.number()
|
|
38
39
|
.int()
|
|
@@ -64,7 +65,7 @@ export const pixooOverlayText = tool('pixoo_overlay_text', {
|
|
|
64
65
|
.int()
|
|
65
66
|
.min(0)
|
|
66
67
|
.optional()
|
|
67
|
-
.describe('Text region width in pixels (
|
|
68
|
+
.describe('Text region width in pixels, 0 to display size (64 on a 64px display; defaults to display width).'),
|
|
68
69
|
}),
|
|
69
70
|
output: z.object({
|
|
70
71
|
acknowledged: z
|
|
@@ -130,6 +131,19 @@ export const pixooOverlayText = tool('pixoo_overlay_text', {
|
|
|
130
131
|
if (!input.text) {
|
|
131
132
|
throw validationError('text is required when mode is "set".');
|
|
132
133
|
}
|
|
134
|
+
// The schema's ceiling is fixed at import; the configured display sets the real edge.
|
|
135
|
+
const size = getServerConfig().pixooSize;
|
|
136
|
+
for (const [axis, value] of [
|
|
137
|
+
['x', input.x],
|
|
138
|
+
['y', input.y],
|
|
139
|
+
]) {
|
|
140
|
+
if (value >= size) {
|
|
141
|
+
throw validationError(`${axis} must be 0–${size - 1} on a ${size}px display (PIXOO_SIZE=${size}); received ${value}.`, { [axis]: value, max: size - 1 });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (input.width !== undefined && input.width > size) {
|
|
145
|
+
throw validationError(`width must be 0–${size} on a ${size}px display (PIXOO_SIZE=${size}); received ${input.width}.`, { width: input.width, max: size });
|
|
146
|
+
}
|
|
133
147
|
ctx.log.info('Setting text overlay', { id: input.id, textLength: input.text.length });
|
|
134
148
|
let color;
|
|
135
149
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pixoo-overlay-text.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/pixoo-overlay-text.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAE3F,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC,oBAAoB,EAAE;IACzD,KAAK,EAAE,oBAAoB;IAC3B,WAAW,EACT,ubAAub;IACzb,WAAW,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE;IAE7D,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;QACvF,EAAE,EAAE,CAAC;aACF,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,EAAE,CAAC;aACP,QAAQ,CAAC,kEAAkE,CAAC;QAC/E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;QAChF,CAAC,EAAE,CAAC;aACD,MAAM,EAAE;aACR,GAAG,EAAE;aACL,GAAG,CAAC,CAAC,CAAC;aACN,GAAG,CAAC,EAAE,CAAC;aACP,OAAO,CAAC,CAAC,CAAC;aACV,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"pixoo-overlay-text.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/pixoo-overlay-text.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pixoo-push-image.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/pixoo-push-image.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"pixoo-push-image.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/pixoo-push-image.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAajE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwLzB,CAAC"}
|
|
@@ -7,7 +7,8 @@ import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
|
7
7
|
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
8
8
|
import { loadImage } from '@cyanheads/pixoo-toolkit';
|
|
9
9
|
import { getServerConfig } from '../../../config/server-config.js';
|
|
10
|
-
import {
|
|
10
|
+
import { pushKeepingPreview, visibilityNotice } from '../device-push.js';
|
|
11
|
+
import { autoSavePreview, encodePreviewBlock, savePngPreview, } from '../../../renderer/preview.js';
|
|
11
12
|
import { fetchRemoteImageToTempPng, isRemoteSource } from '../../../renderer/remote-image.js';
|
|
12
13
|
import { getPixooService } from '../../../services/pixoo/pixoo-service.js';
|
|
13
14
|
export const pixooPushImage = tool('pixoo_push_image', {
|
|
@@ -130,18 +131,18 @@ export const pixooPushImage = tool('pixoo_push_image', {
|
|
|
130
131
|
// absent from `output` — routing it through ctx.content carries the base64 once
|
|
131
132
|
// instead of duplicating it into structuredContent.
|
|
132
133
|
ctx.content.image(encodePreviewBlock(canvas).data, 'image/png');
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
const
|
|
136
|
-
if (savedPath)
|
|
137
|
-
outputFiles.push(savedPath);
|
|
138
|
-
// Push
|
|
134
|
+
const baseName = `push-image-${Date.now()}`;
|
|
135
|
+
const writePreview = (dir) => savePngPreview(canvas, dir, baseName);
|
|
136
|
+
const outputFiles = await autoSavePreview(writePreview);
|
|
139
137
|
let pushed = false;
|
|
140
138
|
let deviceState;
|
|
141
139
|
if (input.push) {
|
|
142
140
|
const svc = getPixooService();
|
|
143
|
-
deviceState = await svc.pushFrame(canvas, ctx);
|
|
141
|
+
deviceState = await pushKeepingPreview(() => svc.pushFrame(canvas, ctx), outputFiles, writePreview);
|
|
144
142
|
pushed = true;
|
|
143
|
+
const notice = visibilityNotice(deviceState);
|
|
144
|
+
if (notice)
|
|
145
|
+
ctx.enrich.notice(notice);
|
|
145
146
|
}
|
|
146
147
|
return {
|
|
147
148
|
pushed,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pixoo-push-image.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/pixoo-push-image.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,SAAS,EAAkB,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"pixoo-push-image.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/pixoo-push-image.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The post-render push path shared by the three push tools: keep the
|
|
3
|
+
* rendered preview when a push fails, and flag a successful push the panel won't show.
|
|
4
|
+
* @module mcp-server/tools/device-push
|
|
5
|
+
*/
|
|
6
|
+
import { type PreviewWriter } from '../../renderer/preview.js';
|
|
7
|
+
import type { DeviceStateSnapshot } from '../../services/pixoo/pixoo-service.js';
|
|
8
|
+
/** Brightness at or below this reads as dark on the panel. */
|
|
9
|
+
export declare const DIM_BRIGHTNESS = 10;
|
|
10
|
+
/**
|
|
11
|
+
* Run a device push. A failed push rethrows its typed error — code, `reason`,
|
|
12
|
+
* `retryable`, and recovery hint untouched — with the preview's path added as
|
|
13
|
+
* `data.outputFiles` and named in the message: the files this call already saved, or
|
|
14
|
+
* a copy written under the OS temp dir when it saved none. Error results carry no
|
|
15
|
+
* `ctx.content` blocks, so the file is how the render outlives the failure.
|
|
16
|
+
*/
|
|
17
|
+
export declare function pushKeepingPreview(push: () => Promise<DeviceStateSnapshot>, savedFiles: string[], writePreview: PreviewWriter): Promise<DeviceStateSnapshot>;
|
|
18
|
+
/**
|
|
19
|
+
* Name every reason a pushed render may not show on the panel, each with the call
|
|
20
|
+
* that fixes it. Undefined when the device reads as visible, or when the read-back
|
|
21
|
+
* never reached it and there is nothing to judge.
|
|
22
|
+
*/
|
|
23
|
+
export declare function visibilityNotice(state: DeviceStateSnapshot): string | undefined;
|
|
24
|
+
//# sourceMappingURL=device-push.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-push.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/tools/device-push.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,aAAa,EAAmB,MAAM,uBAAuB,CAAC;AAC5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAE7E,8DAA8D;AAC9D,eAAO,MAAM,cAAc,KAAK,CAAC;AAEjC;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,EACxC,UAAU,EAAE,MAAM,EAAE,EACpB,YAAY,EAAE,aAAa,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAa9B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,GAAG,SAAS,CAgB/E"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview The post-render push path shared by the three push tools: keep the
|
|
3
|
+
* rendered preview when a push fails, and flag a successful push the panel won't show.
|
|
4
|
+
* @module mcp-server/tools/device-push
|
|
5
|
+
*/
|
|
6
|
+
import { McpError } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { saveTempPreview } from '../../renderer/preview.js';
|
|
8
|
+
/** Brightness at or below this reads as dark on the panel. */
|
|
9
|
+
export const DIM_BRIGHTNESS = 10;
|
|
10
|
+
/**
|
|
11
|
+
* Run a device push. A failed push rethrows its typed error — code, `reason`,
|
|
12
|
+
* `retryable`, and recovery hint untouched — with the preview's path added as
|
|
13
|
+
* `data.outputFiles` and named in the message: the files this call already saved, or
|
|
14
|
+
* a copy written under the OS temp dir when it saved none. Error results carry no
|
|
15
|
+
* `ctx.content` blocks, so the file is how the render outlives the failure.
|
|
16
|
+
*/
|
|
17
|
+
export async function pushKeepingPreview(push, savedFiles, writePreview) {
|
|
18
|
+
try {
|
|
19
|
+
return await push();
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
if (!(err instanceof McpError))
|
|
23
|
+
throw err;
|
|
24
|
+
const outputFiles = savedFiles.length > 0 ? savedFiles : [await saveTempPreview(writePreview)];
|
|
25
|
+
throw new McpError(err.code, `${err.message.replace(/[^.!?]$/, '$&.')} Rendered preview saved to ${outputFiles.join(', ')}.`, { ...err.data, outputFiles }, { cause: err });
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Name every reason a pushed render may not show on the panel, each with the call
|
|
30
|
+
* that fixes it. Undefined when the device reads as visible, or when the read-back
|
|
31
|
+
* never reached it and there is nothing to judge.
|
|
32
|
+
*/
|
|
33
|
+
export function visibilityNotice(state) {
|
|
34
|
+
if (!state.reachable)
|
|
35
|
+
return;
|
|
36
|
+
const problems = [];
|
|
37
|
+
if (state.screenOn === false) {
|
|
38
|
+
problems.push('the screen is off (pixoo_control_device with screen: "on")');
|
|
39
|
+
}
|
|
40
|
+
if (state.brightness !== undefined && state.brightness <= DIM_BRIGHTNESS) {
|
|
41
|
+
problems.push(`brightness is ${state.brightness} (pixoo_control_device with brightness: 80)`);
|
|
42
|
+
}
|
|
43
|
+
if (state.channel !== undefined && state.channel !== 'custom') {
|
|
44
|
+
problems.push(`the device is on the ${state.channel} channel (pixoo_control_device with channel: "custom")`);
|
|
45
|
+
}
|
|
46
|
+
if (problems.length === 0)
|
|
47
|
+
return;
|
|
48
|
+
return `Pushed, but the render may not be visible: ${problems.join('; ')}.`;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=device-push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-push.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/device-push.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAsB,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG5E,8DAA8D;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AAEjC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAwC,EACxC,UAAoB,EACpB,YAA2B;IAE3B,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,CAAC,GAAG,YAAY,QAAQ,CAAC;YAAE,MAAM,GAAG,CAAC;QAC1C,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,eAAe,CAAC,YAAY,CAAC,CAAC,CAAC;QAC/F,MAAM,IAAI,QAAQ,CAChB,GAAG,CAAC,IAAI,EACR,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,8BAA8B,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAC/F,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,EAC5B,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA0B;IACzD,IAAI,CAAC,KAAK,CAAC,SAAS;QAAE,OAAO;IAC7B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;QAC7B,QAAQ,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;IAC9E,CAAC;IACD,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,IAAI,cAAc,EAAE,CAAC;QACzE,QAAQ,CAAC,IAAI,CAAC,iBAAiB,KAAK,CAAC,UAAU,6CAA6C,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;QAC9D,QAAQ,CAAC,IAAI,CACX,wBAAwB,KAAK,CAAC,OAAO,wDAAwD,CAC9F,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAClC,OAAO,8CAA8C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;AAC9E,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Preview encoding utilities: PNG content blocks, contact sheets,
|
|
2
|
+
* @fileoverview Preview encoding utilities: PNG content blocks, contact sheets, and the
|
|
3
|
+
* PNG/GIF preview files written to PIXOO_OUTPUT_DIR or a temp directory.
|
|
3
4
|
* @module renderer/preview
|
|
4
5
|
*/
|
|
5
6
|
import { Canvas } from '@cyanheads/pixoo-toolkit';
|
|
@@ -9,26 +10,23 @@ export interface ImageContentBlock {
|
|
|
9
10
|
mimeType: 'image/png' | 'image/gif';
|
|
10
11
|
type: 'image';
|
|
11
12
|
}
|
|
12
|
-
/**
|
|
13
|
-
export
|
|
14
|
-
gif?: string;
|
|
15
|
-
preview?: string;
|
|
16
|
-
}
|
|
13
|
+
/** Writes a render's preview file into `dir` and resolves to the file's path. */
|
|
14
|
+
export type PreviewWriter = (dir: string) => Promise<string>;
|
|
17
15
|
/** Encode a single canvas as a base64 PNG content block (8× upscaled → 512px). */
|
|
18
16
|
export declare function encodePreviewBlock(canvas: Canvas): ImageContentBlock;
|
|
19
17
|
/**
|
|
20
|
-
* Build a contact-sheet preview
|
|
21
|
-
*
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Optionally save a preview PNG to PIXOO_OUTPUT_DIR.
|
|
26
|
-
* Returns the saved path, or undefined if no output dir is configured.
|
|
27
|
-
*/
|
|
28
|
-
export declare function savePngPreview(canvas: Canvas, baseName: string): Promise<string | undefined>;
|
|
29
|
-
/**
|
|
30
|
-
* Optionally save an animation GIF to PIXOO_OUTPUT_DIR.
|
|
31
|
-
* Returns the saved path, or undefined if no output dir is configured.
|
|
18
|
+
* Build a contact-sheet preview: every frame, in order, tiled left-to-right and
|
|
19
|
+
* top-to-bottom in a `ceil(sqrt(n))`-column grid, each tile an integer upscale that
|
|
20
|
+
* keeps the sheet within the 512px preview budget. A single frame encodes exactly as
|
|
21
|
+
* {@link encodePreviewBlock} does.
|
|
32
22
|
*/
|
|
33
|
-
export declare function
|
|
23
|
+
export declare function buildContactSheet(frames: Canvas[]): Promise<ImageContentBlock>;
|
|
24
|
+
/** Save a canvas as an 8× upscaled PNG in `dir`; returns the saved path. */
|
|
25
|
+
export declare function savePngPreview(canvas: Canvas, dir: string, baseName: string): Promise<string>;
|
|
26
|
+
/** Save animation frames as an 8× upscaled GIF in `dir`; returns the saved path. */
|
|
27
|
+
export declare function saveGifPreview(frames: Canvas[], speed: number, dir: string, baseName: string): Promise<string>;
|
|
28
|
+
/** Write the preview into PIXOO_OUTPUT_DIR when one is configured; returns the paths written. */
|
|
29
|
+
export declare function autoSavePreview(write: PreviewWriter): Promise<string[]>;
|
|
30
|
+
/** Write the preview into a fresh directory under the OS temp dir; returns its path. */
|
|
31
|
+
export declare function saveTempPreview(write: PreviewWriter): Promise<string>;
|
|
34
32
|
//# sourceMappingURL=preview.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/renderer/preview.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/renderer/preview.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,MAAM,EAA0C,MAAM,0BAA0B,CAAC;AAG1F,+BAA+B;AAC/B,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,WAAW,GAAG,WAAW,CAAC;IACpC,IAAI,EAAE,OAAO,CAAC;CACf;AAED,iFAAiF;AACjF,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAS7D,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAIpE;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA+BpF;AAED,4EAA4E;AAC5E,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,oFAAoF;AACpF,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAKjB;AAED,iGAAiG;AACjG,wBAAsB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAG7E;AAED,wFAAwF;AACxF,wBAAsB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAE3E"}
|
package/dist/renderer/preview.js
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Preview encoding utilities: PNG content blocks, contact sheets,
|
|
2
|
+
* @fileoverview Preview encoding utilities: PNG content blocks, contact sheets, and the
|
|
3
|
+
* PNG/GIF preview files written to PIXOO_OUTPUT_DIR or a temp directory.
|
|
3
4
|
* @module renderer/preview
|
|
4
5
|
*/
|
|
5
6
|
import * as fs from 'node:fs/promises';
|
|
7
|
+
import * as os from 'node:os';
|
|
6
8
|
import * as path from 'node:path';
|
|
7
|
-
import { Canvas, canvasToPng, saveAnimationGif } from '@cyanheads/pixoo-toolkit';
|
|
9
|
+
import { Canvas, canvasToPng, saveAnimationGif, savePng } from '@cyanheads/pixoo-toolkit';
|
|
8
10
|
import { getServerConfig } from '../config/server-config.js';
|
|
11
|
+
/** Edge length, in pixels, a preview image is scaled toward. */
|
|
12
|
+
const PREVIEW_BUDGET_PX = 512;
|
|
13
|
+
/** Gutter between contact-sheet tiles, which also fills the grid's unused cells. */
|
|
14
|
+
const SHEET_GAP_PX = 2;
|
|
15
|
+
const SHEET_GAP_COLOR = { r: 48, g: 48, b: 48 };
|
|
9
16
|
/** Encode a single canvas as a base64 PNG content block (8× upscaled → 512px). */
|
|
10
17
|
export function encodePreviewBlock(canvas) {
|
|
11
18
|
const pngBuffer = canvasToPng(canvas, 8);
|
|
@@ -13,44 +20,58 @@ export function encodePreviewBlock(canvas) {
|
|
|
13
20
|
return { type: 'image', data: base64, mimeType: 'image/png' };
|
|
14
21
|
}
|
|
15
22
|
/**
|
|
16
|
-
* Build a contact-sheet preview
|
|
17
|
-
*
|
|
23
|
+
* Build a contact-sheet preview: every frame, in order, tiled left-to-right and
|
|
24
|
+
* top-to-bottom in a `ceil(sqrt(n))`-column grid, each tile an integer upscale that
|
|
25
|
+
* keeps the sheet within the 512px preview budget. A single frame encodes exactly as
|
|
26
|
+
* {@link encodePreviewBlock} does.
|
|
18
27
|
*/
|
|
19
|
-
export function buildContactSheet(frames) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
export async function buildContactSheet(frames) {
|
|
29
|
+
const [first] = frames;
|
|
30
|
+
if (!first || frames.length === 1)
|
|
31
|
+
return encodePreviewBlock(first ?? new Canvas(64));
|
|
32
|
+
const cols = Math.ceil(Math.sqrt(frames.length));
|
|
33
|
+
const rows = Math.ceil(frames.length / cols);
|
|
34
|
+
const scale = Math.max(1, Math.floor((PREVIEW_BUDGET_PX - (cols - 1) * SHEET_GAP_PX) / (cols * first.width)));
|
|
35
|
+
const pitch = first.width * scale + SHEET_GAP_PX;
|
|
36
|
+
const { default: sharp } = await import('sharp');
|
|
37
|
+
const png = await sharp({
|
|
38
|
+
create: {
|
|
39
|
+
width: cols * pitch - SHEET_GAP_PX,
|
|
40
|
+
height: rows * pitch - SHEET_GAP_PX,
|
|
41
|
+
channels: 3,
|
|
42
|
+
background: SHEET_GAP_COLOR,
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
.composite(frames.map((frame, i) => ({
|
|
46
|
+
input: Buffer.from(canvasToPng(frame, scale)),
|
|
47
|
+
left: (i % cols) * pitch,
|
|
48
|
+
top: Math.floor(i / cols) * pitch,
|
|
49
|
+
})))
|
|
50
|
+
.png()
|
|
51
|
+
.toBuffer();
|
|
52
|
+
return { type: 'image', data: png.toString('base64'), mimeType: 'image/png' };
|
|
28
53
|
}
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
export async function savePngPreview(canvas, baseName) {
|
|
34
|
-
const cfg = getServerConfig();
|
|
35
|
-
if (!cfg.pixooOutputDir)
|
|
36
|
-
return;
|
|
37
|
-
await fs.mkdir(cfg.pixooOutputDir, { recursive: true });
|
|
38
|
-
const filePath = path.join(cfg.pixooOutputDir, `${baseName}.png`);
|
|
39
|
-
const { savePng } = await import('@cyanheads/pixoo-toolkit');
|
|
54
|
+
/** Save a canvas as an 8× upscaled PNG in `dir`; returns the saved path. */
|
|
55
|
+
export async function savePngPreview(canvas, dir, baseName) {
|
|
56
|
+
await fs.mkdir(dir, { recursive: true });
|
|
57
|
+
const filePath = path.join(dir, `${baseName}.png`);
|
|
40
58
|
await savePng(canvas, filePath, 8);
|
|
41
59
|
return filePath;
|
|
42
60
|
}
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
export async function saveGifPreview(frames, speed, baseName) {
|
|
48
|
-
const cfg = getServerConfig();
|
|
49
|
-
if (!cfg.pixooOutputDir)
|
|
50
|
-
return;
|
|
51
|
-
await fs.mkdir(cfg.pixooOutputDir, { recursive: true });
|
|
52
|
-
const filePath = path.join(cfg.pixooOutputDir, `${baseName}.gif`);
|
|
61
|
+
/** Save animation frames as an 8× upscaled GIF in `dir`; returns the saved path. */
|
|
62
|
+
export async function saveGifPreview(frames, speed, dir, baseName) {
|
|
63
|
+
await fs.mkdir(dir, { recursive: true });
|
|
64
|
+
const filePath = path.join(dir, `${baseName}.gif`);
|
|
53
65
|
await saveAnimationGif(frames, filePath, speed, 8);
|
|
54
66
|
return filePath;
|
|
55
67
|
}
|
|
68
|
+
/** Write the preview into PIXOO_OUTPUT_DIR when one is configured; returns the paths written. */
|
|
69
|
+
export async function autoSavePreview(write) {
|
|
70
|
+
const dir = getServerConfig().pixooOutputDir;
|
|
71
|
+
return dir ? [await write(dir)] : [];
|
|
72
|
+
}
|
|
73
|
+
/** Write the preview into a fresh directory under the OS temp dir; returns its path. */
|
|
74
|
+
export async function saveTempPreview(write) {
|
|
75
|
+
return write(await fs.mkdtemp(path.join(os.tmpdir(), 'pixoo-preview-')));
|
|
76
|
+
}
|
|
56
77
|
//# sourceMappingURL=preview.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/renderer/preview.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/renderer/preview.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* image elements and the pixoo_push_image tool.
|
|
5
5
|
* @module renderer/remote-image
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
7
|
+
import type { Context } from '@cyanheads/mcp-ts-core';
|
|
8
8
|
/** True when the string is a URL rather than a local filesystem path. */
|
|
9
9
|
export declare function isRemoteSource(source: string): boolean;
|
|
10
10
|
/**
|
|
@@ -14,8 +14,12 @@ export declare function isRemoteSource(source: string): boolean;
|
|
|
14
14
|
* Private and loopback addresses are deliberately reachable: this server drives a
|
|
15
15
|
* LAN device, so a NAS or local web server is a legitimate image host.
|
|
16
16
|
*
|
|
17
|
+
* The download runs under `ctx.signal`: a cancelled request tears the response stream
|
|
18
|
+
* down instead of reading on to the deadline or the byte cap.
|
|
19
|
+
*
|
|
17
20
|
* @throws {McpError} NotFound with `reason: 'asset_not_found'` for a non-https URL,
|
|
18
21
|
* an unreachable or non-2xx endpoint, or a response over {@link MAX_IMAGE_BYTES}.
|
|
22
|
+
* @throws {McpError} RequestCancelled when `ctx.signal` aborts while the body streams.
|
|
19
23
|
*/
|
|
20
|
-
export declare function fetchRemoteImageToTempPng(source: string, ctx:
|
|
24
|
+
export declare function fetchRemoteImageToTempPng(source: string, ctx: Context): Promise<string>;
|
|
21
25
|
//# sourceMappingURL=remote-image.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-image.d.ts","sourceRoot":"","sources":["../../src/renderer/remote-image.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"remote-image.d.ts","sourceRoot":"","sources":["../../src/renderer/remote-image.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAUtD,yEAAyE;AACzE,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAiE7F"}
|
|
@@ -23,8 +23,12 @@ export function isRemoteSource(source) {
|
|
|
23
23
|
* Private and loopback addresses are deliberately reachable: this server drives a
|
|
24
24
|
* LAN device, so a NAS or local web server is a legitimate image host.
|
|
25
25
|
*
|
|
26
|
+
* The download runs under `ctx.signal`: a cancelled request tears the response stream
|
|
27
|
+
* down instead of reading on to the deadline or the byte cap.
|
|
28
|
+
*
|
|
26
29
|
* @throws {McpError} NotFound with `reason: 'asset_not_found'` for a non-https URL,
|
|
27
30
|
* an unreachable or non-2xx endpoint, or a response over {@link MAX_IMAGE_BYTES}.
|
|
31
|
+
* @throws {McpError} RequestCancelled when `ctx.signal` aborts while the body streams.
|
|
28
32
|
*/
|
|
29
33
|
export async function fetchRemoteImageToTempPng(source, ctx) {
|
|
30
34
|
if (!source.startsWith('https://')) {
|
|
@@ -34,7 +38,11 @@ export async function fetchRemoteImageToTempPng(source, ctx) {
|
|
|
34
38
|
recovery: { hint: 'Use an https URL, or pass an absolute local file path instead.' },
|
|
35
39
|
});
|
|
36
40
|
}
|
|
37
|
-
|
|
41
|
+
// A throw here after the signal fired still reaches the caller as a cancellation:
|
|
42
|
+
// the handler factory reclassifies any error once the request's signal has aborted.
|
|
43
|
+
const resp = await fetchWithTimeout(source, FETCH_TIMEOUT_MS, ctx, {
|
|
44
|
+
signal: ctx.signal,
|
|
45
|
+
}).catch((err) => {
|
|
38
46
|
throw notFound(`Failed to fetch image from "${source}": ${err instanceof Error ? err.message : String(err)}`, {
|
|
39
47
|
reason: 'asset_not_found',
|
|
40
48
|
url: source,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remote-image.js","sourceRoot":"","sources":["../../src/renderer/remote-image.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"remote-image.js","sourceRoot":"","sources":["../../src/renderer/remote-image.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* @fileoverview Scene renderer — element vocabulary, layout resolver, frame rendering.
|
|
3
3
|
* @module renderer/scene-renderer
|
|
4
4
|
*/
|
|
5
|
-
import type {
|
|
6
|
-
import { Canvas, downsampleSprite } from '@cyanheads/pixoo-toolkit';
|
|
5
|
+
import type { Context } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { Canvas, downsampleSprite, type PixooSize } from '@cyanheads/pixoo-toolkit';
|
|
7
7
|
import { type EffectName, type KeyframeMap } from './keyframes.js';
|
|
8
8
|
import { type LayoutEntry, type SemanticX, type SemanticY, type TextStyle } from './text-engine.js';
|
|
9
9
|
import { type PaletteName, type ThemeName } from './themes.js';
|
|
@@ -154,18 +154,23 @@ export interface SpriteElement extends BaseElement {
|
|
|
154
154
|
y?: number;
|
|
155
155
|
}
|
|
156
156
|
export type SceneElement = TextElement | IconElement | RectElement | CircleElement | LineElement | ProgressElement | SparklineElement | BitmapElement | PixelsElement | ImageElement | SpriteElement;
|
|
157
|
-
/**
|
|
157
|
+
/**
|
|
158
|
+
* Pre-loaded asset cache for images and sprites. Images are keyed by element: the
|
|
159
|
+
* loader bakes each element's fit, size, and position into its canvas, so two
|
|
160
|
+
* elements sharing a source still need a canvas each.
|
|
161
|
+
*/
|
|
158
162
|
export interface AssetCache {
|
|
159
|
-
images: Map<
|
|
163
|
+
images: Map<ImageElement, Canvas>;
|
|
160
164
|
sprites: Map<string, Awaited<ReturnType<typeof downsampleSprite>>>;
|
|
161
165
|
}
|
|
162
166
|
/**
|
|
163
|
-
* Preload all async assets referenced in elements.
|
|
167
|
+
* Preload all async assets referenced in elements. Images load onto a `size` canvas,
|
|
168
|
+
* the scene's own, so an image with no `w`/`h` fits the display.
|
|
164
169
|
*
|
|
165
|
-
* `ctx` is threaded through so a remote image fetch correlates to the
|
|
166
|
-
*
|
|
170
|
+
* `ctx` is threaded through so a remote image fetch correlates to the originating
|
|
171
|
+
* request in logs and traces, and stops when that request is cancelled.
|
|
167
172
|
*/
|
|
168
|
-
export declare function preloadAssets(elements: SceneElement[], ctx:
|
|
173
|
+
export declare function preloadAssets(elements: SceneElement[], ctx: Context, size: PixooSize): Promise<AssetCache>;
|
|
169
174
|
/** Apply a background spec to a canvas. */
|
|
170
175
|
export declare function applyBackground(canvas: Canvas, bg: BackgroundSpec): void;
|
|
171
176
|
/** Render a single element onto a canvas at a specific frame. */
|
|
@@ -176,7 +181,7 @@ export declare function renderFrame(frameIdx: number, totalFrames: number, backg
|
|
|
176
181
|
layoutEntries: LayoutEntry[];
|
|
177
182
|
};
|
|
178
183
|
/** Render all frames of a scene. */
|
|
179
|
-
export declare function renderScene(background: BackgroundSpec, elements: SceneElement[], frameCount: number, ctx:
|
|
184
|
+
export declare function renderScene(background: BackgroundSpec, elements: SceneElement[], frameCount: number, ctx: Context, size?: PixooSize): Promise<{
|
|
180
185
|
frames: Canvas[];
|
|
181
186
|
layoutEntries: LayoutEntry[];
|
|
182
187
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene-renderer.d.ts","sourceRoot":"","sources":["../../src/renderer/scene-renderer.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"scene-renderer.d.ts","sourceRoot":"","sources":["../../src/renderer/scene-renderer.ts"],"names":[],"mappings":"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"}
|