nautd/webui: scripting, labels, settings, set-location, pause fix

Session checkpoint on webui-plugin:
- engine dump (nautctl dump) + engine endgame integration
- per-file move locations persistence; torrent-level "Set location"
  with reset/keep-relative/leave-separate handling + residual prune
- Lua: naut.get_labels, define_settings/get_setting (script_host struct)
- daemon-owned labels (category+tags) + taxonomy persistence; webui write-through
- fix: pausing a completed/seeding torrent now sticks (stop wins over result)
- automation tab responsive layout; anime_sort label gating + settings

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ookami125 2026-06-21 23:19:41 -04:00
parent 6dc711cf57
commit b633b7d216
40 changed files with 3305 additions and 3267 deletions

View file

@ -11,6 +11,50 @@ typedef naut_err (*naut_script_move_file_cb)(void *context,
uint32_t file_index,
const char *destination);
/* Resolve a torrent's labels for `naut.get_labels(id)`. Returns a heap array of
* `*count` heap strings (caller frees each string then the array), or NULL with
* *count==0 if the torrent has no labels / is unknown. */
typedef char **(*naut_script_labels_cb)(void *context, uint64_t torrent_id,
size_t *count);
/* One user-configurable setting a script declares via naut.define_settings. */
typedef struct {
const char *key; /* stable identifier read by naut.get_setting */
const char *label; /* human label for the web UI form */
const char *type; /* "string" | "bool" | "number" */
const char *default_value; /* stringified default ("true"/"false" for bool)*/
} naut_script_setting_def;
/* The script (re)declared its settings schema. The host stores it and renders a
* form; `defs` is valid only for the duration of the call. */
typedef void (*naut_script_define_settings_cb)(void *context,
const naut_script_setting_def *defs,
size_t count);
/* Setting value kinds, so the Lua side can push the right type. */
typedef enum {
NAUT_SETTING_STRING = 0,
NAUT_SETTING_BOOL = 1,
NAUT_SETTING_NUMBER = 2,
} naut_setting_type;
/* Resolve a setting for `naut.get_setting(key)`: the user-set value if present,
* else the declared default. Returns a heap string (caller frees) and sets
* *type, or NULL if the key is unknown. */
typedef char *(*naut_script_get_setting_cb)(void *context, const char *key,
naut_setting_type *type);
/* Host callbacks the sandboxed script may invoke. Any may be NULL (the matching
* naut.* function then reports it is unavailable). `context` is passed back to
* each callback. */
typedef struct {
naut_script_move_file_cb move_file;
naut_script_labels_cb labels;
naut_script_define_settings_cb define_settings;
naut_script_get_setting_cb get_setting;
void *context;
} naut_script_host;
typedef struct {
uint64_t queued;
uint64_t handled;
@ -20,12 +64,12 @@ typedef struct {
} naut_script_stats;
/* script_path is loaded before the worker starts. queue_capacity bounds copied
* events and must be non-zero. The VM owns no filesystem or process APIs. */
* events and must be non-zero. The VM owns no filesystem or process APIs. `host`
* is copied; its callbacks are invoked from the script worker thread. */
naut_script *naut_script_create(naut_event_bus *events,
const char *script_path,
size_t queue_capacity,
naut_script_move_file_cb move_file,
void *move_context,
const naut_script_host *host,
naut_err *error);
void naut_script_destroy(naut_script *script);