@mcp-use/cli 3.2.1-canary.9 → 3.3.0-canary.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/screenshot.d.ts +11 -0
- package/dist/commands/screenshot.d.ts.map +1 -1
- package/dist/index.cjs +67 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +67 -24
- package/dist/index.js.map +1 -1
- package/dist/utils/cdp-screenshot.d.ts +19 -3
- package/dist/utils/cdp-screenshot.d.ts.map +1 -1
- package/dist/utils/widget-paths.d.ts +2 -0
- package/dist/utils/widget-paths.d.ts.map +1 -0
- package/package.json +3 -3
|
@@ -22,7 +22,16 @@ interface CaptureToolScreenshotInputs {
|
|
|
22
22
|
resourceUri: string;
|
|
23
23
|
}
|
|
24
24
|
interface CaptureToolScreenshotOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Desired output width in CSS pixels. When omitted, the screenshot fits the
|
|
27
|
+
* widget's natural rendered width. When set, also overrides the inline-mode
|
|
28
|
+
* 768px max-width cap so the widget renders at the requested width.
|
|
29
|
+
*/
|
|
25
30
|
width?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Desired output height in CSS pixels. When omitted, the screenshot fits the
|
|
33
|
+
* widget's natural rendered height.
|
|
34
|
+
*/
|
|
26
35
|
height?: number;
|
|
27
36
|
theme?: "light" | "dark";
|
|
28
37
|
output?: string;
|
|
@@ -46,7 +55,9 @@ interface CaptureToolScreenshotOptions {
|
|
|
46
55
|
}
|
|
47
56
|
interface CaptureToolScreenshotResult {
|
|
48
57
|
outputPath: string;
|
|
58
|
+
/** Final clip width in CSS pixels (what the PNG visually represents). */
|
|
49
59
|
width: number;
|
|
60
|
+
/** Final clip height in CSS pixels. */
|
|
50
61
|
height: number;
|
|
51
62
|
view: string;
|
|
52
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/commands/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAwCjD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAa5D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOtE;AAaD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,SAAS,GAAG,IAAI,GAC3D,MAAM,GAAG,IAAI,CAUf;AAED,UAAU,2BAA2B;IACnC,OAAO,EAAE,UAAU,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,4BAA4B;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,UAAU,2BAA2B;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,2BAA2B,EACnC,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,2BAA2B,CAAC,
|
|
1
|
+
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../src/commands/screenshot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAwCjD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAa5D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOtE;AAaD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG,SAAS,GAAG,IAAI,GAC3D,MAAM,GAAG,IAAI,CAUf;AAED,UAAU,2BAA2B;IACnC,OAAO,EAAE,UAAU,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,4BAA4B;IACpC;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,UAAU,2BAA2B;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,2BAA2B,EACnC,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,2BAA2B,CAAC,CAmEtC;AAqLD;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,OAAa,GAAG,MAAM,CAKzD;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAa1D;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAI/D;AAmRD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAwBvD;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAetE"}
|
package/dist/index.cjs
CHANGED
|
@@ -2790,6 +2790,10 @@ async function captureScreenshot(opts) {
|
|
|
2790
2790
|
}
|
|
2791
2791
|
}
|
|
2792
2792
|
};
|
|
2793
|
+
const DEFAULT_VIEWPORT_WIDTH = 1280;
|
|
2794
|
+
const DEFAULT_VIEWPORT_HEIGHT = 2e3;
|
|
2795
|
+
const viewportWidth = Math.max(opts.width ?? 0, DEFAULT_VIEWPORT_WIDTH);
|
|
2796
|
+
const viewportHeight = Math.max(opts.height ?? 0, DEFAULT_VIEWPORT_HEIGHT);
|
|
2793
2797
|
try {
|
|
2794
2798
|
let wsUrl;
|
|
2795
2799
|
if (opts.cdpUrl) {
|
|
@@ -2811,7 +2815,7 @@ async function captureScreenshot(opts) {
|
|
|
2811
2815
|
"--disable-gpu",
|
|
2812
2816
|
"--hide-scrollbars",
|
|
2813
2817
|
"--mute-audio",
|
|
2814
|
-
`--window-size=${
|
|
2818
|
+
`--window-size=${viewportWidth},${viewportHeight}`,
|
|
2815
2819
|
"about:blank"
|
|
2816
2820
|
];
|
|
2817
2821
|
child = (0, import_node_child_process8.spawn)(opts.chromePath, chromeArgs, {
|
|
@@ -2879,8 +2883,8 @@ async function captureScreenshot(opts) {
|
|
|
2879
2883
|
await cdp.send(
|
|
2880
2884
|
"Emulation.setDeviceMetricsOverride",
|
|
2881
2885
|
{
|
|
2882
|
-
width:
|
|
2883
|
-
height:
|
|
2886
|
+
width: viewportWidth,
|
|
2887
|
+
height: viewportHeight,
|
|
2884
2888
|
deviceScaleFactor: opts.deviceScaleFactor ?? 1,
|
|
2885
2889
|
mobile: false
|
|
2886
2890
|
},
|
|
@@ -2930,21 +2934,36 @@ async function captureScreenshot(opts) {
|
|
|
2930
2934
|
if (opts.delayMs && opts.delayMs > 0) {
|
|
2931
2935
|
await new Promise((res) => setTimeout(res, opts.delayMs));
|
|
2932
2936
|
}
|
|
2937
|
+
const rectResult = await cdp.send(
|
|
2938
|
+
"Runtime.evaluate",
|
|
2939
|
+
{
|
|
2940
|
+
expression: `(() => {
|
|
2941
|
+
const d = document.body.dataset;
|
|
2942
|
+
const n = (s) => { const v = parseFloat(s ?? ""); return Number.isFinite(v) ? v : undefined; };
|
|
2943
|
+
return { x: n(d.viewX), y: n(d.viewY), width: n(d.viewWidth), height: n(d.viewHeight) };
|
|
2944
|
+
})()`,
|
|
2945
|
+
returnByValue: true
|
|
2946
|
+
},
|
|
2947
|
+
sessionId
|
|
2948
|
+
);
|
|
2949
|
+
const rect = rectResult.result?.value ?? {};
|
|
2950
|
+
const clip = {
|
|
2951
|
+
x: rect.x ?? 0,
|
|
2952
|
+
y: rect.y ?? 0,
|
|
2953
|
+
width: opts.width ?? (rect.width && rect.width > 0 ? rect.width : viewportWidth),
|
|
2954
|
+
height: opts.height ?? (rect.height && rect.height > 0 ? rect.height : viewportHeight),
|
|
2955
|
+
scale: 1
|
|
2956
|
+
};
|
|
2933
2957
|
const shot = await cdp.send(
|
|
2934
2958
|
"Page.captureScreenshot",
|
|
2935
2959
|
{
|
|
2936
2960
|
format: "png",
|
|
2937
|
-
clip
|
|
2938
|
-
x: 0,
|
|
2939
|
-
y: 0,
|
|
2940
|
-
width: opts.width,
|
|
2941
|
-
height: opts.height,
|
|
2942
|
-
scale: 1
|
|
2943
|
-
}
|
|
2961
|
+
clip
|
|
2944
2962
|
},
|
|
2945
2963
|
sessionId
|
|
2946
2964
|
);
|
|
2947
2965
|
(0, import_node_fs6.writeFileSync)(opts.outputPath, Buffer.from(shot.data, "base64"));
|
|
2966
|
+
return { width: clip.width, height: clip.height };
|
|
2948
2967
|
} finally {
|
|
2949
2968
|
cleanup();
|
|
2950
2969
|
}
|
|
@@ -3073,16 +3092,13 @@ function detectToolResourceUri(tool) {
|
|
|
3073
3092
|
return uiMeta?.resourceUri ?? meta["openai/outputTemplate"] ?? null;
|
|
3074
3093
|
}
|
|
3075
3094
|
async function captureToolScreenshot(inputs, options = {}) {
|
|
3076
|
-
const width = options
|
|
3077
|
-
const height = options.height ?? 600;
|
|
3095
|
+
const { width, height } = options;
|
|
3078
3096
|
const theme = options.theme ?? "light";
|
|
3079
3097
|
const timeoutMs = options.timeoutMs ?? 3e4;
|
|
3080
3098
|
const delayMs = options.delayMs ?? 0;
|
|
3081
3099
|
const chromePath = options.cdpUrl ? void 0 : resolveChromePath();
|
|
3082
3100
|
const view = extractViewName(inputs.resourceUri);
|
|
3083
3101
|
const devOptions = {
|
|
3084
|
-
width: String(width),
|
|
3085
|
-
height: String(height),
|
|
3086
3102
|
theme,
|
|
3087
3103
|
timeout: String(timeoutMs),
|
|
3088
3104
|
inspector: options.inspector,
|
|
@@ -3102,10 +3118,13 @@ async function captureToolScreenshot(inputs, options = {}) {
|
|
|
3102
3118
|
};
|
|
3103
3119
|
const previewUrl = new URL(`/inspector/preview/${view}`, devHandle.url);
|
|
3104
3120
|
previewUrl.searchParams.set("theme", theme);
|
|
3121
|
+
if (width !== void 0) {
|
|
3122
|
+
previewUrl.searchParams.set("width", String(width));
|
|
3123
|
+
}
|
|
3105
3124
|
const ts = timestampSuffix();
|
|
3106
3125
|
const outputPath = import_node_path6.default.resolve(options.output ?? `./${view}-${ts}.png`);
|
|
3107
3126
|
await (0, import_promises5.mkdir)(import_node_path6.default.dirname(outputPath), { recursive: true });
|
|
3108
|
-
await captureScreenshot({
|
|
3127
|
+
const captured = await captureScreenshot({
|
|
3109
3128
|
url: previewUrl.toString(),
|
|
3110
3129
|
width,
|
|
3111
3130
|
height,
|
|
@@ -3119,7 +3138,12 @@ async function captureToolScreenshot(inputs, options = {}) {
|
|
|
3119
3138
|
bundle,
|
|
3120
3139
|
deviceScaleFactor: options.deviceScaleFactor
|
|
3121
3140
|
});
|
|
3122
|
-
return {
|
|
3141
|
+
return {
|
|
3142
|
+
outputPath,
|
|
3143
|
+
width: captured.width,
|
|
3144
|
+
height: captured.height,
|
|
3145
|
+
view
|
|
3146
|
+
};
|
|
3123
3147
|
} finally {
|
|
3124
3148
|
killChild(devHandle?.child);
|
|
3125
3149
|
}
|
|
@@ -3249,9 +3273,10 @@ function timestampSuffix(date = /* @__PURE__ */ new Date()) {
|
|
|
3249
3273
|
return `${datePart}_${timePart}`;
|
|
3250
3274
|
}
|
|
3251
3275
|
function extractViewName(resourceUri) {
|
|
3252
|
-
const m = resourceUri.match(/^ui:\/\/
|
|
3253
|
-
if (!m) return resourceUri;
|
|
3254
|
-
|
|
3276
|
+
const m = resourceUri.match(/^ui:\/\/([^/]+)\/(.+)$/);
|
|
3277
|
+
if (!m) return encodeURIComponent(resourceUri);
|
|
3278
|
+
const name = m[2].replace(/\.html$/, "").replace(/\.[0-9a-f]+$/i, "");
|
|
3279
|
+
return m[1] === "widget" ? name : `${m[1]}-${name}`;
|
|
3255
3280
|
}
|
|
3256
3281
|
function parseDimension(raw, name) {
|
|
3257
3282
|
const n = parseInt(raw, 10);
|
|
@@ -3351,8 +3376,8 @@ async function screenshotCommand(options, argsList, context) {
|
|
|
3351
3376
|
exitCode = 1;
|
|
3352
3377
|
return;
|
|
3353
3378
|
}
|
|
3354
|
-
const width = parseDimension(options.width, "width");
|
|
3355
|
-
const height = parseDimension(options.height, "height");
|
|
3379
|
+
const width = options.width !== void 0 ? parseDimension(options.width, "width") : void 0;
|
|
3380
|
+
const height = options.height !== void 0 ? parseDimension(options.height, "height") : void 0;
|
|
3356
3381
|
const navTimeout = parseInt(options.timeout, 10) || 3e4;
|
|
3357
3382
|
const delayMs = options.delay ? parseInt(options.delay, 10) : 0;
|
|
3358
3383
|
const deviceScaleFactor = options.deviceScaleFactor ? parseDeviceScaleFactor(options.deviceScaleFactor) : void 0;
|
|
@@ -3461,7 +3486,13 @@ function withCommonScreenshotOptions(cmd) {
|
|
|
3461
3486
|
).option(
|
|
3462
3487
|
"--tool <name>",
|
|
3463
3488
|
"Tool to call. Its UI resource is rendered with the result."
|
|
3464
|
-
).option(
|
|
3489
|
+
).option(
|
|
3490
|
+
"--width <px>",
|
|
3491
|
+
"Output image width in pixels. When omitted, fits the widget's natural width. When set, the widget renders at this width (overrides the inline-mode 768px cap)."
|
|
3492
|
+
).option(
|
|
3493
|
+
"--height <px>",
|
|
3494
|
+
"Output image height in pixels. When omitted, fits the widget's natural height."
|
|
3495
|
+
).option(
|
|
3465
3496
|
"--device-scale-factor <n>",
|
|
3466
3497
|
"Device pixel ratio for rendering (e.g. 2 for Retina). Output PNG is (width \xD7 dsf) \xD7 (height \xD7 dsf). Must be > 0 and <= 4."
|
|
3467
3498
|
).option(
|
|
@@ -7152,6 +7183,16 @@ A new release of ${source_default.bold(PACKAGE_NAME)} is available: ${source_def
|
|
|
7152
7183
|
}
|
|
7153
7184
|
}
|
|
7154
7185
|
|
|
7186
|
+
// src/utils/widget-paths.ts
|
|
7187
|
+
function getWidgetAssetBase(mcpUrl, widgetName) {
|
|
7188
|
+
const widgetPath = `/mcp-use/widgets/${widgetName}/`;
|
|
7189
|
+
if (!mcpUrl) {
|
|
7190
|
+
return widgetPath;
|
|
7191
|
+
}
|
|
7192
|
+
const origin = mcpUrl.replace(/\/+$/, "");
|
|
7193
|
+
return `${origin}${widgetPath}`;
|
|
7194
|
+
}
|
|
7195
|
+
|
|
7155
7196
|
// src/index.ts
|
|
7156
7197
|
var program = new import_commander7.Command();
|
|
7157
7198
|
var packageContent = (0, import_node_fs14.readFileSync)(
|
|
@@ -7642,7 +7683,7 @@ if (container && Component) {
|
|
|
7642
7683
|
"widgets",
|
|
7643
7684
|
widgetName
|
|
7644
7685
|
);
|
|
7645
|
-
const baseUrl = mcpUrl
|
|
7686
|
+
const baseUrl = getWidgetAssetBase(mcpUrl, widgetName);
|
|
7646
7687
|
let widgetMetadata = {};
|
|
7647
7688
|
try {
|
|
7648
7689
|
const metadataTempDir = import_node_path12.default.join(
|
|
@@ -7958,7 +7999,9 @@ export default {
|
|
|
7958
7999
|
try {
|
|
7959
8000
|
const htmlPath = import_node_path12.default.join(outDir, "index.html");
|
|
7960
8001
|
let html = await fs11.readFile(htmlPath, "utf8");
|
|
7961
|
-
const
|
|
8002
|
+
const widgetAssetBase = getWidgetAssetBase(mcpUrl, widgetName);
|
|
8003
|
+
const mcpOrigin = mcpUrl ? mcpUrl.replace(/\/+$/, "") : mcpServerUrl;
|
|
8004
|
+
const injectionScript = `<script>window.__getFile = (filename) => { return "${widgetAssetBase}"+filename }; window.__mcpPublicUrl = "${mcpServerUrl}/mcp-use/public"; window.__mcpPublicAssetsUrl = "${mcpOrigin}/mcp-use/public";</script>`;
|
|
7962
8005
|
if (!html.includes("window.__mcpPublicUrl")) {
|
|
7963
8006
|
html = html.replace(
|
|
7964
8007
|
/<head[^>]*>/i,
|