Files
LocalAI/addons/pikvm/ui/test/settings.test.mjs
T
Ettore Di Giacinto bab8a605cc feat(addons): add the PiKVM add-on
Chats and agents can check a PiKVM (kvmd) device and, when a person
confirms each call, press the power buttons of the machine it controls
and use its keyboard.

Read tools: get-info (model, versions, no serial or host name),
get-power-state (ATX LEDs) and get-keyboard-state. Write tools:
power-action (on, off, reset; off_hard, reset_hard and long_press only
with a per-device switch), type-text (bounded, no control characters,
refuses key, token and password-list shapes) and send-key (a short
allowlist, no Windows or Meta chords). All three declare approval
always. The preview reads the power state; apply reads it again and
rejects a stale operation. The add-on journals before it sends, never
retries and reports unknown when the connection drops.

One connection is one device: the address is the single resource of the
connection and the one sealed credential holds user:password, split at
the first colon. A one-time code is not supported. The add-on speaks
only to that address, refuses redirects, uses no proxy and accepts a
self-signed certificate only through a #sha256= pin in the address.
Typing, the text length and hard power actions are per-device switches
that an administrator sets on the add-on page; all start off. Snapshots,
mass storage, GPIO and the mouse are left out.

The add-on ships a skill, a connection page with a Test button and
approval cards, the package files, the library entry and the docs, and
joins the package workflow and the case inventory.

PiKVM API reference: https://docs.pikvm.org/api/

Assisted-by: Claude:claude-sonnet-5-5 go node
2026-11-04 17:20:57 +00:00

21 lines
1.2 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { draftOf, draftProblem, same, valuesOf, DEFAULT_CHARS } from '../src/settings.js'
test('pikvm settings: a device with no saved switches is off and short', () => {
assert.deepEqual(draftOf(undefined), { allowTyping: false, allowHardPower: false, maxTypeChars: String(DEFAULT_CHARS) })
assert.deepEqual(draftOf({ allowTyping: true, allowHardPower: 'yes', maxTypeChars: 300 }), { allowTyping: true, allowHardPower: false, maxTypeChars: '300' })
})
test('pikvm settings: the length is a whole number from 1 to 1000', () => {
for (const ok of ['1', '200', '1000']) assert.equal(draftProblem({ maxTypeChars: ok }), '')
for (const bad of ['0', '1001', '-3', '1.5', '', 'abc']) assert.equal(draftProblem({ maxTypeChars: bad }), 'settings.maxCharsShape', bad)
})
test('pikvm settings: a draft is dirty only when something differs, and sends numbers', () => {
const a = draftOf({ allowTyping: true, maxTypeChars: 200 })
assert.equal(same(a, draftOf({ allowTyping: true, maxTypeChars: 200 })), true)
assert.equal(same(a, { ...a, allowHardPower: true }), false)
assert.deepEqual(valuesOf({ ...a, maxTypeChars: '350' }), { allowTyping: true, allowHardPower: false, maxTypeChars: 350 })
})