Repository navigation
Releases: taxah92/dsh-pve-vm
Release list
dsh-pve-vm 0.2.5 — SPICE VMs: the first frame and the clipboard
dsh-pve-vm 0.2.5 — SPICE VMs: the first frame and the clipboard
This release makes the plugin work with SPICE/QXL virtual machines — the ones Proxmox starts with
vga: qxl and a SPICE client — and removes a way to wedge the QEMU guest agent.
Fixed
- The first frame of a QXL/SPICE VM could come out blank. On guests with a hardware cursor QEMU
sends a “cursor only” update before the full frame, and the firstwaitForUpdatesometimes ended
exactly there:console_shotand the “VM screen” panel returned a white frame. A new
RfbClient.waitForFrame()keeps reading until an update carries a real rectangle, console captures
use it, and the panel allows the first frame of a session up to 1.5 s (FIRST_FRAME_WAIT_MS).
Reproduced on a 3440x1336 guest: the blank update arrived first, the real frame 79–300 ms later. - The clipboard did not work on SPICE VMs at all.
console_pasteandconsole_clipboardrequired
vga: <type>,clipboard=vncplus a SPICE agent, which is impossible onvga: qxl: the
com.redhat.spice.0channel is taken byspicevmc, and enablingclipboard=vncthere would remove
the SPICE agent (dynamic resolution and your SPICE clipboard). Both tools now use the guest agent
first — on Windows a scheduled task in the logged-in user session (the clipboard is per-session;
SYSTEM in session 0 cannot see it), on Linuxxsel/xclip/wl-copy/wl-pastein the active
graphical session. The VNC clipboard stays as a fallback when the VM hasclipboard=vnc. A
logged-in session is required: there is no clipboard on the logon screen. - Non-ASCII in a guest
argvcould wedge the guest agent. PVE truncates non-ASCII QMP payloads
(Proxmox #6609), soqm guest exectimed out
andqemu-gastayed stuck until its service was restarted. The controller now refuses such an
argvbefore anything is sent (NON_ASCII_ARGV) and points at stdin/base64 envelopes.
Changed
typeTextArgvpasses the guest script via base64, so aguestTypeCommandwith non-ASCII text
no longer travels inargv.console_pasteandconsole_clipboardtimeouts were raised for the task round trip, and the
clipboard result gainedchannelandtruncated.- The default Linux input script now picks the first active graphical session (filters by session
typex11/wayland/mir), fixing “No protocol specified” on guests whereloginctlreports an
emptyDisplayfor an X11 session.
Verification
npm run check,check-clientandcheck-pluginon the publication: no problems, 16 tools.- Live acceptance on Proxmox VE 8.4: SPICE/QXL Windows 11 guest, Windows Server 2025 guest and a
RedOS 8 / MATE guest — frames arrive, Cyrillic text pastes into Notepad through the guest channel,
and the Linux clipboard round trip (get → set → read → restore) matches. - The npm tarball (30 files) is the checked artifact: the registry
shasumequals the local
npm packsha1 (a2100f1d98e8da24e29e1a9cf6d26209fdc0d53b), and the release asset is the tarball
downloaded from the registry.
Install
dsh plugin --profile web add dsh-pve-vm
# or straight from the repository:
dsh plugin --profile web add github:taxah92/dsh-pve-vmFull changelog: CHANGELOG.md
dsh-pve-vm 0.2.4 — Simplified Chinese translation
dsh-pve-vm 0.2.4 — Simplified Chinese translation
Added
- The web UI now speaks Simplified Chinese (
zh). The settings card and the “VM screen” sidebar
panel are translated; DeepSeek Harness ships thezhlocale, so the plugin follows it exactly like
it already followedenandru. Missing keys would fall back to English, but there are none —
tools/check-client.mjsnow fails when a locale lacks a key or a{placeholder}differs between
dictionaries. - The plugin card in Settings ▸ Plugins reads Chinese.
locale/zh.jsonjoins the existing
en/rumetadata files, in the samemetashape the panel already reads.
Chinese labels cover the whole contribution: the settings section (19 fields with hints), the status
line, the screen panel controls and every state banner, and the tab title/guide.
Verification
check-clientandcheck-pluginon the publication: no problems, 16 tools.- The three dictionaries (
ru,en,zh) have identical key sets (70 keys each) and identical
{vmid}/{resolution}/{capture}/{pointer}/{kb}/{message}placeholders. The new
gate was verified negatively: removingview.pausedand dropping{vmid}fromview.status
produces exactly those two reports. - The npm tarball (30 files) contains
locale/zh.jsonand the Chinesezh:block inclient.js;
the registryshasumequals the localnpm packsha1.
No host-side code changed — the host half still runs the 0.2.2 guest-channel code unchanged.
Install
dsh plugin --profile web add dsh-pve-vm
# or straight from the repository:
dsh plugin --profile web add github:taxah92/dsh-pve-vmFull changelog: CHANGELOG.md
dsh-pve-vm 0.2.3 — packaging fix: the npm tarball was missing tools/
dsh-pve-vm 0.2.3 — packaging fix
What was broken
index.js imports ./tools/console.js and ./tools/guest.js — the definitions of all 16 tools —
but the files list in package.json never included that directory. The published npm tarball
therefore could not be imported at all:
dsh plugin --profile web add dsh-pve-vm
→ ERR_MODULE_NOT_FOUND: Cannot find module '…/dsh-pve-vm/tools/console.js'
Every release up to and including 0.2.2 was affected. Installing straight from the repository
(dsh plugin --profile web add github:taxah92/dsh-pve-vm) was not affected — that path uses the
repository itself, where tools/ has always been present.
Fixed
filesnow includestools/.- The two-copy gate in the development workspace (
tools/sync-pve-vm.mjs) checks that every relative
import of the packed tree resolves inside the package. Verified against the old list: it reports
exactlyindex.js → ./tools/console.jsandindex.js → ./tools/guest.js.
No runtime code changed since 0.2.2 — the guest-channel work (request markers, file-length checks,
OEM/ANSI decoding, 1 MiB writes, honest timeouts) is all in 0.2.2 and carried over unchanged.
Verification
- A local
npm packof 0.2.3 containstools/console.jsandtools/guest.js; importing the packed
tree with the real peer packages succeeds (Config, apply, inject, name), and all 24 relative
imports resolve. check-plugin/check-clienton the publication: 16 tools, no problems.
Install
dsh plugin --profile web add dsh-pve-vm
# or straight from the repository:
dsh plugin --profile web add github:taxah92/dsh-pve-vmFull changelog: CHANGELOG.md
dsh-pve-vm 0.2.2 — the guest channel made reliable
dsh-pve-vm 0.2.2 — the guest channel made reliable
Found by running the plugin against a real Windows guest (Windows Server 2025, 4 GB RAM), not by
reading code: a live 19-check suite went from failing somewhere on every run to green.
Fixed
- A non-ASCII
commandcould wedge the guest agent untilQEMU-GAwas restarted. The fault is
in Proxmox, notqemu-ga: non-ASCII QMP payloads are truncated by one byte per character
(#6609). A Windowscommandnow travels as a
base64 envelope;argvwith non-ASCII is refused before anything is sent
(UNICODE_ARGV_WINDOWS). - Russian output came back as mojibake. PVE puts guest bytes into JSON as latin-1 and a Windows
console writes in its OEM code page; output is now decoded from bytes with the code page cached
per VM. Messages ofcmd.exeitself arrive in the system ANSI code page even whenchcpreports
OEM, so the decoder tries both and keeps the readable one. - Commands longer than 30 s reported a false failure.
qm guest execwaits 30 s and returns a
pid withoutexited; the plugin now passes--timeoutand reportsSTILL_RUNNINGwith the pid
instead ofexitcode -1. vm_file_writeworked only up to ~8 KB. File data now goes over stdin (--pass-stdin), which
raises the limit to 1 MiB per call.vm_file_readbroke the QGA channel at 1 MiB. Files are read in 256 KiB chunks with an offset,
and a chunk is retried (reading is idempotent).- A successful but short or foreign agent reply could silently corrupt a result.
qemu-ga
reuses pids, and the tail of an earlier command can arrive as the answer to a new one. Every read
script and the non-ASCII command envelope now carry a per-call request marker and the real file
length; a reply that does not match is retried, and if it still does not add up the tool fails
instead of quietly returning an incomplete or foreign result. - PowerShell progress noise (CLIXML) no longer replaces error texts — every generated script
starts with$ProgressPreference='SilentlyContinue'.
Changed
- All
qmcalls to one VM are serialised with a 250 ms gap: QEMU serves one QMP client at a time,
and back-to-back calls used to steal each other's replies. - A failed call is retried exactly once, and only when PVE answers “agent is not running” — that
check runs before the command is sent, so the retry cannot execute anything twice. vm_statusexplains how to recover a wedged guest agent; tool descriptions state the real limits.
Notes
- A command that outlives
timeoutMskeeps running in the guest — the tool reports
STILL_RUNNINGwith the pid instead of pretending it failed. - Residual PVE/QMP flakiness on a busy guest is not a plugin bug: on mixed load one call in ~20 can
still hit the five-second QMP timeout, andqemu-gacan hand back an earlier command's output when
Windows reuses a pid. File reads and non-ASCII commands now detect and retry that; a plain
vm_exechas nothing to check its output against.
Install
dsh plugin --profile web add dsh-pve-vm
# or straight from the repository:
dsh plugin --profile web add github:taxah92/dsh-pve-vmFull changelog: CHANGELOG.md
dsh-pve-vm 0.2.1 — Russian plugin card
The plugin card in the panel is now localized — and it finally shows its own title instead of the package name.
Fixed
locale/en.jsonandlocale/ru.jsonwere written in a format the panel never reads. The
reader (readPluginMetaindsh-app-boot) takes display text from ametaobject —
{"meta": {"title": …, "description": …}}— and silently drops a flat{title, description}file.
Both files were flat, so the card in the plugin inventory showed the package namedsh-pve-vmand
the manifest description; the Russian text never appeared anywhere. Wrapped inmeta: the card now
reads “Proxmox VE VM control” / “Управление ВМ Proxmox VE” and follows the panel language.
Checks
tools/check-plugin.mjsverifies the card metadata: themetashape of everylocale/*.json,
field parity between the languages, and — through the installed harness — thatreadPluginMeta
answers with a translation map rather than the package-name fallback.
Registry sha1 ee7c24afb201947f4d47c90c32f9561e63b28ecb is identical to a local npm pack;
the attached tarball is the one the registry serves. Install with
dsh plugin --profile web add dsh-pve-vm.
dsh-pve-vm 0.2.0 — live VM screen in the right sidebar
Watch the agent work: a live VM screen in the right sidebar of the harness web UI.
Added
- The “VM screen” tab. A right-sidebar panel that streams the frames the agent sees.
The frames come from the agent's own RFB session, so no second VNC session appears and
theqm vncproxypassword is never reset under the agent's feet. Captures and tools share
one session queue, so they never tear the stream for each other. The panel is watch-only by
design: nothing is injected into the guest. viewAutoOpen(off by default) — reveal the tab by itself when the agent touches a console.viewFollowAgent(on by default) — the panel follows the VM the agent works with; a VM chip
pins it by hand. Watching never counts as agent work, so the panel cannot chase itself.viewFps(2) andviewScale(2) — frame pace and resolution divisor, both changeable
on the fly inside the panel.- Host routes
/pve-vm/console/state,/frameand/releaseon the harness web server,
registered only when the composition has awebServer. They carry a loopback-only fence: the
Hostmust be loopback, a presentOriginmust match it,sec-fetch-site: cross-siteis
refused, and POST must beapplication/json. RfbClient.waitForUpdate({ idleOk: true })— silence at a message boundary means “the screen did
not change” instead of an error, while a timeout inside a message stays fatal.
Fixed
inputChannelandsendkeyDelayMsnever reached the tools. Both keys were missing from
CONFIG_KEYS, sosnapshot()dropped them and every run silently used the built-inauto/80 ms
defaults: the settings form accepted the values, the code ignored them.
Verified
node tools/check-plugin.mjs— route inventory and fence (foreign Host, foreign Origin,
cross-site and non-JSON POST all answer 403).node tools/check-client.mjs— tab type, both sidebar seats, key, dictionary, declared
ctx.inject(['sidebarRight', 'sidebarRightTabs']).node tools/view-test.mjsagainst a live VM: a real HTTP server,state200, a genuine PNG frame
(1280×800 at half scale), ~1.2 s for the first frame and ~0.26 s incremental,releaseclosing
the session, and the check that watching leaves no agent-activity mark.
dsh-pve-vm 0.1.1 — Linux guest fixes
Linux guest support. Four defects that made the guest-agent half unusable on Linux — all found by
installing the plugin against a real RedOS 8 guest with a MATE desktop, not by reading the code.
Fixed
- Guest OS detection rejected almost every Linux distribution. The guest agent reports
id
from/etc/os-release, and only IDs containinglinuxwere accepted — RedOS reportsredos,
Debiandebian, Ubuntuubuntu. All of them landed inother, so everyvm_*tool answered
running a shell command is not supported for guest OS «other». Windows was unaffected
(mswindows), which is why it went unnoticed. vm_type_texttyped nothing on a GDM desktop. The built-in typing script used
$HOME/.Xauthority, which does not exist when GDM owns the session — RedOS and RHEL keep the file
at/run/user/<uid>/gdm/Xauthority.xdotoolthen talked to the X server with no authorization,
failed with No protocol specified, and the text never appeared.vm_type_textcould not submit text.text=$(… | base64 -d)— command substitution strips
trailing newlines, so text ending in"\n"was typed without pressing Enter and the shell prompt
never came back.- Console errors hid the actual cause. When the node's
sshddoes not acceptAcceptEnv,
LC_PVE_TICKETnever arrives andqm vncproxyexits with a precise
LC_PVE_TICKET not set, VNC proxy without password is forbidden — but the RFB reader saw EOF
before ssh had finished exiting, so only the VNC stream was closed by the node surfaced.
Install: dsh plugin --profile web add dsh-pve-vm (or github:taxah92/dsh-pve-vm) — then enable
the bundle in the profile and restart the harness.
See README.md for requirements (root ssh,
AcceptEnv LC_*, guest agent) and CHANGELOG.md
for details, including the known 5-second QMP timeout on long guest commands.
dsh-pve-vm 0.1.0 — first public release
Proxmox VE VM control for DeepSeek Harness: 11 console tools (VNC/RFB: frame, pointer, keyboard, batch, Unicode clipboard) plus 5 guest-agent tools, over a single ssh connection, with zero runtime dependencies.
Install: dsh plugin --profile web add github:taxah92/dsh-pve-vm — then enable the bundle in the profile and restart the harness.
See README.md for requirements (root ssh, AcceptEnv LC_*, guest agent) and CHANGELOG.md for details.