Default behavior is now setup-only (symlinks + binary, no interactive launch)
so array_started.sh can call it directly without arguments. Use --launch to
start an interactive Claude session.
Remote functions (_remote_arr_up, _remote_library, _remote_defaults,
_remote_add, _delete_remote_item) now check ${node_id}_<ARR>_API_KEY
from the environment first. When found (conf cache populated by
conf_sync.sh + load_config.sh sourcing /tmp/.vv/), they call the arr
API directly over Tailscale — no SSH connection needed.
SSH fallback (grep config.xml + localhost API) remains for the first
boot before conf_sync has run or when the partner is offline.
config_xml is no longer passed between functions — computed internally
in the SSH path only. Call sites in _sync_arr and blocklist-add updated
accordingly.
conf_sync.sh has always populated /tmp/.vv/config/cached/.confs/ with
partner host*.conf files pulled via SCP, but load_config.sh never read
from it — leaving HOST2_* vars undefined on HOST1 and vice versa.
After the disk host*.conf loop, source any cached conf whose basename
wasn't already loaded from disk. Disk copy always wins (authoritative);
cache supplies partner vars that sparse checkout intentionally withholds.
Cache is tmpfs, cleared on reboot, repopulated by conf_sync.sh on array
start.
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.
common.sh gains:
- docker_cmd() + verify_running() + retry_docker() — removed from all 3 Docker_Essentials
scripts where they were byte-for-byte duplicates
- emby_api(endpoint, [timeout=30]) — removed from 6 Media/Tools scripts that each defined
their own _emby_api() with the same curl/parse/error pattern; call sites renamed emby_api
- format_duration() extended with days/hours branch (was capped at minutes+seconds)
- notify() comment: scripts do not need to preflight the notify script via validate_unraid_cmd
Tailscale deduplication:
- arr_sync.sh: _resolve_node_ip() and inline block in _delete_remote_item() both replaced
with resolve_tailscale_ip() from common.sh
- git_pull_execute.sh: inline tailscale ip -4 replaced with resolve_tailscale_ip() (adds
the tailscale status fallback that was missing)
- ARRAY_START_SCRIPTS: add api_cache_writer.sh so monitor/arrs cache is populated
immediately on array start (/tmp is tmpfs — cleared on reboot, so first-boot
load was hitting live API for up to 60 seconds until the cron fired)
- api/monitor.php + arrs.php: raise cache TTL from 90s to 300s — stale-but-instant
beats a 6-second live API wait if the writer is momentarily behind
- include/unraid_api.php: replace last inline uptime formatter with vv_format_uptime()
Consolidations (config.php gains 5 shared utilities):
- vv_format_uptime() replaces 4 inline uptime-formatting blocks
- vv_parse_conf_scalar() replaces vv_arr_scalar/vv_wd_scalar/vv_fb_scalar/vv_media_conf_scalar
- vv_known_hosts() replaces vv_arr_known_hosts/vv_fb_known_hosts + inline parser in watchdog
- vv_parse_kv_db() replaces inline key=value parsing in snapshot and monitor
- vv_local_ip() replaces duplicate in docker_folders.php and inline in docker.php
All module-level function names kept as thin aliases so call sites unchanged.
Critical bug fixes:
- api/system.php: added require_once config.php and POST-only guard (no auth on shutdown)
- api/movescript.php + reorderarray.php: use vv_write_conf_raw (atomic) + vv_push_master_conf
- api/snapshot.php: share /tmp/vv_cpu_stat.json with vv_cpu_per_core() instead of own state file
Correctness:
- vv_cpu_per_core() and vv_network_stats(): atomic tmp+rename for state files (concurrent poll safety)
- ext_ip curl cache moved from /tmp/vv_ext_ip.cache to vv_cache_read/write (canonical cache dir)
- monitor_remote.php + board.php + snapshot.php: all use vv_cache_read/write instead of ad-hoc /tmp files
HTTP method guards added to write-only APIs that were missing them:
- api/scheduler.php, conf_toggle.php, flag_toggle.php
Split slow cached monitor endpoint from the live stats. monitor_fast.php
reads /proc/stat, /proc/meminfo, ZFS arcstats, and /proc/net/dev directly
— no cache wrapper, 87ms response. Docker/vm/swap pulled from last full
cache so mem card stays complete. Full monitor poll stays at 2s for
everything else (GPU, containers, storage, etc).
unRAID API rejects underscores and hyphens in key names — only letters, numbers,
and spaces allowed. Varaverk_HOST1 / Varaverk_Gmer4Lfe both fail; now uses
"Varaverk <hostname>" (space). Also adds monitor_remote.php, conf_populate.sh,
and conf_sync.sh from dev branch that were missing from production.
play_state_sync: fix TVDB episode lookup for Jellyfin 10.x — AnyProviderIdEquals
returns the entire library for TVDB queries; switch to season+episode search with
ProviderIds.Tvdb validation to find the correct episode. Also fix pkey extraction
that was pulling s7e2 instead of the TVDB ID from tvdb:ep:5618559:s7e2.
docker_watchdog: add automatic manual-stop detection — containers stopped cleanly
(exit 0/143) are tracked in docker_watchdog_manual_stop.db and skipped until
restarted, removing the need to add manually-stopped containers to the exclusion
list. Auto-clears when the container is seen running again.
docker_daily_restart: remove bare `local` declarations outside a function that
were printing an error for every container restarted.
Previously exited early when key was found in registry without checking
if the conf matched. After a reboot or key rotation the registry holds
the current key but the conf could have a stale value causing API auth
failures on every boot.
Now compares registry key to conf value and syncs if they differ.
New span-1 card shows global RSYNC_ENABLED gate, per-window badges (C/D/I/W),
active profile names + elapsed time from lock files, and last-sync timestamp
per orchestrator window from script log files.
GPU shrunk from span 2 to span 1 to make room. Row 3 is now:
Rsync(1) | GPU(1) | Transcode(2) | Streams(4)
docker_watchdog: config dump at startup (thresholds/limits), skip list shown when active, per-container healthy log for Tier1 required + mem/CPU monitored containers
stability_watchdog: config dump with all tier thresholds, log() on pass for rootfs/log/tmp/load/zombies/NIC checks (previously silent on clean)
resource_watchdog: config dump with all pressure thresholds and container lists, log normal pressure state with live RAM/load values
system_watchdog: per-script timing on each child script run
network_watchdog: config dump (internet URL, DDNS domain/container, NPM URL, strike limit)
storage_watchdog: config dump (growth threshold, log max, paths, suppress ceilings)
webgui_watchdog: log nginx worker and php-fpm worker counts on healthy check
- Config/threshold dumps at startup in every script (retry counts, timeouts, sizes, thresholds)
- Per-item detail in verbose: container images, timing per container/share/job, image ID diffs
- Orchestrators: watchdog cycle now logs array state, grace state, per-script timing; transcode_management shows ramdisk state before each cycle; critical_sync logs share list and maintenance scripts; coffee report logs server state at run time
- Summary counts replaced with names in verbose where previously only counts were shown
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
disk_io now returns {tr, tw} cumulative GB alongside {r, w} rates.
A centered span in each card h3 shows ↓total ↑total (since last boot),
updating each poll. Helpers updated for the new object format.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Shows N/total ok · X% used · max Y° · ↓read ↑write in the Pools
card title, using SSD thresholds for temp coloring.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds vv_disk_io_rates() — snapshots /proc/diskstats each poll and
computes per-device MB/s. Exposed as disk_io in the monitor API.
JS:
- Per-disk rows: ↓read ↑write inline next to disk name (green/amber, hidden when idle)
- Pool rows: aggregate pool I/O next to pool name
- Array header: total array I/O in the subtitle line
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Server badges + media type anchor to the left; device/res/codec anchor
to the right via justify-content:space-between. Right group still
disappears at ≤1024px (now a single display:none on .vv-stream-right).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Removes the 4-item cap and +N more label. All sessions go into balanced
columns; the container max-height clips to 2 rows with a hidden scrollbar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Splits up to 4 sessions into two balanced columns (ceil/floor split),
separated by a subtle divider. A '+N more' line appears beyond 4.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Parses the last 'Ramdisk freed' and 'SSD freed' values from the transcode
management log and displays them as small ↓XMB annotations inside each tag.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reduced max-height from 57px to 44px (2 × 22px rows) so the container
cleanly shows two entries at a time and scrolls when a third appears.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wraps each group (separator + chips) in a display:contents span so it
flows naturally at full width and collapses cleanly at the 1024px breakpoint,
leaving server badges and media type visible at intermediate sizes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Purple-accented chips, ordered Movies → Shows → Music → Live, with
per-index shade variation matching the other chip groups.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Global webkit rule now covers all descendants, not just direct children.
Inline scrollbar-width:none added to the three inner overflow-y:auto divs
(transcode sessions, GPU processes, scripts list) so Firefox hides them too.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Device chips: blue, resolution chips: teal, codec chips: amber.
Alternating bg shades within each group to visually separate chips.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds height/codec fields to both Emby/Jellyfin and Plex session data,
then surfaces them as chip groups (· 2 4K 3 1080p · 4 H.264 2 HEVC)
in the streams card header alongside the existing device type bar.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Parses each session's client string (e.g. "Emby for Roku / Bedroom TV")
into a device category using priority-ordered regex matching:
Android TV, Fire TV, Apple TV, Android, iOS, Roku, LG, Samsung,
Google TV, Kodi, Browser, Desktop.
Counts are grouped and sorted by frequency, displayed as compact chips
to the right of the server badges:
Emby 7 Jellyfin 2 · 3 Android 2 Roku 1 Fire TV 1 iOS
Unknown client strings are silently skipped (not shown as "Other").
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
Two root causes of the May 31 19:30 hang (orchestrator stuck for 45min):
1. /etc/rc.d/rc.docker restart had no timeout — on a host with many
containers, stopping them all before daemon restart can take 30+
minutes. Added timeout 180 so it's bounded.
2. WATCHDOG_DAEMON_RESTART_WAIT=900 (15min sleep after restart) —
unnecessary. The daemon itself comes up in seconds; containers are
handled by subsequent docker_watchdog cycles. Reduced to 90s in
master.conf, cutting worst-case orchestrator block from 45min to ~5min.
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>
- Remove dead DOCKER_TIMEOUT=10 from stability_watchdog (daemon check
is delegated to docker_watchdog; variable was never used post-refactor)
- Fix parity check detection: parity-date.txt is gone in Unraid 7.3;
now reads mdResync from var.ini (non-zero = check/sync in progress),
with parity-date.txt fallback for older versions
- Same is_parity_running() fix in docker_watchdog
- DOCKER_TIMEOUT in docker_watchdog now reads WATCHDOG_DAEMON_TIMEOUT
from master.conf (default 20s) instead of hardcoded 15s
- WATCHDOG_DAEMON_RESTART_WAIT now reads from master.conf
(default 900s/15min) instead of hardcoded 30s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
common.sh: add is_docker_enabled() and is_vm_manager_enabled() helpers
reading /boot/config/docker.cfg and /boot/config/domain.cfg.
docker_watchdog: exit cleanly if Docker not enabled in Unraid settings.
stability_watchdog: skip Docker daemon check and Docker container stop
if Docker not enabled; skip virsh VM shutdown if VM Manager not enabled.
server_reboot: skip VM shutdown and libvirt stop if VM Manager not enabled.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docker restart uses the image ID baked in at container creation — it never
picks up a new digest. rebuild_container reads the stored Unraid XML template,
stops the old container, recreates it with the new image, then handles the
old image cleanup. This is what the Unraid UI 'Apply Update' button does.
docker_update.sh: add rebuild section after pull loop for DAILY containers.
docker_update_remaining.sh: replace retry_docker docker restart with rebuild_container.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docker_update_remaining.sh already pruned; docker_update.sh (daily)
did not — orphaned images accumulated with every daily update run.
Same prune pattern as docker_update_remaining.sh.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Redis warns and can fail background saves without this. Applied via
inotify_tuning.sh which already handles kernel parameter tuning at
array start. Resets on each reboot — reapplied automatically.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Skip list belongs to docker_watchdog, not stability_watchdog (legacy
naming from when docker+system were the only two watchdogs). Rename
variable and physical file system_watchdog_failed.db →
docker_watchdog_failed.db across all files.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
stability_watchdog: remove SYS_WATCHDOG_FAILED_FILE from state file
touch list — skip list is owned by docker_watchdog, not stability.
docker_watchdog: rename check_system_watchdog_state →
check_resource_watchdog_state (reads RW_STATE_FILE from resource_watchdog,
not SYS_WATCHDOG_STATE_FILE from stability_watchdog). Update all comments
and state file docs to reflect correct ownership.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously only cleared inside the strikes>0 block. After a reboot,
strikes reset to 0 but the flag persists on flash — daemon could be
healthy but flag stays true, causing stability_watchdog to keep striking.
Now cleared on every healthy docker info check regardless of strike count.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docker_watchdog now writes daemon_confirmed_down=true to its state file
when restart is attempted and daemon is still unresponsive. Clears the
flag on recovery.
stability_watchdog removes the duplicate CRITICAL daemon check (which
bypassed all strikes, all abort conditions, and had its own rc.docker
restart). Replaced with a standard strike check reading the
daemon_confirmed_down flag from docker_watchdog's state file.
Result: docker_watchdog owns all daemon restart logic. stability_watchdog
escalates to reboot only after N consecutive strike cycles confirming the
daemon is truly unrecoverable — same pattern as all other standard checks.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
stability_watchdog: container health is owned by docker_watchdog — rebooting
when docker_watchdog skip-lists a container creates a reboot loop. Removed
SYS_WATCHDOG_CHECK_CONTAINERS check entirely. docker_watchdog handles
strikes, restart attempts, skip-listing, and notifications.
varaverk.plg: warn on USB/removable boot device at install time. Plugin is
designed for internal NVMe/SSD boot. Warning is non-blocking but clear.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Exits cleanly before startup grace check if /mnt/user is not mounted
as shfs. Prevents watchdogs running against Docker/storage that isn't
available, and blocks false-positive reboots when array is stopped.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
runc v1.3.5 (Docker 29.x / Unraid 7.3+) crashes on bind-propagation=shared
with any container — not GPU-specific. Ramdisk tmpfs is already MS_SHARED
at kernel level; propagation is automatic and the option is unnecessary.
- Remove bind-propagation=shared from all example Extra Parameters
- Update "Why shared Is Required" → "Mount Propagation — Unraid 7.3+"
- Update GPU troubleshooting section to cover the general runc crash
- Verify commands updated (no longer checking for Propagation: shared)
- Historical notes preserved explaining why it existed before
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
runc v1.3.5 (Docker 29.x / Unraid 7.3+) rejects bind-propagation=shared
on symlink sources with: open /proc/self/mountinfo: no such file or directory.
The ramdisk tmpfs is already MS_SHARED at the kernel level — propagation is
inherited automatically and does not need to be specified in Docker.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
228 path references updated from /mnt/user/appdata/Varaverk/ to
/boot/config/plugins/varaverk/. PATHS header block updated to match.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Plugin folder /boot/config/plugins/varaverk is the single home for
scripts, data, and state. Available at boot before array mounts.
USB boot is not a supported configuration.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bootstrap varaverk.cfg default and conf template default back to
/mnt/user/appdata/Varaverk — safe for USB boot users. Flash paths
(/boot/config/plugins/varaverk) are set in the user's gitignored
personal configs and don't affect public installs.
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>