返回 CodeWhale
check-config-example.py
根目录 / scripts / check-config-example.py
1 #!/usr/bin/env python3
2 """Check that config.example.toml keeps root-level keys at the root.
3
4 TOML assigns every key after a `[table]` header to that table, so a root key
5 written below `[update]` silently becomes `update.skills_dir`. A user who
6 copies the example then gets a config whose keys the loader never reads.
7 This parses the example with the stdlib TOML parser and asserts the keys the
8 loader reads from the root are really root keys.
9 """
10
11 from __future__ import annotations
12
13 import sys
14 import tomllib
15 from pathlib import Path
16
17
18 ROOT = Path(__file__).resolve().parents[1]
19 CONFIG_EXAMPLE_TOML = ROOT / "config.example.toml"
20
21 ROOT_KEYS = (
22 "allow_shell",
23 "approval_policy",
24 "sandbox_mode",
25 "max_subagents",
26 "skills_dir",
27 "mcp_config_path",
28 "notes_path",
29 "memory_path",
30 )
31
32
33 def main() -> int:
34 try:
35 with CONFIG_EXAMPLE_TOML.open("rb") as handle:
36 config = tomllib.load(handle)
37 except (OSError, tomllib.TOMLDecodeError) as error:
38 print(f"config.example.toml: cannot parse: {error}", file=sys.stderr)
39 return 1
40
41 errors = []
42 for key in ROOT_KEYS:
43 if key in config:
44 continue
45 owners = sorted(
46 name
47 for name, value in config.items()
48 if isinstance(value, dict) and key in value
49 )
50 where = f" (parsed under [{', '.join(owners)}])" if owners else ""
51 errors.append(
52 f"config.example.toml: `{key}` is not a root-level key{where}; "
53 "move it above the first [table] header"
54 )
55
56 if errors:
57 for error in errors:
58 print(error, file=sys.stderr)
59 return 1
60 print(f"config.example.toml: {len(ROOT_KEYS)} root-level keys OK")
61 return 0
62
63
64 if __name__ == "__main__":
65 sys.exit(main())
66
66 lines PYTHON