dsh-vps-ops
Read-first VPS operations tools for DeepSeek Harness.
dsh-vps-ops gives your DSH agent a small, explicit toolkit for running a
server: systemd status, disk usage, Docker status, log tails, configured
backups, and quiet-hours schedule checks. Nothing about your host is baked into
the code — every unit, container, backup command, and time window comes from
plugin config.
Read-only by default. Destructive tools refuse in read-only mode, only accept allow-listed targets, and ask the host for approval before running.
Tools
| Tool | Kind | What it does |
|---|---|---|
service_status |
read-only | systemctl state, sub-state, restarts, PID, start time, host uptime, last error journal lines. One configured unit or all of them. |
disk_usage |
read-only | df -h /, inode usage, and the five largest top-level directories under /. |
docker_status |
read-only | Running containers, or docker inspect state/health/restarts for one configured container. |
log_tail |
read-only | journalctl tail for a configured unit, or the tail of an absolute file inside the configured log directories. Max 200 lines. |
quiet_hours_status |
read-only | Pure schedule calculation: lists the windows and says whether now is inside one. Starts and stops nothing. |
service_action |
destructive | `systemctl start |
backup_run |
destructive | Runs one operator-configured backup command, after approval. |
Install
dsh plugin --profile web add dsh-vps-ops
systemctl restart dsh-web # or restart your DSH process
Then allow-list your host's units in the profile's cordis.patch.yml:
- id: vps-ops
config:
services:
- label: DSH Web
unit: dsh-web
- label: OpenBot
unit: openbot
containers:
- label: OpenViking
name: openviking
backups:
- id: openviking-daily
label: OpenViking backup
command: ['/usr/local/bin/openviking-backup.sh']
timeoutMs: 120000
quietHours:
timeZone: UTC
windows:
- 'Mon-Fri 01:00-04:00'
- 'Mon-Fri 06:00-10:00'
logs:
dirs: ['/var/log']
safety:
readOnly: false
requireApproval: true
timeoutMs: 15000
maxOutputBytes: 65536
Without a config block the plugin still boots and only reports that nothing is configured.
Configuration
| Key | Default | Meaning |
|---|---|---|
services |
[] |
{ label, unit } allow-list of systemd units. |
containers |
[] |
{ label, name } allow-list of Docker containers. |
backups |
[] |
{ id, label, command, timeoutMs }; command is an argv array (preferred) or a shell string. |
quietHours.timeZone |
UTC |
IANA zone used to evaluate the windows. |
quietHours.windows |
[] |
"<days> HH:MM-HH:MM"; day ranges may wrap (Fri-Mon) and a window whose end precedes its start crosses midnight. |
logs.dirs |
["/var/log"] |
Directories log_tail may read files from. |
audit.file |
<DSH_HOME>/logs/vps-ops-audit.log |
Where approved operations are recorded. |
safety.readOnly |
true |
When true, service_action and backup_run refuse. |
safety.requireApproval |
true |
When true, destructive tools ask the host first. |
safety.timeoutMs |
15000 |
Default command timeout. |
safety.maxOutputBytes |
65536 |
Output cap per call. |
Safety model
- No shell interpolation of model input. Commands are executed as an
executable plus an argv array. Names are validated before they reach an argv
slot, which also blocks option injection such as a unit called
--help. - Allow-lists only.
service_action,docker_status <container>,log_tail <unit>, andbackup_runaccept only configured names. - Files stay in the log directories.
log_tail <file>resolves symlinks and refuses anything outsidelogs.dirs. - Bounded work. Every command has a wall-clock timeout and a stdout/stderr byte cap; runaway output kills the child.
- No secret plumbing. Children get a minimal environment, and no tool reads or forwards credentials.
- Fail-closed approval. A missing or throwing approval answerer means the operation does not run.
- One audit line per approved operation, as JSON on a single line.
Requirements
- DSH
>= 0.2.1-rc.4(Node^22.19.0 || >=24.0.0). systemctl/journalctlfor the systemd tools,dockerfor the Docker tool. Missing binaries are reported as tool output, not as crashes.
Development
node --test
The suite covers window parsing and evaluation, argv building, UTF-8 safe output truncation, output parsers, and the destructive-operation gate (read-only refusal, rejected approval, missing answerer, approved execution, audit line).
License
MIT
No comments yet. Be the first to write one.