fix: per-user Today, native paste and drop on a local machine

- 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.
This commit is contained in:
2026-10-26 11:18:05 +07:00
parent c59e196e41
commit f2f1cd9b6c
33 changed files with 1046 additions and 60 deletions
+65
View File
@@ -161,6 +161,71 @@ const paths = {
},
},
},
"/api/run/clipboard-files": {
post: {
tags: ["Run"],
summary: "The files a file manager's Copy put on this machine's clipboard",
operationId: "runClipboardFiles",
description:
"For a browser on this machine: the files the OS clipboard holds (Windows GetFileDropList, macOS NSPasteboard file URLs, Linux text/uri-list via wl-paste/xclip), each that exists here with its size (`null` for a folder), at most 100 — so a pasted copy is attached by its own path, with no upload and no size limit. The client uses a path only when name and size match the pasted file. 403 EREMOTE in server mode or for any non-loopback (or proxied) request.",
responses: {
200: ok("The clipboard's files; empty when it holds none or no reader is installed.", {
files: {
type: "array",
items: {
type: "object",
properties: {
path: { type: "string" },
size: { type: "integer", nullable: true },
dir: { type: "boolean" },
},
},
},
}),
403: errs("EREMOTE."),
},
},
},
"/api/run/selected-files": {
post: {
tags: ["Run"],
summary: "The files selected in this machine's file manager (what a drag carries)",
operationId: "runSelectedFiles",
description:
"For a browser on this machine: the items selected in Explorer (every window, and the desktop) or Finder — a drag from the file manager carries exactly those — each that exists here with its size (`null` for a folder), at most 100, so a dropped file is attached by its own path with no upload and no size limit. Linux file managers publish no selection: always empty there. Nothing is searched for on disk. 403 EREMOTE in server mode or for any non-loopback (or proxied) request.",
responses: {
200: ok("The selected files; empty when none or no reader is available.", {
files: {
type: "array",
items: {
type: "object",
properties: {
path: { type: "string" },
size: { type: "integer", nullable: true },
dir: { type: "boolean" },
},
},
},
}),
403: errs("EREMOTE."),
},
},
},
"/api/run/native-paste": {
get: {
tags: ["Run"],
summary: "Whether a claude pane can read this machine's clipboard itself",
operationId: "runNativePaste",
description:
"`native`: local mode, a loopback request, and on Linux a reachable display plus `wl-paste` or `xclip` — then the terminal hands a pasted screenshot to `claude` as its image-paste key instead of uploading it. `key`: that chord on this machine — `alt+v` on Windows, `ctrl+v` elsewhere (Claude Code's own bindings).",
responses: {
200: ok("The answer.", {
native: { type: "boolean" },
key: { type: "string", enum: ["ctrl+v", "alt+v"] },
}),
},
},
},
"/api/run/interrupted": {
get: {
tags: ["Run"],