Unraid 7's React CSS overrides line-height: 1.5 on textareas to normal.
vvRestoreEditorPrefs() only called vvFontSize() for non-default sizes, so
the inline style that overrides Unraid's CSS was never set for the default
12px case — leaving Firefox to render at ~14px while our code calculated
positions at 18px, putting the cursor 2-3 lines above where clicked.
Now always calls vvFontSize() so the inline lineHeight is always forced.
- Auth stack: fold cert monitor into Auth Stack page as fourth tab (Certs);
remove standalone cert page and top-level tab
- cert_monitor.sh: write JSON status cache to State_Files/cert_status.json
after each run; expose per-domain days/expiry via _CERT_DAYS/_CERT_EXPIRY globals
- api/cert.php: new — serves cached cert status; falls back to configured
domains as UNKN when no cache exists; POST action=run triggers live check
- arrs db fallbacks: vv_arr_cleanup_stats/discovery_stats/recovery_stats now
read from data/*.db files when log JSON files don't yet exist
- config.php vv_conf_vars(): unescape bash \$ → $ so passwords with dollar
signs read correctly from conf files
- host1.conf: fill in HOST1_NPM_USER/PASS and HOST1_LLDAP_USER/PASS
- Partnership adapter pattern: Unraid-specific container logic extracted to
Plugin/unraid/Partnership/; platform-agnostic structure stays in Partnership/
- First-run wizard: uniform multi-step flow for all hosts; HOST2 pull moved
to checklist; auto SSH keygen and API key creation on save
- api/checklist.php: live setup checklist with pull_master action
- Fullscreen toggle: hide Unraid header/menu; state persists via localStorage
Adds a "Wrap" button to the editor status bar that toggles word wrap
on/off, persisted in localStorage. Default is nowrap with horizontal
scroll (standard code editor behaviour). In wrap mode the line-number
gutter and current-line highlight are hidden — both rely on fixed
line-height calculations that break when lines wrap visually.
CSS: textarea/overlay default to white-space:pre; .vv-ed-wrap class
(on #vv-editor-wrap) overrides to pre-wrap, hides gutter and cur-line.
JS: vvWordWrap state, vvApplyWordWrap(), vvToggleWordWrap(); guards in
vvUpdateLineNums() and vvUpdateCurLine(); restored via
vvRestoreEditorPrefs() on both script and raw-conf editor entry points.
Find & Replace (Ctrl+H):
- Two-row find bar: expand › arrow shows replace row (VS Code pattern)
- Replace button (Enter): replaces current match, advances to next
- Replace All: replaces all occurrences, shows count
- Find input searches live; replace row preserved across open/close
Multi-line comment toggle (Ctrl+/):
- With multi-line selection: checks if ALL lines are commented
→ if all commented, uncomments all; otherwise comments all
- Empty lines in selection are skipped
- After toggle: block stays selected (same as VS Code)
- Single-line behavior unchanged
Indent guides:
- CSS repeating-linear-gradient on #vv-editor-inner: 1px guide every 2ch
- First guide at indent level 1 (col 2); then 4, 6, 8... matching 2-space indents
- Shows through the transparent overlay; scales automatically with font size
- Very subtle (0.045 opacity) — visible but not distracting
Font size A− / A+ in status bar (9–22px):
- Persisted to localStorage, restored on every editor open
- Updates textarea, overlay, gutter, and cur-line height together
- All scroll calculations use vvLH() (fontSizePx × 1.5) instead of
hardcoded 18 — find nav, goto, select-next-occurrence all correct at
any font size
Also: fixed duplicate id="vv-find-close" in goto bar (now .vv-find-x class)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Line operations:
- Alt+↑/↓ — move current line up / down (swaps with adjacent line)
- Alt+Shift+↓/↑ — duplicate line below / above
- Ctrl+Shift+K — delete current line
- Ctrl+L — select entire current line (including newline)
Auto-close brackets and quotes:
- ( [ { " ' ` — inserts matching close, cursor placed inside
- Wrap selection — if text is selected, typing an opener wraps it
- Skip-over — typing a close char when it's already next → jumps past it
- Smart backspace — deletes BOTH chars when cursor sits between a matched pair
- Guards: skip ' auto-close after word chars (contractions); skip auto-close
when next char is a word char (prevents disrupting existing text)
Navigation:
- Ctrl+G — Go to Line bar (pre-filled with current line, shows "of N")
- Smart Home — first press → first non-whitespace; second → col 0
- Ctrl+D — first press: select word at cursor; subsequent: cycle through
all occurrences (wraps around), integrates with word highlight overlay
Keyboard shortcuts panel:
- Added "Editor Keyboard Shortcuts" section to the How do I use this panel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Native browser undo breaks when ta.value is set programmatically (tab,
enter, ctrl+/) — replaced with a custom snapshot-based undo system.
Stack behaviour:
- oninput → debounced capture (600ms) — groups rapid typing into chunks
- Tab / Enter / Ctrl+/ → immediate capture BEFORE edit, then capture AFTER
(each programmatic edit gets its own undo step)
- Content load → vvUndoCaptureInitial() seeds the stack with a clean baseline
- Max 200 history entries (VV_UNDO_MAX); old entries dropped from front
Keyboard: Ctrl/Cmd+Z = undo, Ctrl/Cmd+Y or Ctrl/Cmd+Shift+Z = redo
(both handled in vvEditorKeydown before any other key processing)
Buttons: ↩ Undo / ↪ Redo appear in toolbar beside Cancel/Save when editor
is open; disabled state with 0.28 opacity when no steps available; Undo
button shows step count "↩ Undo 5" so you can see how deep the history is
Cleanup: vvEditorReset() calls vvUndoReset() so stack is cleared on every
editor open/close — fresh baseline each time
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Selection:
- ::selection fix: text selection now visible (bright blue) even when
textarea color is transparent — the #1 complaint
- Overlay background changed transparent → #vv-editor-inner provides bg,
allowing #vv-cur-line to show through
Current line highlight:
- #vv-cur-line div positioned absolutely behind overlay, tracks cursor
line on every keyup/mouseup/click/scroll
- Gutter: current line number highlighted in bright white + bold
Word/variable occurrence highlight:
- Click or position cursor on any identifier → all occurrences highlighted
in yellow throughout the overlay (whole-word, case-sensitive)
- Select a word → same treatment for the selection text
- Clears when cursor moves off the word or find bar opens
Find in file (Ctrl+F):
- Find bar slides in above editor, pre-filled with selected word
- Highlights all matches orange, current match in bright amber
- ↑/↓ buttons + Enter/Shift+Enter to navigate between matches
- Live match count "N / M"
- Red border + "no matches" feedback when term not found
- Escape or × closes, returns focus to editor
Status bar:
- Persistent bar below editor: Ln N, Col N | selection info | language
- Shows "Bash" or "Bash / Config" depending on file type
- Hides when editor is not open
Visual polish:
- Editor wrap: unified border + border-radius 4px 4px 0 0, overflow:hidden
clips gutter and inner to rounded corners as one block
- Status bar border-radius 0 0 4px 4px — completes the block
- Gutter: 46px (was 42) — room for 3-digit line numbers
- Slim 8px scrollbar with styled track and hover state
- vvEditorReset() clears all editor state on open/close
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Selection / highlight:
- .vv-row-selected: blue tint + left accent bar (was barely-visible gray)
- .vv-sb-selected: same treatment, consistent across both panels
- .vv-df-active (containers): match new selection style
- .vv-job-row + .vv-sb-row: smooth transition on state changes
- .vv-orch-row: hover feedback + pointer cursor (was no visual response)
Drag and drop:
- .vv-drag-ghost: adds dashed ring so source item stays visible while dragging
- .vv-drop-line: blue glow to match selection accent (was flat green)
- All drop targets: unified blue theme (.vv-children, .vv-folder-children)
- .vv-library-zone drop target: improved red with inset glow
- .vv-drag-handle:active: grabbing cursor state
- document.body.vv-is-dragging: cursor:grabbing on entire page during drag
(added to all three drag start handlers + failsafe document dragend)
Keyboard navigation (scheduler):
- ↑/↓: navigate between top-level orchestrator cards
- Home/End: jump to first/last card
- Escape: close right panel, return to suggestions
- /: focus log search when log panel is open
- All shortcuts suppressed when focus is in any input/textarea/select
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Move SCRIPTS_DIR/DATA_DIR/STATE_DIR from appdata to /boot/config/plugins/varaverk
- All state files now in STATE_DIR (no more /tmp or /boot/config root writes)
- Bootstrap: Gitea-first clone with GitHub fallback, no array dependency
- varaverk.cfg seeded with Gitea connection settings
- .gitignore: add State_Files/, varaverk.cfg, varaverk-*.txz
- Partnership/transcode/fallback scripts use STATE_DIR variables
- PHP config.php: DATA_DIR/STATE_DIR constants, VV_SETUP_STATE_FILE dynamic
- deploy.sh PROD_ROOT updated to plugin flash dir
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix 1 — Monitor partner card (common.php + monitor.php):
vv_remote_hosts_stats() no longer skips hosts with no API key.
Returns no_api_key:true entry instead. Monitor JS renders
"API key not configured — complete Onboard to enable" instead
of a blank space.
Fix 2 — rawconf push not alarming pre-onboard (config.php + scheduler.php):
Probe failures (Tailscale not found, plugin not installed) now carry
ready:false. JS treats ready:false results silently — button shows
"✓ Saved" not "push failed: HOST2" before SSH is set up.
Only genuine post-onboard failures (ready not false) show as errors.
Fix 3 — Partnership Onboard button (partnership.php):
Disabled with tooltip when no partner hostname is in master.conf.
When partner configured but not onboarded, adds explanation note:
"Onboard will generate your SSH key, exchange it with the partner..."
No partner configured: "Edit master.conf and set HOST2."
scheduler.php: after host1.conf save in setup mode, redirect to
?tab=partnership&vv_onboard=1 instead of Monitor.
HOST2+ still redirects to Monitor (they don't manage the partnership).
partnership.php: detects vv_onboard=1 URL param after actions render.
Adds pulse animation + box-shadow to the Onboard button and scrolls
it into view. One-shot — gone when user navigates away.
Varaverk.page: also shows wizard when local host.conf is missing
(handles master.conf pushed by HOST1 before HOST2 installs plugin).
pages/setup.php: three wizard flows
- Standard: blank master.conf, fill hostnames, redirect to scheduler
- Host2/state file: state file detected, pull master.conf from HOST1 via SSH
- Conf-only: master.conf already filled (was pushed), just create local host.conf
api/setup.php:
- save action: writes master.conf + host.conf, creates varaverk_setup.db state file,
redirects to ?tab=scheduler&vv_setup=master.conf
- pull action: resolves HOST1 Tailscale IP, queries HOST1 SCRIPTS_DIR, SCPs
master.conf, creates local host.conf, redirects to ?tab=scheduler&vv_setup=hostN.conf
include/config.php: vv_setup_state_read/write/push helpers.
vv_push_setup_state() pushes varaverk_setup.db to /boot/config/ on all known
remotes — no plugin-readiness probe needed (flash is always accessible).
api/rawconf.php: calls vv_push_setup_state() alongside master.conf push.
pages/scheduler.php: setup mode via ?vv_setup=<conf> URL param.
Auto-opens the specified conf file on page load (DOMContentLoaded).
vvSaveRawConf: in setup mode, skips confirm dialog and forces sequence:
master.conf save → auto-open hostN.conf
hostN.conf save → redirect to Monitor (setup complete)
vv_push_master_conf() in config.php: finds all remote HOST* entries,
resolves Tailscale IPs, SCPs master.conf to each.
rawconf.php calls it after a successful write when file=master.conf.
Scheduler save button shows sync status: "✓ Saved · synced to HOST2"
or "✓ Saved · push failed: HOST2" on error.
Also fix path bug in partnership_transfer.sh — was SCPing to
appdata root instead of Configurations/.
VaraverkSettings.page (Settings → Other Settings) now owns SCRIPTS_DIR.
The inline Advanced-mode field and vvSaveSettings() in the Scheduler tab
were a second path to the same write — removed.
- Tools and Custom: args input always visible (translucent at rest, full on hover)
- Orch children: args input hidden when orch is on, shown when orch is off
(same toggle as the cron field — orch off = standalone mode)
- vvRunJob/vvDryRun: pick up .vv-script-args value, POST as extra_args
- run.php / dryrun.php: accept extra_args, validate against shell metacharacters,
append to run_job.sh invocation (flows through SCRIPT_ARGS to the script)
- CSS: .vv-script-args — 30% opacity at rest, 100% on hover/focus
PHP architecture:
- Extract common.php from monitor.php — shared system functions (vv_system_info,
vv_memory_breakdown, vv_remote_hosts_stats, disk/GPU/UPS/network/docker/parity, etc.)
now live in one place; monitor.php and watchdog.php both require common.php
- Add unraid_api.php as explicit include (was implicit via config.php chain)
- confform.php: add missing require_once config.php (implicit dep made explicit)
- Delete orphaned pages/docs.php and pages/config.php (absorbed into scheduler)
Watchdog page:
- Add Storage watchdog card (growth + log strikes, baseline age, suppress ceilings)
- Add Network watchdog card (NPM strikes, DDNS domain/container, NPM URL)
- One host per row layout — all 5 watchdog cards equally spaced via inner grid
- Watchdog now uses Unraid API for local system stats; remote nodes with API key
but no SSH get system info from vv_remote_hosts_stats() with api_only flag
- SSH bundle: /proc/meminfo passed as raw section instead of awk-parsed header
fields — fixes RAM showing 0 on remote hosts where awk quoting was unreliable
- vv_wd_local_system() rewritten as thin wrapper over vv_system_info() + vv_memory_breakdown()
Monitor page:
- Watchdog card: add stability strikes, storage watchdog strikes, network NPM status,
live system stats (rootfs/log/tmp %, RAM free, load, CPU temp, zombies, NIC, sshd)
- Row height: switch from max-height on cards to minmax(0, calc(...)) on grid track —
all cards in a row now fill to the tallest card's height correctly (fixes Pools card
being shorter than neighbours)
Scheduler page:
- Add Tools section above Custom Scripts — lists Tools/*.sh with run/dry-run/cron/log
- vv_tools_scripts() function in scheduler.php include
Tools:
- Add docker_prune_images.sh — removes dangling Docker images; --dry-run and --status modes