- Fix restoreBackup using backupOptions instead of restoreOptions
- Add missing await on preRestore/postRestore hooks
- Remove -c (checksum) flag that forced full reads on every run
- Add --partial to keep partially transferred files on interruption
- Add --inplace to avoid temp-file+rename metadata churn
- Add --timeout=300 to prevent hangs on stalled mounts
Adds a VPS restart button to the settings page, above logout. Shows a
spinner while the RPC completes, then a dialog telling the user to wait
1-2 minutes and refresh.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bug: After running an action (e.g. bitcoin's autoconfig), update_tasks was
called with the submitted form input — which for task-triggered actions is
filtered to only the task's fields (e.g. {zmqEnabled: true}). Other services'
tasks targeting the same action were then compared against this partial via
is_partial_of, so any task wanting a field NOT in the submission (e.g.
{blocknotify: "curl..."}) would incorrectly become active, even though the
full config still satisfied it.
This caused a cycling bug: running LND's autoconfig (zmqEnabled) would
activate Datum's task (blocknotify), and vice versa, despite the merge
correctly preserving both values in the config.
Fix: After running an action, fetch the full current config via
get_action_input (same as create_task and recheck_tasks already do) and
compare tasks against that.
The one-liner fix would have been to add a get_action_input call in the
RunAction handler. Instead, we extracted eval_action_tasks on
ServiceActorSeed — a single method that both RunAction and recheck_tasks
now call — because the duplication between these two sites is exactly how
this bug happened: recheck_tasks fetched the full config, RunAction didn't,
and they silently diverged.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bug: Setting a task input property to undefined (e.g. { prune: undefined })
to express "this key should be deleted" resulted in no task being created.
JSON.stringify strips undefined values, so { prune: undefined } serialized
as {}, and is_partial_of({}, any_config) always returns true — meaning
input-not-matches saw a "match" and never activated the task.
Fix (two parts):
- SDK: coerce undefined to null in task input values before serialization,
so they survive JSON.stringify and reach the Rust backend
- Rust: treat null in a partial as matching a missing key in the full
config, so tasks correctly deactivate when the key is already absent
Assumption: null and undefined/absent are semantically equivalent for
StartOS config values. Input specs produce concrete values (strings,
numbers, booleans, objects, arrays) — null never appears as a meaningful
distinct-from-absent value in real-world configs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Guard z.union() against empty arrays in dynamicSelect/dynamicMultiselect
by falling back to z.string() (fixes zod v4 _zod TypeError)
- Add smtpShape: typed zod schema for store file models, replacing
smtpInputSpec.validator which caused cross-zod-instance errors
- Bump version to 0.4.0-beta.62
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- add #[group(skip)] to all Parser-derived structs
- fix conflicts_with and arg definitions for correct CLI behavior
- refactor bin entry points to support manpage generation
Remove static wifi_interface/ethernet_interface fields from RpcContextSeed. Instead, look up
the wifi interface from the DB (populated by gateway sync) and check ethernet connectivity
by querying gateway entries. This ensures the wifi manager always uses the correct interface
even if network devices change after boot.
- COW snapshot (cp --reflink=always) of package volumes before
install/update; restore on failure, remove on success
- Automatic ext4→btrfs conversion via btrfs-convert during disk attach
with e2fsck pre-check and post-conversion defrag
- Probe package-data filesystem during setup.disk.list (on both disk
and partition level) so the UI can warn about ext4 conversion
- Setup wizard preserve-overwrite dialog shows ext4 warning with
backup acknowledgment checkbox before allowing preserve
The diff() method computes `compare - self`, not `self - compare`.
The reversed arguments caused all cert expiration times to resolve
to before the unix epoch, making getSslCertificate callbacks fire
immediately and infinitely on every registration.
Convert getServiceInterface, listServiceInterfaces, getSystemSmtp, and
getServiceManifest from manual callback triggers to DbWatchedCallbacks.
getServiceManifest now always returns the installed manifest.