diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 51295d2..7b8b058 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -14,5 +14,5 @@ "license": "BSD-3-Clause", "name": "yas", "repository": "https://github.com/tmck-code/yet-another-statusline", - "version": "0.2.10" + "version": "0.2.11" } diff --git a/claude/yas/config.py b/claude/yas/config.py index 3ed8455..3f810b0 100644 --- a/claude/yas/config.py +++ b/claude/yas/config.py @@ -11,6 +11,7 @@ from __future__ import annotations +import json import os try: import tomllib @@ -54,14 +55,16 @@ def _parse_pos_float(raw: object, origin: str) -> float: raise ValueError('must be > 0') return x +BOOL_ALLOWLIST = ('1', '0', 'true', 'false') def _parse_bool(raw: object, origin: str) -> bool: if isinstance(raw, bool): return raw - # Env form: any non-empty value is true (empty strings are filtered out - # before reaching here). A non-bool from yas.toml is a type error. if origin == 'cli' or origin.startswith('env'): - return True + v = str(raw).strip().lower() + if v not in BOOL_ALLOWLIST: + raise ValueError(f"expected one of {', '.join(BOOL_ALLOWLIST)}") + return bool(json.loads(v)) raise ValueError('expected a boolean') diff --git a/pyproject.toml b/pyproject.toml index 490a74f..12fb18c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "yet-another-statusline" -version = "0.2.10" +version = "0.2.11" description = "Claude Code statusline showing info at a glance: tokens, context, model, subagents, burn rate, skills, plugins, OpenSpec specs, task lists, and more" readme = "README.md" diff --git a/test/test_config.py b/test/test_config.py index 35af55c..900ac68 100644 --- a/test/test_config.py +++ b/test/test_config.py @@ -154,9 +154,36 @@ def test_toml_full_width_true(tmp_path: Path) -> None: assert cfg.full_width is True -def test_env_full_width_any_nonempty_is_true(tmp_path: Path) -> None: +def test_env_full_width_truthy_values(tmp_path: Path) -> None: + for val in ('1', 'true', 'True', 'TRUE'): + cfg = config.Config.load(env={'YAS_FULL_WIDTH': val}, config_dir=tmp_path) + assert cfg.full_width is True, f'expected True for YAS_FULL_WIDTH={val!r}' + + +def test_env_full_width_falsy_values(tmp_path: Path) -> None: + for val in ('0', 'false', 'False', 'FALSE'): + cfg = config.Config.load(env={'YAS_FULL_WIDTH': val}, config_dir=tmp_path) + assert cfg.full_width is False, f'expected False for YAS_FULL_WIDTH={val!r}' + + +def test_env_full_width_invalid_falls_through_to_default(tmp_path: Path) -> None: + cfg = config.Config.load(env={'YAS_FULL_WIDTH': 'yes'}, config_dir=tmp_path) + assert cfg.full_width is False # invalid env value → default + + +@requires_tomllib +def test_env_full_width_zero_overrides_toml_true(tmp_path: Path) -> None: + (tmp_path / 'yas.toml').write_text('[layout]\nfull_width = true\n') cfg = config.Config.load(env={'YAS_FULL_WIDTH': '0'}, config_dir=tmp_path) - assert cfg.full_width is True + assert cfg.full_width is False + + +@requires_tomllib +def test_env_max_width_respected_when_full_width_disabled(tmp_path: Path) -> None: + (tmp_path / 'yas.toml').write_text('[layout]\nfull_width = true\n') + cfg = config.Config.load(env={'YAS_FULL_WIDTH': '0', 'YAS_MAX_WIDTH': '40'}, config_dir=tmp_path) + assert cfg.full_width is False + assert cfg.max_width == 40 # 4.4 Broken TOML + unknown keys diff --git a/uv.lock b/uv.lock index 02e4d36..df335e9 100644 --- a/uv.lock +++ b/uv.lock @@ -399,7 +399,7 @@ wheels = [ [[package]] name = "yet-another-statusline" -version = "0.2.10" +version = "0.2.11" source = { virtual = "." } [package.dev-dependencies]