f2f1cd9b6c
- Today's spend in the status bar and the Claude Code statusline is the
caller's own (`GET /api/pricing/cost?mine=1`, scope.ownSessionWhere), not
every user's sum for an admin or analyst.
- A screenshot pasted into a local claude pane is sent as Claude Code's own
image-paste key: Alt+V on Windows (Ctrl+V did nothing there), ^V elsewhere,
and only when the machine can read its clipboard (wl-paste/xclip + a
display on Linux), else it is uploaded (GET /api/run/native-paste {key}).
- A file manager's files pasted or dropped on a local browser go in by their
own paths, read from the OS clipboard or the file manager's selection
(server/lib/file-manager.js, POST /api/run/clipboard-files and
/selected-files): no upload, no size limit. A copied image file is pasted
by path, text that comes with a picture of it (spreadsheet cells) is
pasted as text, Windows paths go in as `C:/…` mentions.
- Tab titles for Snapshot, Artifacts, Files and Administration.
- An npm tool AgentHub installed under ~/.local is updated there, not by its
own updater into npm's global prefix.
91 lines
3.2 KiB
JavaScript
91 lines
3.2 KiB
JavaScript
/**
|
|
* @file desktop-env.test.js
|
|
* @description Unit tests for the graphical-session variables forwarded into a
|
|
* lane's tmux pane. Without them a `claude` started by the dashboard has no
|
|
* DISPLAY/WAYLAND_DISPLAY at all and answers "no image found in clipboard" on
|
|
* a paste, while the same CLI works in a normal terminal.
|
|
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
|
*/
|
|
const { describe, it, beforeEach, afterEach } = require("node:test");
|
|
const assert = require("node:assert/strict");
|
|
const { desktopEnv, canReadClipboard, FORWARDED, __setExecImpl } = require("../lib/desktop-env");
|
|
|
|
const saved = {};
|
|
|
|
describe("desktopEnv", () => {
|
|
beforeEach(() => {
|
|
for (const name of FORWARDED) {
|
|
saved[name] = process.env[name];
|
|
delete process.env[name];
|
|
}
|
|
});
|
|
afterEach(() => {
|
|
for (const name of FORWARDED) {
|
|
if (saved[name] === undefined) delete process.env[name];
|
|
else process.env[name] = saved[name];
|
|
}
|
|
});
|
|
|
|
it("reads the systemd user manager's environment", () => {
|
|
__setExecImpl(
|
|
() => "XDG_RUNTIME_DIR=/run/user/1001\nDISPLAY=:0\nXAUTHORITY=/run/user/1001/gdm/Xauthority\n"
|
|
);
|
|
assert.deepEqual(desktopEnv(), {
|
|
DISPLAY: ":0",
|
|
XAUTHORITY: "/run/user/1001/gdm/Xauthority",
|
|
XDG_RUNTIME_DIR: "/run/user/1001",
|
|
});
|
|
});
|
|
|
|
it("prefers this process's own value — a checkout run from a terminal has the real one", () => {
|
|
process.env.DISPLAY = ":1";
|
|
__setExecImpl(() => "DISPLAY=:0\n");
|
|
assert.equal(desktopEnv().DISPLAY, ":1");
|
|
});
|
|
|
|
it("forwards nothing when there is no systemd user manager (macOS, a container)", () => {
|
|
__setExecImpl(() => {
|
|
throw new Error("systemctl: not found");
|
|
});
|
|
assert.deepEqual(desktopEnv(), {});
|
|
});
|
|
|
|
it("forwards only the clipboard-related names, never the whole session", () => {
|
|
__setExecImpl(() => "DISPLAY=:0\nSSH_AUTH_SOCK=/tmp/agent\nPATH=/usr/bin\n");
|
|
assert.deepEqual(Object.keys(desktopEnv()), ["DISPLAY"]);
|
|
});
|
|
|
|
it("drops a value carrying a newline — it becomes a tmux -e argv", () => {
|
|
__setExecImpl(() => "");
|
|
process.env.WAYLAND_DISPLAY = "wayland-0\ninjected";
|
|
assert.equal(desktopEnv().WAYLAND_DISPLAY, undefined);
|
|
});
|
|
});
|
|
|
|
describe("canReadClipboard", () => {
|
|
const has =
|
|
(...names) =>
|
|
(n) =>
|
|
names.includes(n) ? `/usr/bin/${n}` : null;
|
|
|
|
it("needs wl-paste for a Wayland display, xclip for an X one", () => {
|
|
const wl = { WAYLAND_DISPLAY: "wayland-0" };
|
|
const x = { DISPLAY: ":0" };
|
|
assert.equal(canReadClipboard({ platform: "linux", env: wl, which: has("wl-paste") }), true);
|
|
assert.equal(canReadClipboard({ platform: "linux", env: wl, which: has("xclip") }), false);
|
|
assert.equal(canReadClipboard({ platform: "linux", env: x, which: has("xclip") }), true);
|
|
assert.equal(canReadClipboard({ platform: "linux", env: x, which: has() }), false);
|
|
});
|
|
|
|
it("is false with no display at all — a headless box", () => {
|
|
assert.equal(
|
|
canReadClipboard({ platform: "linux", env: {}, which: has("xclip", "wl-paste") }),
|
|
false
|
|
);
|
|
});
|
|
|
|
it("is true off Linux, where the clipboard tools are built in", () => {
|
|
assert.equal(canReadClipboard({ platform: "darwin", env: {}, which: has() }), true);
|
|
});
|
|
});
|