@cli-remote/local 0.4.0 → 0.4.2
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/index.cjs +65 -15
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -10468,16 +10468,65 @@ var DesktopManager = class {
|
|
|
10468
10468
|
/** Probes displays/workspaces. Degrades gracefully — missing tools yield
|
|
10469
10469
|
* empty/unknown values, never throws (web always gets an answer). */
|
|
10470
10470
|
async queryInfo() {
|
|
10471
|
-
if (this.platform
|
|
10472
|
-
|
|
10471
|
+
if (this.platform === "darwin") {
|
|
10472
|
+
const displays = await this.listScreensMac().catch(() => []);
|
|
10473
|
+
return {
|
|
10474
|
+
displays,
|
|
10475
|
+
workspaces: null,
|
|
10476
|
+
currentWorkspace: null,
|
|
10477
|
+
canPickDisplay: displays.length > 1,
|
|
10478
|
+
cropMode: "client"
|
|
10479
|
+
};
|
|
10473
10480
|
}
|
|
10474
|
-
|
|
10475
|
-
|
|
10476
|
-
|
|
10477
|
-
|
|
10478
|
-
|
|
10479
|
-
|
|
10480
|
-
|
|
10481
|
+
if (this.platform === "linux") {
|
|
10482
|
+
const [heads, ws] = await Promise.all([
|
|
10483
|
+
this.listHeads().catch(() => []),
|
|
10484
|
+
this.workspaceState().catch(() => null)
|
|
10485
|
+
]);
|
|
10486
|
+
return {
|
|
10487
|
+
displays: heads.map((h) => ({ name: h.name, width: h.w, height: h.h, x: h.x, y: h.y })),
|
|
10488
|
+
workspaces: ws?.count ?? null,
|
|
10489
|
+
currentWorkspace: ws?.current ?? null,
|
|
10490
|
+
canPickDisplay: heads.length > 0,
|
|
10491
|
+
cropMode: "server"
|
|
10492
|
+
};
|
|
10493
|
+
}
|
|
10494
|
+
return { displays: [], workspaces: null, currentWorkspace: null, canPickDisplay: false, cropMode: "client" };
|
|
10495
|
+
}
|
|
10496
|
+
/** macOS: NSScreen frames via JXA (osascript -l JavaScript + AppKit).
|
|
10497
|
+
* AppKit origins are bottom-left → converted to CG top-left coords to
|
|
10498
|
+
* match the RFB framebuffer. Warm run ~1.5s; any failure → empty list. */
|
|
10499
|
+
async listScreensMac() {
|
|
10500
|
+
const script = [
|
|
10501
|
+
'ObjC.import("AppKit")',
|
|
10502
|
+
"const screens = $.NSScreen.screens",
|
|
10503
|
+
"let gb = 0",
|
|
10504
|
+
"for (let i = 0; i < screens.count; i++) {",
|
|
10505
|
+
" const f = screens.objectAtIndex(i).frame",
|
|
10506
|
+
" gb = Math.max(gb, f.origin.y + f.size.height)",
|
|
10507
|
+
"}",
|
|
10508
|
+
"const out = []",
|
|
10509
|
+
"for (let i = 0; i < screens.count; i++) {",
|
|
10510
|
+
" const s = screens.objectAtIndex(i)",
|
|
10511
|
+
" const f = s.frame",
|
|
10512
|
+
' out.push([Math.round(f.origin.x), Math.round(gb - f.origin.y - f.size.height), Math.round(f.size.width), Math.round(f.size.height), s.localizedName.js].join("|"))',
|
|
10513
|
+
"}",
|
|
10514
|
+
'out.join("\\n")'
|
|
10515
|
+
].join("\n");
|
|
10516
|
+
const out = await this.exec("osascript", ["-l", "JavaScript", "-e", script], 8e3);
|
|
10517
|
+
const displays = [];
|
|
10518
|
+
for (const line of out.split("\n").filter((l) => l.trim())) {
|
|
10519
|
+
const [x, y, w, h, ...rest] = line.split("|");
|
|
10520
|
+
if (x === void 0 || w === void 0 || rest.length === 0) continue;
|
|
10521
|
+
displays.push({
|
|
10522
|
+
name: rest.join("|"),
|
|
10523
|
+
x: Number(x),
|
|
10524
|
+
y: Number(y),
|
|
10525
|
+
width: Number(w),
|
|
10526
|
+
height: Number(h)
|
|
10527
|
+
});
|
|
10528
|
+
}
|
|
10529
|
+
return displays;
|
|
10481
10530
|
}
|
|
10482
10531
|
/** `xrandr --query` connected heads (name + geometry). */
|
|
10483
10532
|
async listHeads() {
|
|
@@ -10508,9 +10557,6 @@ var DesktopManager = class {
|
|
|
10508
10557
|
if (opts.workspace !== void 0 && this.platform !== "linux") {
|
|
10509
10558
|
throw new Error("workspace selection is not supported on this platform (session-internal prev/next still works on macOS)");
|
|
10510
10559
|
}
|
|
10511
|
-
if (opts.display !== void 0 && this.platform !== "linux") {
|
|
10512
|
-
throw new Error("display selection is not supported on this platform");
|
|
10513
|
-
}
|
|
10514
10560
|
if (opts.workspace !== void 0) {
|
|
10515
10561
|
await this.switchWorkspaceAbsolute(opts.workspace);
|
|
10516
10562
|
this.hooks.log(`desktop ${sessionId}: workspace \u2192 ${opts.workspace}`);
|
|
@@ -10518,7 +10564,7 @@ var DesktopManager = class {
|
|
|
10518
10564
|
let tcp = await probeConnect(host, port, 750);
|
|
10519
10565
|
let ownChild = null;
|
|
10520
10566
|
let clip;
|
|
10521
|
-
if (opts.display !== void 0) {
|
|
10567
|
+
if (opts.display !== void 0 && this.platform === "linux") {
|
|
10522
10568
|
const heads = await this.listHeads().catch(() => []);
|
|
10523
10569
|
clip = heads[opts.display];
|
|
10524
10570
|
if (!clip) {
|
|
@@ -10673,6 +10719,9 @@ var DesktopManager = class {
|
|
|
10673
10719
|
/** Linux: respawn OUR x11vnc with a new -clip and swap the TCP socket.
|
|
10674
10720
|
* The RFB handshake restarts on the web side (viewer re-attaches). */
|
|
10675
10721
|
async switchDisplay(s, display) {
|
|
10722
|
+
if (this.platform === "darwin") {
|
|
10723
|
+
return "display switching is client-side on this platform (web viewport crop)";
|
|
10724
|
+
}
|
|
10676
10725
|
if (this.platform !== "linux") return "display switching is not supported on this platform";
|
|
10677
10726
|
if (s.externalServer || !s.x11vnc) {
|
|
10678
10727
|
return "cannot switch displays on an external VNC server (only locally started x11vnc)";
|
|
@@ -11895,7 +11944,8 @@ async function startLocal(opts = {}) {
|
|
|
11895
11944
|
displays: [],
|
|
11896
11945
|
workspaces: null,
|
|
11897
11946
|
currentWorkspace: null,
|
|
11898
|
-
canPickDisplay: false
|
|
11947
|
+
canPickDisplay: false,
|
|
11948
|
+
cropMode: "client"
|
|
11899
11949
|
})
|
|
11900
11950
|
);
|
|
11901
11951
|
});
|
|
@@ -12174,7 +12224,7 @@ function resolveHere() {
|
|
|
12174
12224
|
var argUrl = process.argv[2];
|
|
12175
12225
|
var argMatch = argUrl && (argUrl.startsWith("ws://") || argUrl.startsWith("wss://"));
|
|
12176
12226
|
function readVersion() {
|
|
12177
|
-
if (true) return "0.4.
|
|
12227
|
+
if (true) return "0.4.2";
|
|
12178
12228
|
try {
|
|
12179
12229
|
const pkg = JSON.parse(
|
|
12180
12230
|
(0, import_node_fs5.readFileSync)(new URL("../package.json", import_meta.url), "utf-8")
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cli-remote/local",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Local PTY agent for cli-remote — exposes your local CLI tools (claude/codex/kimi-cli/shell) to the mobile web client via a self-hosted hub.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|