Rebased lane/daemon onto main first — fast-forward, no conflicts (lane/daemon was already fully merged; main has since taken lane/gui, lane/pkg-qa, lane/proto). 1. capture.offer and capture.getRules were stubs, buried inside D3's generic stub list with no flag for how load-bearing capture.offer is: it's a CLAUDE.md §4 non-negotiable (750ms deadline, fails open) and AGENT-DAEMON.md build step 6, and against the real daemon it 500s to -32603 every time — the extension captures nothing, not "falls through to Firefox on a slow path." Split into their own D7/D8 rows so they stop being invisible. 2. settings.get/settings.set (D9, closed). Four pointer-to-member tables in dispatcher.cpp (bool / ranged int / plain string / string array), five enum-typed keys handled individually since parse_XXX already validates those — covers all 43 SettingKeys without ~40 repetitive hand blocks. store::Settings::kDefaults grew from 14 entries to 43 (the schema itself carries no "default" keyword anywhere, so these are hand-chosen — conservative for the ones ADR 0012 doesn't speak to; capture.monitoredExtensions defaults to the union of every builtin category's extensions rather than an arbitrary list of its own). settings.set validates every field before writing any of them: numeric min/max (hand-checked — the generated parser only checks JSON type, not schema constraints) and saveTo.* paths via fs::resolve_target/canonicalize_root (-32011) — allowedRoots entries checked as roots in their own right, defaultDir/tempDir checked as paths resolving inside the (possibly just-updated, same call) root list. Reports exactly the keys whose effective value actually changed, publishes event.settings.changed with that list, and calls the scheduler's reload_config() when a connection.* key took effect — live, not on next restart. Verified against real veloxd: all 43 keys round-trip with defaults, a keys subset filters, an out-of-range value rejects the whole call, a bad saveTo.defaultDir is -32011, allowedRoots+defaultDir set together cross-validate against the new roots, event.settings.changed fires over a live subscription. New dispatcher_settings_test covers the same ground without a socket. Full ctest: 53/53 (excluding a pre-existing, unrelated conformance failure — see below). Also found, not fixed (not this lane): tests/conformance/run.sh's live-veloxd leg fails "pairing failed: no token issued" reproducibly, isolated, on main before any of this session's changes — it launches the isolated veloxd without VELOX_PAIR_AUTO=1, so EnvAutoApprover denies every session.pair and the WS leg's session.hello never gets a token. tests/conformance/ is PROTO/QA-owned; flagging rather than editing across the lane boundary. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01GRDjHGgpYmMoPE2UFbe7pP
50 lines
1.7 KiB
C++
50 lines
1.7 KiB
C++
#pragma once
|
|
|
|
// Read/write access to the `settings` table (key -> JSON-text value). The table starts
|
|
// empty; a key with no row falls back to the built-in default that mirrors
|
|
// Settings.schema.json. Typed helpers cover what the daemon reads internally (governor
|
|
// config, allowed roots); the full settings.get / settings.set projection onto the wire
|
|
// `Settings` object lands with those handlers.
|
|
|
|
#include <cstdint>
|
|
#include <map>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <string_view>
|
|
#include <vector>
|
|
|
|
#include "store/sqlite.hpp"
|
|
|
|
namespace velox::daemon::store {
|
|
|
|
class Settings {
|
|
public:
|
|
explicit Settings(Db& db) : db_(db) {}
|
|
|
|
// Raw JSON text for one key: the stored row, or the built-in default, or nullopt if
|
|
// the key is unknown to the daemon entirely.
|
|
DbResult<std::optional<std::string>> get_raw(std::string_view key);
|
|
|
|
// Replace one key's value. `json_text` must be a valid JSON document; the caller
|
|
// (settings.set handler) validates it against the schema first.
|
|
DbResult<void> set_raw(std::string_view key, std::string_view json_text);
|
|
|
|
// Every stored override (not merged with defaults).
|
|
DbResult<std::map<std::string, std::string>> overrides();
|
|
|
|
// Typed convenience over get_raw + the defaults. A malformed stored value falls back
|
|
// to the default rather than throwing.
|
|
std::int64_t get_int(std::string_view key);
|
|
bool get_bool(std::string_view key);
|
|
std::string get_string(std::string_view key);
|
|
std::vector<std::string> get_string_array(std::string_view key);
|
|
|
|
// The built-in default JSON for `key`, or nullopt if unknown.
|
|
static std::optional<std::string_view> default_for(std::string_view key);
|
|
|
|
private:
|
|
Db& db_;
|
|
};
|
|
|
|
} // namespace velox::daemon::store
|