tauri-agent-tools 0.4.0 → 0.5.1
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/skills/tauri-agent-tools/SKILL.md +2 -1
- package/README.md +4 -2
- package/dist/cli.js +6 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/diff.js +6 -2
- package/dist/commands/diff.js.map +1 -1
- package/dist/platform/detect.d.ts +2 -1
- package/dist/platform/detect.js +84 -35
- package/dist/platform/detect.js.map +1 -1
- package/dist/platform/hyprland.d.ts +11 -0
- package/dist/platform/hyprland.js +51 -0
- package/dist/platform/hyprland.js.map +1 -0
- package/dist/platform/x11.js +3 -1
- package/dist/platform/x11.js.map +1 -1
- package/dist/schemas/platform.d.ts +51 -0
- package/dist/schemas/platform.js +11 -0
- package/dist/schemas/platform.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/util/image.js +5 -2
- package/dist/util/image.js.map +1 -1
- package/dist/util/magick.d.ts +21 -0
- package/dist/util/magick.js +46 -0
- package/dist/util/magick.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tauri-agent-tools
|
|
3
3
|
description: CLI for inspecting Tauri desktop apps — DOM queries, screenshots, IPC/console monitoring, storage, and page state
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.1
|
|
5
5
|
tags: [tauri, desktop, debugging, screenshot, dom, inspection, diff, mutations, snapshot]
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -25,6 +25,7 @@ npm install -g tauri-agent-tools
|
|
|
25
25
|
|----------|-------------|
|
|
26
26
|
| Linux X11 | `xdotool`, `imagemagick` (`sudo apt install xdotool imagemagick`) |
|
|
27
27
|
| Linux Wayland/Sway | `swaymsg`, `grim`, `imagemagick` |
|
|
28
|
+
| Linux Wayland/Hyprland | `hyprctl` (included with Hyprland), `grim`, `imagemagick` |
|
|
28
29
|
| macOS | `imagemagick` (`brew install imagemagick`), Screen Recording permission |
|
|
29
30
|
|
|
30
31
|
## Bridge vs Standalone
|
package/README.md
CHANGED
|
@@ -46,6 +46,7 @@ npm install -g tauri-agent-tools
|
|
|
46
46
|
**System requirements:**
|
|
47
47
|
- **Linux X11:** `xdotool`, `imagemagick` (`sudo apt install xdotool imagemagick`)
|
|
48
48
|
- **Linux Wayland/Sway:** `swaymsg`, `grim`, `imagemagick`
|
|
49
|
+
- **Linux Wayland/Hyprland:** `hyprctl` (included with Hyprland), `grim`, `imagemagick`
|
|
49
50
|
- **macOS:** `imagemagick` (`brew install imagemagick`) — all other tools are built-in. Grant Screen Recording permission in System Settings → Privacy & Security → Screen Recording.
|
|
50
51
|
|
|
51
52
|
## Quick Start
|
|
@@ -256,7 +257,7 @@ screenshot --selector ".toolbar" --title "My App"
|
|
|
256
257
|
├─► Compute crop region:
|
|
257
258
|
│ element rect from bridge + viewport offset (outerHeight - innerHeight)
|
|
258
259
|
│
|
|
259
|
-
└─►
|
|
260
|
+
└─► ImageMagick crop: png:- -crop WxH+X+Y +repage png:-
|
|
260
261
|
```
|
|
261
262
|
|
|
262
263
|
The crop accounts for window decoration (title bar, borders) by comparing `window.innerHeight` from the bridge with the actual window height from `xdotool`.
|
|
@@ -267,6 +268,7 @@ The crop accounts for window decoration (title bar, borders) by comparing `windo
|
|
|
267
268
|
|----------|---------------|--------|
|
|
268
269
|
| Linux | X11 | Supported |
|
|
269
270
|
| Linux | Wayland (Sway) | Supported |
|
|
271
|
+
| Linux | Wayland (Hyprland) | Supported |
|
|
270
272
|
| macOS | CoreGraphics | Supported |
|
|
271
273
|
| Windows | - | Planned |
|
|
272
274
|
|
|
@@ -293,7 +295,7 @@ This tool is a CLI that runs commands and exits — not a persistent MCP server.
|
|
|
293
295
|
## Safety Guarantees
|
|
294
296
|
|
|
295
297
|
- **No input injection** — no mouse moves, clicks, keystrokes, or cursor changes
|
|
296
|
-
- **No xcap crate** — uses `xdotool` + ImageMagick
|
|
298
|
+
- **No xcap crate** — uses `xdotool` + ImageMagick (read-only X11 operations)
|
|
297
299
|
- **No daemon** — CLI runs and exits, no background processes
|
|
298
300
|
- **No `.mcp.json`** — never auto-starts
|
|
299
301
|
- **All OS interactions read-only** — `xdotool search`, `getwindowgeometry`, `import -window`
|
package/dist/cli.js
CHANGED
|
@@ -7,6 +7,7 @@ import { detectDisplayServer, ensureTools } from './platform/detect.js';
|
|
|
7
7
|
import { PackageJsonSchema } from './schemas/commands.js';
|
|
8
8
|
import { X11Adapter } from './platform/x11.js';
|
|
9
9
|
import { WaylandAdapter } from './platform/wayland.js';
|
|
10
|
+
import { HyprlandAdapter } from './platform/hyprland.js';
|
|
10
11
|
import { MacOSAdapter } from './platform/macos.js';
|
|
11
12
|
import { registerScreenshot } from './commands/screenshot.js';
|
|
12
13
|
import { registerInfo } from './commands/info.js';
|
|
@@ -40,7 +41,11 @@ async function getAdapter() {
|
|
|
40
41
|
}
|
|
41
42
|
if (ds === 'darwin')
|
|
42
43
|
return new MacOSAdapter();
|
|
43
|
-
|
|
44
|
+
if (ds === 'wayland-hyprland')
|
|
45
|
+
return new HyprlandAdapter();
|
|
46
|
+
if (ds === 'wayland-sway' || ds === 'wayland')
|
|
47
|
+
return new WaylandAdapter();
|
|
48
|
+
return new X11Adapter();
|
|
44
49
|
}
|
|
45
50
|
registerScreenshot(program, getAdapter);
|
|
46
51
|
registerInfo(program, getAdapter);
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,GAAG,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAEjH,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE;KAC1B,IAAI,CAAC,mBAAmB,CAAC;KACzB,WAAW,CAAC,wDAAwD,CAAC;KACrE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExB,IAAI,YAAY,GAAyB,IAAI,CAAC;AAE9C,KAAK,UAAU,UAAU;IACvB,MAAM,EAAE,GAAG,mBAAmB,EAAE,CAAC;IACjC,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,kFAAkF,CACnF,CAAC;IACJ,CAAC;IAED,IAAI,YAAY,KAAK,EAAE,EAAE,CAAC;QACxB,MAAM,WAAW,CAAC,EAAE,CAAC,CAAC;QACtB,YAAY,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,IAAI,EAAE,KAAK,QAAQ;QAAE,OAAO,IAAI,YAAY,EAAE,CAAC;IAC/C,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/diff.js
CHANGED
|
@@ -2,6 +2,7 @@ import { stat } from 'node:fs/promises';
|
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { exec } from '../util/exec.js';
|
|
5
|
+
import { magickCommand } from '../util/magick.js';
|
|
5
6
|
function formatResult(result) {
|
|
6
7
|
const lines = [
|
|
7
8
|
`Pixels different: ${result.pixelsDifferent}`,
|
|
@@ -34,7 +35,8 @@ export function registerDiff(program) {
|
|
|
34
35
|
// Get image dimensions for total pixel count
|
|
35
36
|
let totalPixels = 0;
|
|
36
37
|
try {
|
|
37
|
-
const
|
|
38
|
+
const identifyCmd = await magickCommand('identify');
|
|
39
|
+
const { stdout } = await exec(identifyCmd.bin, [...identifyCmd.args, '-format', '%w %h', image1]);
|
|
38
40
|
const [w, h] = z.tuple([z.number().int().positive(), z.number().int().positive()]).parse(stdout.toString().trim().split(' ').map(Number));
|
|
39
41
|
totalPixels = w * h;
|
|
40
42
|
}
|
|
@@ -48,7 +50,9 @@ export function registerDiff(program) {
|
|
|
48
50
|
let pixelsDifferent = 0;
|
|
49
51
|
try {
|
|
50
52
|
// compare exits with code 1 when images differ (not an error)
|
|
51
|
-
const
|
|
53
|
+
const compareCmd = await magickCommand('compare');
|
|
54
|
+
const { stderr } = await exec(compareCmd.bin, [
|
|
55
|
+
...compareCmd.args,
|
|
52
56
|
'-metric', 'AE',
|
|
53
57
|
image1,
|
|
54
58
|
image2,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ export interface ToolCheck {
|
|
|
6
6
|
installHint: string;
|
|
7
7
|
}
|
|
8
8
|
export declare function checkX11Tools(): Promise<ToolCheck[]>;
|
|
9
|
-
export declare function
|
|
9
|
+
export declare function checkSwayTools(): Promise<ToolCheck[]>;
|
|
10
|
+
export declare function checkHyprlandTools(): Promise<ToolCheck[]>;
|
|
10
11
|
export declare function checkMacOSTools(): Promise<ToolCheck[]>;
|
|
11
12
|
export declare function ensureTools(displayServer: DisplayServer): Promise<void>;
|
package/dist/platform/detect.js
CHANGED
|
@@ -2,14 +2,17 @@ import { execFile } from 'node:child_process';
|
|
|
2
2
|
export function detectDisplayServer() {
|
|
3
3
|
if (process.platform === 'darwin')
|
|
4
4
|
return 'darwin';
|
|
5
|
-
|
|
5
|
+
const isWayland = !!process.env.WAYLAND_DISPLAY || process.env.XDG_SESSION_TYPE === 'wayland';
|
|
6
|
+
if (isWayland) {
|
|
7
|
+
if (process.env.SWAYSOCK)
|
|
8
|
+
return 'wayland-sway';
|
|
9
|
+
if (process.env.HYPRLAND_INSTANCE_SIGNATURE)
|
|
10
|
+
return 'wayland-hyprland';
|
|
6
11
|
return 'wayland';
|
|
12
|
+
}
|
|
7
13
|
if (process.env.DISPLAY)
|
|
8
14
|
return 'x11';
|
|
9
|
-
|
|
10
|
-
if (session === 'wayland')
|
|
11
|
-
return 'wayland';
|
|
12
|
-
if (session === 'x11')
|
|
15
|
+
if (process.env.XDG_SESSION_TYPE === 'x11')
|
|
13
16
|
return 'x11';
|
|
14
17
|
return 'unknown';
|
|
15
18
|
}
|
|
@@ -19,47 +22,93 @@ function commandExists(cmd) {
|
|
|
19
22
|
execFile(which, [cmd], (error) => resolve(!error));
|
|
20
23
|
});
|
|
21
24
|
}
|
|
25
|
+
async function checkImageMagick(installHint) {
|
|
26
|
+
// ImageMagick v7 uses a unified `magick` binary; v6 has standalone commands
|
|
27
|
+
const hasMagick = await commandExists('magick');
|
|
28
|
+
if (hasMagick) {
|
|
29
|
+
return { name: 'magick (ImageMagick)', available: true, installHint };
|
|
30
|
+
}
|
|
31
|
+
const hasConvert = await commandExists('convert');
|
|
32
|
+
return { name: 'magick (ImageMagick)', available: hasConvert, installHint };
|
|
33
|
+
}
|
|
22
34
|
export async function checkX11Tools() {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
const [xdotool, magick] = await Promise.all([
|
|
36
|
+
commandExists('xdotool').then((available) => ({
|
|
37
|
+
name: 'xdotool',
|
|
38
|
+
available,
|
|
39
|
+
installHint: 'sudo apt install xdotool',
|
|
40
|
+
})),
|
|
41
|
+
checkImageMagick('sudo apt install imagemagick'),
|
|
42
|
+
]);
|
|
43
|
+
return [xdotool, magick];
|
|
32
44
|
}
|
|
33
|
-
export async function
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
export async function checkSwayTools() {
|
|
46
|
+
const [swaymsg, grim, magick] = await Promise.all([
|
|
47
|
+
commandExists('swaymsg').then((available) => ({
|
|
48
|
+
name: 'swaymsg',
|
|
49
|
+
available,
|
|
50
|
+
installHint: 'sudo apt install sway',
|
|
51
|
+
})),
|
|
52
|
+
commandExists('grim').then((available) => ({
|
|
53
|
+
name: 'grim',
|
|
54
|
+
available,
|
|
55
|
+
installHint: 'sudo apt install grim',
|
|
56
|
+
})),
|
|
57
|
+
checkImageMagick('sudo apt install imagemagick'),
|
|
58
|
+
]);
|
|
59
|
+
return [swaymsg, grim, magick];
|
|
60
|
+
}
|
|
61
|
+
export async function checkHyprlandTools() {
|
|
62
|
+
const [hyprctl, grim, magick] = await Promise.all([
|
|
63
|
+
commandExists('hyprctl').then((available) => ({
|
|
64
|
+
name: 'hyprctl',
|
|
65
|
+
available,
|
|
66
|
+
installHint: 'Included with Hyprland',
|
|
67
|
+
})),
|
|
68
|
+
commandExists('grim').then((available) => ({
|
|
69
|
+
name: 'grim',
|
|
70
|
+
available,
|
|
71
|
+
installHint: 'sudo apt install grim',
|
|
72
|
+
})),
|
|
73
|
+
checkImageMagick('sudo apt install imagemagick'),
|
|
74
|
+
]);
|
|
75
|
+
return [hyprctl, grim, magick];
|
|
43
76
|
}
|
|
44
77
|
export async function checkMacOSTools() {
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
78
|
+
const [screencapture, osascript, sips, magick] = await Promise.all([
|
|
79
|
+
commandExists('screencapture').then((available) => ({
|
|
80
|
+
name: 'screencapture',
|
|
81
|
+
available,
|
|
82
|
+
installHint: 'Built-in on macOS',
|
|
83
|
+
})),
|
|
84
|
+
commandExists('osascript').then((available) => ({
|
|
85
|
+
name: 'osascript',
|
|
86
|
+
available,
|
|
87
|
+
installHint: 'Built-in on macOS',
|
|
88
|
+
})),
|
|
89
|
+
commandExists('sips').then((available) => ({
|
|
90
|
+
name: 'sips',
|
|
91
|
+
available,
|
|
92
|
+
installHint: 'Built-in on macOS',
|
|
93
|
+
})),
|
|
94
|
+
checkImageMagick('brew install imagemagick'),
|
|
95
|
+
]);
|
|
96
|
+
return [screencapture, osascript, sips, magick];
|
|
55
97
|
}
|
|
56
98
|
export async function ensureTools(displayServer) {
|
|
57
99
|
let checks;
|
|
58
100
|
if (displayServer === 'darwin') {
|
|
59
101
|
checks = await checkMacOSTools();
|
|
60
102
|
}
|
|
103
|
+
else if (displayServer === 'wayland-sway') {
|
|
104
|
+
checks = await checkSwayTools();
|
|
105
|
+
}
|
|
106
|
+
else if (displayServer === 'wayland-hyprland') {
|
|
107
|
+
checks = await checkHyprlandTools();
|
|
108
|
+
}
|
|
61
109
|
else if (displayServer === 'wayland') {
|
|
62
|
-
|
|
110
|
+
// Generic Wayland — try sway tools as fallback
|
|
111
|
+
checks = await checkSwayTools();
|
|
63
112
|
}
|
|
64
113
|
else {
|
|
65
114
|
checks = await checkX11Tools();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/platform/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,MAAM,UAAU,mBAAmB;IACjC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/platform/detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PlatformAdapter, WindowInfo } from '../types.js';
|
|
2
|
+
import type { ImageFormat } from '../schemas/commands.js';
|
|
3
|
+
export declare class HyprlandAdapter implements PlatformAdapter {
|
|
4
|
+
findWindow(title: string): Promise<string>;
|
|
5
|
+
captureWindow(windowId: string, format: ImageFormat): Promise<Buffer>;
|
|
6
|
+
getWindowGeometry(windowId: string): Promise<WindowInfo>;
|
|
7
|
+
getWindowName(windowId: string): Promise<string>;
|
|
8
|
+
listWindows(): Promise<WindowInfo[]>;
|
|
9
|
+
private _getClients;
|
|
10
|
+
private _toWindowInfo;
|
|
11
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { exec } from '../util/exec.js';
|
|
2
|
+
import { HyprClientListSchema } from '../schemas/platform.js';
|
|
3
|
+
export class HyprlandAdapter {
|
|
4
|
+
async findWindow(title) {
|
|
5
|
+
const clients = await this._getClients();
|
|
6
|
+
const match = clients.find((c) => c.mapped && !c.hidden && c.title.includes(title));
|
|
7
|
+
if (!match) {
|
|
8
|
+
throw new Error(`No window found matching: ${title}`);
|
|
9
|
+
}
|
|
10
|
+
return match.address;
|
|
11
|
+
}
|
|
12
|
+
async captureWindow(windowId, format) {
|
|
13
|
+
const geom = await this.getWindowGeometry(windowId);
|
|
14
|
+
const region = `${geom.x},${geom.y} ${geom.width}x${geom.height}`;
|
|
15
|
+
const fmt = format === 'jpg' ? 'jpeg' : 'png';
|
|
16
|
+
const { stdout } = await exec('grim', ['-g', region, '-t', fmt, '-']);
|
|
17
|
+
return stdout;
|
|
18
|
+
}
|
|
19
|
+
async getWindowGeometry(windowId) {
|
|
20
|
+
const clients = await this._getClients();
|
|
21
|
+
const client = clients.find((c) => c.address === windowId);
|
|
22
|
+
if (!client) {
|
|
23
|
+
throw new Error(`Window ${windowId} not found`);
|
|
24
|
+
}
|
|
25
|
+
return this._toWindowInfo(client);
|
|
26
|
+
}
|
|
27
|
+
async getWindowName(windowId) {
|
|
28
|
+
const geom = await this.getWindowGeometry(windowId);
|
|
29
|
+
return geom.name ?? '';
|
|
30
|
+
}
|
|
31
|
+
async listWindows() {
|
|
32
|
+
const clients = await this._getClients();
|
|
33
|
+
return clients.filter((c) => c.mapped && !c.hidden).map((c) => this._toWindowInfo(c));
|
|
34
|
+
}
|
|
35
|
+
async _getClients() {
|
|
36
|
+
const { stdout } = await exec('hyprctl', ['clients', '-j']);
|
|
37
|
+
return HyprClientListSchema.parse(JSON.parse(stdout.toString()));
|
|
38
|
+
}
|
|
39
|
+
_toWindowInfo(client) {
|
|
40
|
+
return {
|
|
41
|
+
windowId: client.address,
|
|
42
|
+
pid: client.pid,
|
|
43
|
+
name: client.title || undefined,
|
|
44
|
+
x: client.at[0],
|
|
45
|
+
y: client.at[1],
|
|
46
|
+
width: client.size[0],
|
|
47
|
+
height: client.size[1],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=hyprland.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hyprland.js","sourceRoot":"","sources":["../../src/platform/hyprland.ts"],"names":[],"mappings":"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"}
|
package/dist/platform/x11.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { exec, validateWindowId } from '../util/exec.js';
|
|
2
|
+
import { magickCommand } from '../util/magick.js';
|
|
2
3
|
function parseShellVar(output, key, fallback) {
|
|
3
4
|
const match = output.match(new RegExp(`${key}=(\\d+)`));
|
|
4
5
|
if (!match) {
|
|
@@ -20,7 +21,8 @@ export class X11Adapter {
|
|
|
20
21
|
async captureWindow(windowId, format) {
|
|
21
22
|
validateWindowId(windowId);
|
|
22
23
|
const fmt = format === 'jpg' ? 'jpg' : 'png';
|
|
23
|
-
const
|
|
24
|
+
const cmd = await magickCommand('import');
|
|
25
|
+
const { stdout } = await exec(cmd.bin, [...cmd.args, '-window', windowId, `${fmt}:-`]);
|
|
24
26
|
return stdout;
|
|
25
27
|
}
|
|
26
28
|
async getWindowGeometry(windowId) {
|
package/dist/platform/x11.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"x11.js","sourceRoot":"","sources":["../../src/platform/x11.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"x11.js","sourceRoot":"","sources":["../../src/platform/x11.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,SAAS,aAAa,CAAC,MAAc,EAAE,GAAW,EAAE,QAAiB;IACnE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC;IACxD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,sBAAsB,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,OAAO,UAAU;IACrB,KAAK,CAAC,UAAU,CAAC,KAAa;QAC5B,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;QACtE,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACjE,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAC;QACxD,CAAC;QACD,OAAO,GAAG,CAAC,CAAC,CAAE,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,QAAgB,EAAE,MAAmB;QACvD,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC3B,MAAM,GAAG,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAC7C,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC1C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC;QACvF,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,QAAgB;QACtC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC3B,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,mBAAmB,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;QACrF,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAEjC,OAAO;YACL,QAAQ;YACR,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC;YAC7B,CAAC,EAAE,aAAa,CAAC,MAAM,EAAE,GAAG,CAAC;YAC7B,KAAK,EAAE,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC;YACrC,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC;SACxC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,QAAgB;QAClC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC3B,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC;QACtE,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,WAAW;QACf,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;QACnE,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEjE,MAAM,OAAO,GAAiB,EAAE,CAAC;QACjC,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;oBAC5D,IAAI,CAAC,SAAS,EAAE,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;oBACtC,IAAI,CAAC,SAAS,EAAE,CAAC,mBAAmB,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;oBACrD,IAAI,CAAC,SAAS,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;iBACtC,CAAC,CAAC;gBAEH,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;gBACjD,IAAI,CAAC,IAAI;oBAAE,SAAS;gBAEpB,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAChD,MAAM,GAAG,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;gBAE7D,OAAO,CAAC,IAAI,CAAC;oBACX,QAAQ,EAAE,EAAE;oBACZ,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG;oBACjC,IAAI;oBACJ,CAAC,EAAE,aAAa,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;oBACpC,CAAC,EAAE,aAAa,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;oBACpC,KAAK,EAAE,aAAa,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;oBAC5C,MAAM,EAAE,aAAa,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;iBAC/C,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,oDAAoD;gBACpD,SAAS;YACX,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -59,3 +59,54 @@ export interface SwayNode {
|
|
|
59
59
|
floating_nodes?: SwayNode[];
|
|
60
60
|
}
|
|
61
61
|
export declare const SwayNodeSchema: z.ZodType<SwayNode>;
|
|
62
|
+
export declare const HyprClientSchema: z.ZodObject<{
|
|
63
|
+
address: z.ZodString;
|
|
64
|
+
mapped: z.ZodBoolean;
|
|
65
|
+
hidden: z.ZodBoolean;
|
|
66
|
+
at: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
67
|
+
size: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
68
|
+
title: z.ZodString;
|
|
69
|
+
pid: z.ZodNumber;
|
|
70
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
71
|
+
address: z.ZodString;
|
|
72
|
+
mapped: z.ZodBoolean;
|
|
73
|
+
hidden: z.ZodBoolean;
|
|
74
|
+
at: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
75
|
+
size: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
76
|
+
title: z.ZodString;
|
|
77
|
+
pid: z.ZodNumber;
|
|
78
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
79
|
+
address: z.ZodString;
|
|
80
|
+
mapped: z.ZodBoolean;
|
|
81
|
+
hidden: z.ZodBoolean;
|
|
82
|
+
at: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
83
|
+
size: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
84
|
+
title: z.ZodString;
|
|
85
|
+
pid: z.ZodNumber;
|
|
86
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
87
|
+
export type HyprClient = z.infer<typeof HyprClientSchema>;
|
|
88
|
+
export declare const HyprClientListSchema: z.ZodArray<z.ZodObject<{
|
|
89
|
+
address: z.ZodString;
|
|
90
|
+
mapped: z.ZodBoolean;
|
|
91
|
+
hidden: z.ZodBoolean;
|
|
92
|
+
at: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
93
|
+
size: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
94
|
+
title: z.ZodString;
|
|
95
|
+
pid: z.ZodNumber;
|
|
96
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
97
|
+
address: z.ZodString;
|
|
98
|
+
mapped: z.ZodBoolean;
|
|
99
|
+
hidden: z.ZodBoolean;
|
|
100
|
+
at: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
101
|
+
size: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
102
|
+
title: z.ZodString;
|
|
103
|
+
pid: z.ZodNumber;
|
|
104
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
105
|
+
address: z.ZodString;
|
|
106
|
+
mapped: z.ZodBoolean;
|
|
107
|
+
hidden: z.ZodBoolean;
|
|
108
|
+
at: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
109
|
+
size: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
110
|
+
title: z.ZodString;
|
|
111
|
+
pid: z.ZodNumber;
|
|
112
|
+
}, z.ZodTypeAny, "passthrough">>, "many">;
|
package/dist/schemas/platform.js
CHANGED
|
@@ -31,4 +31,15 @@ export const SwayNodeSchema = z.object({
|
|
|
31
31
|
return z.array(SwayNodeSchema).optional();
|
|
32
32
|
},
|
|
33
33
|
});
|
|
34
|
+
// === Platform: Wayland / Hyprland ===
|
|
35
|
+
export const HyprClientSchema = z.object({
|
|
36
|
+
address: z.string(),
|
|
37
|
+
mapped: z.boolean(),
|
|
38
|
+
hidden: z.boolean(),
|
|
39
|
+
at: z.tuple([z.number(), z.number()]),
|
|
40
|
+
size: z.tuple([z.number(), z.number()]),
|
|
41
|
+
title: z.string(),
|
|
42
|
+
pid: z.number(),
|
|
43
|
+
}).passthrough();
|
|
44
|
+
export const HyprClientListSchema = z.array(HyprClientSchema);
|
|
34
45
|
//# sourceMappingURL=platform.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/schemas/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8BAA8B;AAE9B,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE7E,0BAA0B;AAE1B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;IAC3B,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzC,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC;QACxB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;QACb,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;QACb,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;KACnB,CAAC;CACH,CAAC,CAAC;AAcH,MAAM,CAAC,MAAM,cAAc,GAAwB,CAAC,CAAC,MAAM,CAAC;IAC1D,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACb,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;QACb,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;QACb,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;KACnB,CAAC;IACF,IAAI,KAAK;QACP,OAAO,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5C,CAAC;IACD,IAAI,cAAc;QAChB,OAAO,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5C,CAAC;CACF,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/schemas/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8BAA8B;AAE9B,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAE7E,0BAA0B;AAE1B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE;IAC3B,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACxC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzC,eAAe,EAAE,CAAC,CAAC,MAAM,CAAC;QACxB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;QACb,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;QACb,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;KACnB,CAAC;CACH,CAAC,CAAC;AAcH,MAAM,CAAC,MAAM,cAAc,GAAwB,CAAC,CAAC,MAAM,CAAC;IAC1D,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACb,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;QACb,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;QACb,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;KACnB,CAAC;IACF,IAAI,KAAK;QACP,OAAO,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5C,CAAC;IACD,IAAI,cAAc;QAChB,OAAO,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC5C,CAAC;CACF,CAAC,CAAC;AAEH,uCAAuC;AAEvC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;IACnB,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;IACnB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;CAChB,CAAC,CAAC,WAAW,EAAE,CAAC;AAGjB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export interface WindowInfo {
|
|
|
9
9
|
width: number;
|
|
10
10
|
height: number;
|
|
11
11
|
}
|
|
12
|
-
export type DisplayServer = 'x11' | 'wayland' | 'darwin' | 'unknown';
|
|
12
|
+
export type DisplayServer = 'x11' | 'wayland-sway' | 'wayland-hyprland' | 'wayland' | 'darwin' | 'unknown';
|
|
13
13
|
export interface PlatformAdapter {
|
|
14
14
|
findWindow(title: string): Promise<string>;
|
|
15
15
|
captureWindow(windowId: string, format: ImageFormat): Promise<Buffer>;
|
package/dist/util/image.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { exec } from './exec.js';
|
|
2
|
+
import { magickCommand } from './magick.js';
|
|
2
3
|
export async function cropImage(buffer, rect, format) {
|
|
3
4
|
const fmt = format === 'jpg' ? 'jpg' : 'png';
|
|
4
5
|
const crop = `${Math.round(rect.width)}x${Math.round(rect.height)}+${Math.round(rect.x)}+${Math.round(rect.y)}`;
|
|
5
|
-
const
|
|
6
|
+
const cmd = await magickCommand('convert');
|
|
7
|
+
const { stdout } = await exec(cmd.bin, [...cmd.args, `${fmt}:-`, '-crop', crop, '+repage', `${fmt}:-`], { stdin: buffer });
|
|
6
8
|
return stdout;
|
|
7
9
|
}
|
|
8
10
|
export async function resizeImage(buffer, maxWidth, format) {
|
|
9
11
|
const fmt = format === 'jpg' ? 'jpg' : 'png';
|
|
10
|
-
const
|
|
12
|
+
const cmd = await magickCommand('convert');
|
|
13
|
+
const { stdout } = await exec(cmd.bin, [...cmd.args, `${fmt}:-`, '-resize', `${maxWidth}x>`, `${fmt}:-`], { stdin: buffer });
|
|
11
14
|
return stdout;
|
|
12
15
|
}
|
|
13
16
|
export function computeCropRect(elementRect, viewport, windowGeometry) {
|
package/dist/util/image.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/util/image.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"image.js","sourceRoot":"","sources":["../../src/util/image.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAc,EACd,IAAiB,EACjB,MAAmB;IAEnB,MAAM,GAAG,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7C,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAChH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IAC3C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAC3B,GAAG,CAAC,GAAG,EACP,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,GAAG,IAAI,CAAC,EAC/D,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAc,EACd,QAAgB,EAChB,MAAmB;IAEnB,MAAM,GAAG,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7C,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAC;IAC3C,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAC3B,GAAG,CAAC,GAAG,EACP,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,SAAS,EAAE,GAAG,QAAQ,IAAI,EAAE,GAAG,GAAG,IAAI,CAAC,EACjE,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,WAAwB,EACxB,QAA2C,EAC3C,cAAiD;IAEjD,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IACrD,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IACvD,OAAO;QACL,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC;QACzB,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC;QACzB,KAAK,EAAE,WAAW,CAAC,KAAK;QACxB,MAAM,EAAE,WAAW,CAAC,MAAM;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ImageMagick command resolver.
|
|
3
|
+
*
|
|
4
|
+
* v6: standalone commands — `convert`, `import`, `identify`, `compare`
|
|
5
|
+
* v7: unified binary — `magick convert`, `magick import`, etc.
|
|
6
|
+
* (`magick` alone acts as `convert`)
|
|
7
|
+
*/
|
|
8
|
+
export interface MagickCommand {
|
|
9
|
+
bin: string;
|
|
10
|
+
args: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare function detectMagickVersion(): Promise<6 | 7>;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve an ImageMagick subcommand to the correct bin + args prefix.
|
|
15
|
+
*
|
|
16
|
+
* v7: `magick` alone replaces `convert`; other subcommands use `magick <sub>`
|
|
17
|
+
* v6: standalone commands — `convert`, `import`, `identify`, `compare`
|
|
18
|
+
*/
|
|
19
|
+
export declare function magickCommand(subcommand: 'convert' | 'import' | 'identify' | 'compare'): Promise<MagickCommand>;
|
|
20
|
+
/** Reset cached version (for testing). */
|
|
21
|
+
export declare function _resetMagickCache(): void;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
let cachedVersion = null;
|
|
3
|
+
function commandExists(cmd) {
|
|
4
|
+
const which = process.platform === 'win32' ? 'where' : 'which';
|
|
5
|
+
return new Promise((resolve) => {
|
|
6
|
+
execFile(which, [cmd], (error) => resolve(!error));
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
export async function detectMagickVersion() {
|
|
10
|
+
if (cachedVersion !== null)
|
|
11
|
+
return cachedVersion;
|
|
12
|
+
if (await commandExists('magick')) {
|
|
13
|
+
cachedVersion = 7;
|
|
14
|
+
}
|
|
15
|
+
else if (await commandExists('convert')) {
|
|
16
|
+
cachedVersion = 6;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
throw new Error('ImageMagick not found. Install it:\n' +
|
|
20
|
+
' Linux: sudo apt install imagemagick (or your distro equivalent)\n' +
|
|
21
|
+
' macOS: brew install imagemagick');
|
|
22
|
+
}
|
|
23
|
+
return cachedVersion;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve an ImageMagick subcommand to the correct bin + args prefix.
|
|
27
|
+
*
|
|
28
|
+
* v7: `magick` alone replaces `convert`; other subcommands use `magick <sub>`
|
|
29
|
+
* v6: standalone commands — `convert`, `import`, `identify`, `compare`
|
|
30
|
+
*/
|
|
31
|
+
export async function magickCommand(subcommand) {
|
|
32
|
+
const version = await detectMagickVersion();
|
|
33
|
+
if (version === 7) {
|
|
34
|
+
// In v7, `magick` alone IS convert; other tools need the subcommand
|
|
35
|
+
if (subcommand === 'convert') {
|
|
36
|
+
return { bin: 'magick', args: [] };
|
|
37
|
+
}
|
|
38
|
+
return { bin: 'magick', args: [subcommand] };
|
|
39
|
+
}
|
|
40
|
+
return { bin: subcommand, args: [] };
|
|
41
|
+
}
|
|
42
|
+
/** Reset cached version (for testing). */
|
|
43
|
+
export function _resetMagickCache() {
|
|
44
|
+
cachedVersion = null;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=magick.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"magick.js","sourceRoot":"","sources":["../../src/util/magick.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAe9C,IAAI,aAAa,GAAiB,IAAI,CAAC;AAEvC,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,IAAI,aAAa,KAAK,IAAI;QAAE,OAAO,aAAa,CAAC;IAEjD,IAAI,MAAM,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClC,aAAa,GAAG,CAAC,CAAC;IACpB,CAAC;SAAM,IAAI,MAAM,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1C,aAAa,GAAG,CAAC,CAAC;IACpB,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CACb,sCAAsC;YACpC,uEAAuE;YACvE,oCAAoC,CACvC,CAAC;IACJ,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAyD;IAEzD,MAAM,OAAO,GAAG,MAAM,mBAAmB,EAAE,CAAC;IAE5C,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,oEAAoE;QACpE,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACrC,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;IAC/C,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACvC,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,iBAAiB;IAC/B,aAAa,GAAG,IAAI,CAAC;AACvB,CAAC"}
|