@kaged/local-config
TOML-backed operator-local configuration with Zod validation, file I/O, provider management, tool overrides, and Langfuse tracing settings
7
source files
3
test files
~2.1k
lines
✓ 124 pass
tests
pass
typecheck
clean
lint
Test results 124
WebConfigSchema > accepts empty object
[1.74ms]
WebConfigSchema > accepts preferred_provider
[0.510ms]
WebConfigSchema > accepts provider_order list
[0.340ms]
WebConfigSchema > accepts hard_timeout_ms integer >= 1000
[0.210ms]
WebConfigSchema > rejects hard_timeout_ms below 1000
[0.500ms]
WebConfigSchema > accepts all fields together
[0.110ms]
LocalConfigSchema [web] section > accepts local.toml with [web] block + provider overrides
[2.10ms]
LocalConfigSchema [web] section > accepts local.toml with [secrets.web] flat map
[0.170ms]
LocalConfigSchema [web] section > accepts combined [web] + [secrets.web]
[0.300ms]
LocalConfigSchema [web] section > local.toml without [web] still parses
[0.120ms]
redactSecrets covers [secrets.web] > redacts [secrets.web] values to <redacted>
[0.280ms]
redactSecrets covers [secrets.web] > does not mutate original config
[0.150ms]
LocalConfigSchema passthrough on [web] > unknown [web.<provider>] subsections are preserved (passthrough)
[0.180ms]
LocalConfigSchema passthrough on [web] > LocalConfigSchema accepts web as a top-level key
[0.180ms]
resolveLocalConfigPath > per-user mode with xdgConfigHome
[0.080ms]
resolveLocalConfigPath > per-user mode falls back to userHome/.config
[0.030ms]
resolveLocalConfigPath > per-user mode throws without userHome or xdgConfigHome
[0.060ms]
resolveLocalConfigPath > xdgConfigHome takes priority over userHome in per-user mode
[0.020ms]
resolveLocalConfigPath > system-wide mode builds user-specific path
[0.040ms]
resolveLocalConfigPath > system-wide mode throws without kagedHome
[0.040ms]
resolveLocalConfigPath > system-wide mode throws without userId
[0.030ms]
resolveLocalConfigPath > override takes precedence over everything
[0.020ms]
resolveLocalConfigPath > override works in system-wide mode too
[0.020ms]
serializeLocalConfig > empty config produces valid TOML
[0.370ms]
serializeLocalConfig > config with operator_name round-trips
[0.250ms]
serializeLocalConfig > config with aliases round-trips
[0.250ms]
serializeLocalConfig > config with providers round-trips
[0.310ms]
serializeLocalConfig > config with projects round-trips
[0.510ms]
serializeLocalConfig > config with audit section round-trips
[0.240ms]
serializeLocalConfig > config with plugins round-trips
[0.340ms]
serializeLocalConfig > full config round-trips
[0.300ms]
generateDefaultLocalToml > produces valid TOML
[0.140ms]
generateDefaultLocalToml > starts with comment header
[0.030ms]
generateDefaultLocalToml > parses to config with no projects and no aliases
[0.070ms]
readLocalConfigFile &gt; file I/O > reads and parses valid TOML file
[1.68ms]
readLocalConfigFile &gt; file I/O > throws ENOENT for missing file
[0.310ms]
readLocalConfigFile &gt; file I/O > returns parse errors for invalid TOML
[1.12ms]
readLocalConfigFile &gt; file I/O > reads empty file as empty config
[0.370ms]
writeLocalConfigFile &gt; file I/O > writes valid TOML that can be read back
[0.710ms]
writeLocalConfigFile &gt; file I/O > creates parent directories
[0.390ms]
writeLocalConfigFile &gt; file I/O > file has mode 0600
[0.330ms]
writeLocalConfigFile &gt; file I/O > overwrites existing file
[0.510ms]
ensureLocalConfigFile &gt; file I/O > creates file if missing and returns created=true
[0.640ms]
ensureLocalConfigFile &gt; file I/O > returns existing file with created=false
[0.340ms]
ensureLocalConfigFile &gt; file I/O > created file starts with comment header
[0.370ms]
ensureLocalConfigFile &gt; file I/O > created file has mode 0600
[0.390ms]
ensureLocalConfigFile &gt; file I/O > idempotent — second call returns created=false
[0.530ms]
addProjectEntry &gt; file I/O > adds entry to empty config
[0.650ms]
addProjectEntry &gt; file I/O > appends to existing projects list
[0.730ms]
addProjectEntry &gt; file I/O > upserts entry with same id
[0.600ms]
addProjectEntry &gt; file I/O > preserves other config sections
[0.620ms]
addProjectEntry &gt; file I/O > creates file if it does not exist
[0.410ms]
addProjectEntry &gt; file I/O > persists to disk — survives re-read
[0.540ms]
removeProjectEntry &gt; file I/O > removes existing entry
[0.640ms]
removeProjectEntry &gt; file I/O > no-op for unknown id
[0.550ms]
removeProjectEntry &gt; file I/O > preserves other entries
[0.590ms]
removeProjectEntry &gt; file I/O > preserves other config sections
[0.520ms]
removeProjectEntry &gt; file I/O > persists to disk — survives re-read
[0.760ms]
TOML parsing > parses full config successfully
[0.560ms]
TOML parsing > parses minimal config
[0.140ms]
TOML parsing > empty string parses to empty config
[0.050ms]
TOML parsing > invalid TOML returns error
[0.110ms]
TOML parsing > ui section parsed correctly
[0.300ms]
TOML parsing > invalid ui theme rejected
[0.240ms]
TOML parsing > provider fields parsed
[0.280ms]
TOML parsing > plugin entries parsed
[0.250ms]
TOML parsing > project registry parsed
[0.250ms]
TOML parsing > invalid project status rejected
[0.120ms]
TOML parsing > audit config parsed
[0.270ms]
TOML parsing > notifications section is optional
[0.090ms]
notifications > accepts empty [notifications] section
[0.060ms]
notifications > accepts attention_required routing channel config
[0.080ms]
notifications > accepts enabled false to disable a channel
[0.060ms]
notifications > accepts web_push config
[0.080ms]
notifications > accepts arbitrary per-channel keys via passthrough
[0.090ms]
notifications > rejects notifications as a string
[0.060ms]
notifications > rejects invalid channel config type
[0.070ms]
alias name validation > valid alias names accepted
[0.040ms]
alias name validation > alias with colon rejected
[0.030ms]
alias name validation > reserved names rejected
[0.050ms]
alias name validation > invalid pattern rejected
[0.020ms]
alias name validation > parse warns on invalid alias names
[0.070ms]
alias target validation > valid targets accepted
[0.020ms]
alias target validation > target without colon rejected
[0.020ms]
alias target validation > empty provider rejected
[0.020ms]
alias target validation > empty model rejected
[0.010ms]
alias target validation > parse warns on invalid alias targets
[0.060ms]
alias resolution > resolves known alias to provider + model
[0.130ms]
alias resolution > resolves local provider alias
[0.050ms]
alias resolution > unresolved alias returns alias_unresolved
[0.030ms]
alias resolution > alias with missing provider returns provider_missing
[0.030ms]
alias resolution > alias chaining (alias → alias) is rejected
[0.030ms]
alias resolution > direct provider:model passthrough resolves
[0.030ms]
alias resolution > direct provider:model with missing provider
[0.030ms]
checkProjectAliases > all aliases resolved
[0.080ms]
checkProjectAliases > unresolved alias reported
[0.030ms]
checkProjectAliases > empty required list returns empty results
[0.020ms]
secret redaction > credentials value is redacted
[0.130ms]
secret redaction > credentials env is NOT redacted
[0.090ms]
secret redaction > original config is not mutated
[0.080ms]
secret redaction > config without providers is unchanged
[0.050ms]
plugin store > local plugin is available to all projects
[0.090ms]
plugin store > project-scoped plugin has project list
[0.100ms]
plugin store > plugin with config
[0.080ms]
plugin store > plugin with system_config
[0.080ms]
project registry > project with all fields
[0.150ms]
project registry > project accent_color is optional
[0.070ms]
project registry > project label is parsed
[0.080ms]
project registry > project label is optional
[0.080ms]
project registry > legacy nickname field still parses (back-compat)
[0.080ms]
project registry > multiple projects
[0.070ms]
project registry > all three status values accepted
[0.170ms]
provider config > provider with credentials env
[0.080ms]
provider config > provider with inline credentials value
[0.070ms]
provider config > provider without any auth (ollama-style)
[0.050ms]
provider config > quoted provider name with dash
[0.090ms]
provider config > base_url is accepted as an arbitrary string
[0.070ms]
secrets (ADR-0043) > parses secrets section
[0.080ms]
secrets (ADR-0043) > secrets are redacted by redactSecrets
[0.050ms]
secrets (ADR-0043) > absence of secrets section is fine
[0.040ms]
mcp overrides (ADR-0043) > parses mcp server overrides
[0.100ms]
mcp overrides (ADR-0043) > absence of mcp section is fine
[0.050ms]
mcp overrides (ADR-0043) > mcp override with only disabled field
[0.060ms]
mcp overrides (ADR-0043) > mcp override with only timeout_ms field
[0.070ms]