Skip to content

Commit 2bf5266

Browse files
committed
fix(config): address CodeRabbit review comments
- Guard dict/scalar type conflict in _type_based_merge: when base holds a scalar or list for a key that an overlay wants to replace with a dict, let the overlay win outright instead of recursing into a non-dict (which crashes with TypeError before validation can surface a ConfigError) - Add integration test verifying _load_scoped auto-gitignores config.local.toml when the file is present (test_load_scoped_gitignores_local_config) - Add MD041-compliant H1 heading to agents/default/system.md
1 parent ebd5604 commit 2bf5266

3 files changed

Lines changed: 21 additions & 0 deletions

File tree

src/pythinker_code/agents/default/system.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# System Prompt
2+
13
You are **Pythinker** — a think-first software engineering agent developed by **Pythoughts-labs**, running on the user's computer. Before you write code, you read code.
24

35
## Product Identity

src/pythinker_code/config.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ def _type_based_merge(
159159
"""
160160
for key, value in overlay.items():
161161
if isinstance(value, dict):
162+
# If base holds a scalar/list for this key, the overlay dict wins outright
163+
# (recursing into a non-dict crashes with TypeError before validation runs).
164+
if key in base and not isinstance(base[key], dict):
165+
base[key] = value
166+
provenance[key] = scope
167+
continue
162168
# For dicts, always recurse to track individual nested keys
163169
if key not in base:
164170
base[key] = {}

tests/core/test_config.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,19 @@ def test_load_scoped_source_scopes_populated(tmp_path, monkeypatch):
597597
assert "local" not in config.source_scopes # local file absent
598598

599599

600+
def test_load_scoped_gitignores_local_config(tmp_path, monkeypatch):
601+
monkeypatch.setenv("PYTHINKER_SHARE_DIR", str(tmp_path))
602+
_write_toml(tmp_path / "config.toml", {})
603+
project_root = tmp_path / "myproject"
604+
_write_toml(project_root / ".pythinker" / "config.local.toml", {})
605+
606+
_load_scoped(project_root=project_root)
607+
608+
gitignore = project_root / ".gitignore"
609+
assert gitignore.exists()
610+
assert ".pythinker/config.local.toml" in gitignore.read_text(encoding="utf-8")
611+
612+
600613
def test_load_config_explicit_path_bypasses_scoping(tmp_path):
601614
"""--config flag must bypass scope resolution entirely."""
602615
config_file = tmp_path / "explicit.toml"

0 commit comments

Comments
 (0)