@mcp-use/cli 3.2.1-canary.9 → 3.3.0-canary.20
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
package/dist/index.js
CHANGED
|
@@ -2775,6 +2775,10 @@ async function captureScreenshot(opts) {
|
|
|
2775
2775
|
}
|
|
2776
2776
|
}
|
|
2777
2777
|
};
|
|
2778
|
+
const DEFAULT_VIEWPORT_WIDTH = 1280;
|
|
2779
|
+
const DEFAULT_VIEWPORT_HEIGHT = 2e3;
|
|
2780
|
+
const viewportWidth = Math.max(opts.width ?? 0, DEFAULT_VIEWPORT_WIDTH);
|
|
2781
|
+
const viewportHeight = Math.max(opts.height ?? 0, DEFAULT_VIEWPORT_HEIGHT);
|
|
2778
2782
|
try {
|
|
2779
2783
|
let wsUrl;
|
|
2780
2784
|
if (opts.cdpUrl) {
|
|
@@ -2796,7 +2800,7 @@ async function captureScreenshot(opts) {
|
|
|
2796
2800
|
"--disable-gpu",
|
|
2797
2801
|
"--hide-scrollbars",
|
|
2798
2802
|
"--mute-audio",
|
|
2799
|
-
`--window-size=${
|
|
2803
|
+
`--window-size=${viewportWidth},${viewportHeight}`,
|
|
2800
2804
|
"about:blank"
|
|
2801
2805
|
];
|
|
2802
2806
|
child = spawn(opts.chromePath, chromeArgs, {
|
|
@@ -2864,8 +2868,8 @@ async function captureScreenshot(opts) {
|
|
|
2864
2868
|
await cdp.send(
|
|
2865
2869
|
"Emulation.setDeviceMetricsOverride",
|
|
2866
2870
|
{
|
|
2867
|
-
width:
|
|
2868
|
-
height:
|
|
2871
|
+
width: viewportWidth,
|
|
2872
|
+
height: viewportHeight,
|
|
2869
2873
|
deviceScaleFactor: opts.deviceScaleFactor ?? 1,
|
|
2870
2874
|
mobile: false
|
|
2871
2875
|
},
|
|
@@ -2915,21 +2919,36 @@ async function captureScreenshot(opts) {
|
|
|
2915
2919
|
if (opts.delayMs && opts.delayMs > 0) {
|
|
2916
2920
|
await new Promise((res) => setTimeout(res, opts.delayMs));
|
|
2917
2921
|
}
|
|
2922
|
+
const rectResult = await cdp.send(
|
|
2923
|
+
"Runtime.evaluate",
|
|
2924
|
+
{
|
|
2925
|
+
expression: `(() => {
|
|
2926
|
+
const d = document.body.dataset;
|
|
2927
|
+
const n = (s) => { const v = parseFloat(s ?? ""); return Number.isFinite(v) ? v : undefined; };
|
|
2928
|
+
return { x: n(d.viewX), y: n(d.viewY), width: n(d.viewWidth), height: n(d.viewHeight) };
|
|
2929
|
+
})()`,
|
|
2930
|
+
returnByValue: true
|
|
2931
|
+
},
|
|
2932
|
+
sessionId
|
|
2933
|
+
);
|
|
2934
|
+
const rect = rectResult.result?.value ?? {};
|
|
2935
|
+
const clip = {
|
|
2936
|
+
x: rect.x ?? 0,
|
|
2937
|
+
y: rect.y ?? 0,
|
|
2938
|
+
width: opts.width ?? (rect.width && rect.width > 0 ? rect.width : viewportWidth),
|
|
2939
|
+
height: opts.height ?? (rect.height && rect.height > 0 ? rect.height : viewportHeight),
|
|
2940
|
+
scale: 1
|
|
2941
|
+
};
|
|
2918
2942
|
const shot = await cdp.send(
|
|
2919
2943
|
"Page.captureScreenshot",
|
|
2920
2944
|
{
|
|
2921
2945
|
format: "png",
|
|
2922
|
-
clip
|
|
2923
|
-
x: 0,
|
|
2924
|
-
y: 0,
|
|
2925
|
-
width: opts.width,
|
|
2926
|
-
height: opts.height,
|
|
2927
|
-
scale: 1
|
|
2928
|
-
}
|
|
2946
|
+
clip
|
|
2929
2947
|
},
|
|
2930
2948
|
sessionId
|
|
2931
2949
|
);
|
|
2932
2950
|
writeFileSync(opts.outputPath, Buffer.from(shot.data, "base64"));
|
|
2951
|
+
return { width: clip.width, height: clip.height };
|
|
2933
2952
|
} finally {
|
|
2934
2953
|
cleanup();
|
|
2935
2954
|
}
|
|
@@ -3058,16 +3077,13 @@ function detectToolResourceUri(tool) {
|
|
|
3058
3077
|
return uiMeta?.resourceUri ?? meta["openai/outputTemplate"] ?? null;
|
|
3059
3078
|
}
|
|
3060
3079
|
async function captureToolScreenshot(inputs, options = {}) {
|
|
3061
|
-
const width = options
|
|
3062
|
-
const height = options.height ?? 600;
|
|
3080
|
+
const { width, height } = options;
|
|
3063
3081
|
const theme = options.theme ?? "light";
|
|
3064
3082
|
const timeoutMs = options.timeoutMs ?? 3e4;
|
|
3065
3083
|
const delayMs = options.delayMs ?? 0;
|
|
3066
3084
|
const chromePath = options.cdpUrl ? void 0 : resolveChromePath();
|
|
3067
3085
|
const view = extractViewName(inputs.resourceUri);
|
|
3068
3086
|
const devOptions = {
|
|
3069
|
-
width: String(width),
|
|
3070
|
-
height: String(height),
|
|
3071
3087
|
theme,
|
|
3072
3088
|
timeout: String(timeoutMs),
|
|
3073
3089
|
inspector: options.inspector,
|
|
@@ -3087,10 +3103,13 @@ async function captureToolScreenshot(inputs, options = {}) {
|
|
|
3087
3103
|
};
|
|
3088
3104
|
const previewUrl = new URL(`/inspector/preview/${view}`, devHandle.url);
|
|
3089
3105
|
previewUrl.searchParams.set("theme", theme);
|
|
3106
|
+
if (width !== void 0) {
|
|
3107
|
+
previewUrl.searchParams.set("width", String(width));
|
|
3108
|
+
}
|
|
3090
3109
|
const ts = timestampSuffix();
|
|
3091
3110
|
const outputPath = path6.resolve(options.output ?? `./${view}-${ts}.png`);
|
|
3092
3111
|
await mkdir2(path6.dirname(outputPath), { recursive: true });
|
|
3093
|
-
await captureScreenshot({
|
|
3112
|
+
const captured = await captureScreenshot({
|
|
3094
3113
|
url: previewUrl.toString(),
|
|
3095
3114
|
width,
|
|
3096
3115
|
height,
|
|
@@ -3104,7 +3123,12 @@ async function captureToolScreenshot(inputs, options = {}) {
|
|
|
3104
3123
|
bundle,
|
|
3105
3124
|
deviceScaleFactor: options.deviceScaleFactor
|
|
3106
3125
|
});
|
|
3107
|
-
return {
|
|
3126
|
+
return {
|
|
3127
|
+
outputPath,
|
|
3128
|
+
width: captured.width,
|
|
3129
|
+
height: captured.height,
|
|
3130
|
+
view
|
|
3131
|
+
};
|
|
3108
3132
|
} finally {
|
|
3109
3133
|
killChild(devHandle?.child);
|
|
3110
3134
|
}
|
|
@@ -3234,9 +3258,10 @@ function timestampSuffix(date = /* @__PURE__ */ new Date()) {
|
|
|
3234
3258
|
return `${datePart}_${timePart}`;
|
|
3235
3259
|
}
|
|
3236
3260
|
function extractViewName(resourceUri) {
|
|
3237
|
-
const m = resourceUri.match(/^ui:\/\/
|
|
3238
|
-
if (!m) return resourceUri;
|
|
3239
|
-
|
|
3261
|
+
const m = resourceUri.match(/^ui:\/\/([^/]+)\/(.+)$/);
|
|
3262
|
+
if (!m) return encodeURIComponent(resourceUri);
|
|
3263
|
+
const name = m[2].replace(/\.html$/, "").replace(/\.[0-9a-f]+$/i, "");
|
|
3264
|
+
return m[1] === "widget" ? name : `${m[1]}-${name}`;
|
|
3240
3265
|
}
|
|
3241
3266
|
function parseDimension(raw, name) {
|
|
3242
3267
|
const n = parseInt(raw, 10);
|
|
@@ -3336,8 +3361,8 @@ async function screenshotCommand(options, argsList, context) {
|
|
|
3336
3361
|
exitCode = 1;
|
|
3337
3362
|
return;
|
|
3338
3363
|
}
|
|
3339
|
-
const width = parseDimension(options.width, "width");
|
|
3340
|
-
const height = parseDimension(options.height, "height");
|
|
3364
|
+
const width = options.width !== void 0 ? parseDimension(options.width, "width") : void 0;
|
|
3365
|
+
const height = options.height !== void 0 ? parseDimension(options.height, "height") : void 0;
|
|
3341
3366
|
const navTimeout = parseInt(options.timeout, 10) || 3e4;
|
|
3342
3367
|
const delayMs = options.delay ? parseInt(options.delay, 10) : 0;
|
|
3343
3368
|
const deviceScaleFactor = options.deviceScaleFactor ? parseDeviceScaleFactor(options.deviceScaleFactor) : void 0;
|
|
@@ -3446,7 +3471,13 @@ function withCommonScreenshotOptions(cmd) {
|
|
|
3446
3471
|
).option(
|
|
3447
3472
|
"--tool <name>",
|
|
3448
3473
|
"Tool to call. Its UI resource is rendered with the result."
|
|
3449
|
-
).option(
|
|
3474
|
+
).option(
|
|
3475
|
+
"--width <px>",
|
|
3476
|
+
"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)."
|
|
3477
|
+
).option(
|
|
3478
|
+
"--height <px>",
|
|
3479
|
+
"Output image height in pixels. When omitted, fits the widget's natural height."
|
|
3480
|
+
).option(
|
|
3450
3481
|
"--device-scale-factor <n>",
|
|
3451
3482
|
"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."
|
|
3452
3483
|
).option(
|
|
@@ -7137,6 +7168,16 @@ A new release of ${source_default.bold(PACKAGE_NAME)} is available: ${source_def
|
|
|
7137
7168
|
}
|
|
7138
7169
|
}
|
|
7139
7170
|
|
|
7171
|
+
// src/utils/widget-paths.ts
|
|
7172
|
+
function getWidgetAssetBase(mcpUrl, widgetName) {
|
|
7173
|
+
const widgetPath = `/mcp-use/widgets/${widgetName}/`;
|
|
7174
|
+
if (!mcpUrl) {
|
|
7175
|
+
return widgetPath;
|
|
7176
|
+
}
|
|
7177
|
+
const origin = mcpUrl.replace(/\/+$/, "");
|
|
7178
|
+
return `${origin}${widgetPath}`;
|
|
7179
|
+
}
|
|
7180
|
+
|
|
7140
7181
|
// src/index.ts
|
|
7141
7182
|
var program = new Command7();
|
|
7142
7183
|
var packageContent = readFileSync2(
|
|
@@ -7627,7 +7668,7 @@ if (container && Component) {
|
|
|
7627
7668
|
"widgets",
|
|
7628
7669
|
widgetName
|
|
7629
7670
|
);
|
|
7630
|
-
const baseUrl = mcpUrl
|
|
7671
|
+
const baseUrl = getWidgetAssetBase(mcpUrl, widgetName);
|
|
7631
7672
|
let widgetMetadata = {};
|
|
7632
7673
|
try {
|
|
7633
7674
|
const metadataTempDir = path11.join(
|
|
@@ -7943,7 +7984,9 @@ export default {
|
|
|
7943
7984
|
try {
|
|
7944
7985
|
const htmlPath = path11.join(outDir, "index.html");
|
|
7945
7986
|
let html = await fs11.readFile(htmlPath, "utf8");
|
|
7946
|
-
const
|
|
7987
|
+
const widgetAssetBase = getWidgetAssetBase(mcpUrl, widgetName);
|
|
7988
|
+
const mcpOrigin = mcpUrl ? mcpUrl.replace(/\/+$/, "") : mcpServerUrl;
|
|
7989
|
+
const injectionScript = `<script>window.__getFile = (filename) => { return "${widgetAssetBase}"+filename }; window.__mcpPublicUrl = "${mcpServerUrl}/mcp-use/public"; window.__mcpPublicAssetsUrl = "${mcpOrigin}/mcp-use/public";</script>`;
|
|
7947
7990
|
if (!html.includes("window.__mcpPublicUrl")) {
|
|
7948
7991
|
html = html.replace(
|
|
7949
7992
|
/<head[^>]*>/i,
|