Overview
These findings were identified during a code smell review on 2026-03-13. Actionable, self-contained fixes (dead imports, FURB101 read_bytes patterns, the isinstance dict guard) have already been applied. The items below are deferred structural work, mypy type-narrowing, and LOW-priority observations.
Deferred Findings
auto_sync_manifests.py
| Severity |
Location |
Finding |
| MEDIUM |
module level (lines 39–42) |
sys.stdout.reconfigure() runs at import time. Guard behind if __name__ == "__main__" or move to CLI entry-point function to avoid side effects when imported as a library. |
| LOW |
whole file |
File is 1300+ lines combining CLI parsing, git diff analysis, manifest CRUD, version bumping, and reconciliation. Consider decomposing into submodules: _version_bump.py, _reconcile.py, _git_helpers.py. |
plugin_validator.py
| Severity |
Location |
Finding |
| HIGH |
line 1981 |
data["hooks"] typed as YamlValue — mypy does not narrow through .get() guard on line 1979. Fix: assign hooks = data["hooks"] after the isinstance guard, or use an explicit cast. |
| HIGH |
line 3024 |
item.lstrip("./") where item is YamlValue (iterated from list[YamlValue]). Non-string items would raise AttributeError at runtime. Add if isinstance(item, str) guard. |
| HIGH |
line 4063 |
group.get("hooks", []) returns YamlValue which includes int | float | None — not always iterable. Add isinstance check before iterating. |
| MEDIUM |
line 2957 |
metadata["author"] = author assigns dict[str, str] to a slot typed as YamlValue. Technically compatible but mypy flags due to recursive type alias limitations. Consider narrowing metadata dict annotation. |
| MEDIUM |
module level (lines 28–31) |
sys.stdout.reconfigure() at import time — same concern as auto_sync_manifests.py. |
| MEDIUM |
line 85 |
_ADAPTERS dict built at module level via load_adapters() — triggers filesystem operations on import. |
| LOW |
whole file |
File is 4000+ lines. Consider extracting: HookValidator into its own module, CLI entry point (app, typer commands) into cli.py, auto-fix logic into _autofix.py, reporting/formatting into _reporting.py. |
| LOW |
multiple except blocks |
Where exceptions are re-raised, consider using e.add_note() (PEP 678) to attach context rather than wrapping in new exceptions. |
adapters/claude_code/adapter.py
| Severity |
Location |
Finding |
| MEDIUM |
line 66 |
self.get_schema("plugin") — verify that the schema contains a "plugin" entry in file_types, otherwise validate() always returns [] for JSON files. |
| LOW |
— |
ClaudeCodeAdapter implements PlatformAdapter protocol but does not declare compliance. Consider explicit inheritance or a module-level type assertion: _: PlatformAdapter = ClaudeCodeAdapter() |
| LOW |
— |
Add runtime protocol compliance assertion at module bottom to catch interface drift early. |
_schema_loader.py
| Severity |
Location |
Finding |
| LOW |
— |
Return type is dict — could be dict[str, Any] for precision. No FileNotFoundError handling; consider a friendlier error message when a bundled schema file is missing. |
tests/test_frontmatter_utils.py
| Severity |
Location |
Finding |
| LOW |
lines 21, 30, 39, 49, 75 |
Imports of loads_frontmatter, dump_frontmatter, etc. inside every test method. Move to module level to reduce noise. |
Acceptance Criteria
https://claude.ai/code/session_01BevYUBWJm64cnqQ1E7U9uj
Overview
These findings were identified during a code smell review on 2026-03-13. Actionable, self-contained fixes (dead imports, FURB101 read_bytes patterns, the isinstance dict guard) have already been applied. The items below are deferred structural work, mypy type-narrowing, and LOW-priority observations.
Deferred Findings
auto_sync_manifests.py
sys.stdout.reconfigure()runs at import time. Guard behindif __name__ == "__main__"or move to CLI entry-point function to avoid side effects when imported as a library._version_bump.py,_reconcile.py,_git_helpers.py.plugin_validator.py
data["hooks"]typed asYamlValue— mypy does not narrow through.get()guard on line 1979. Fix: assignhooks = data["hooks"]after the isinstance guard, or use an explicit cast.item.lstrip("./")whereitemisYamlValue(iterated fromlist[YamlValue]). Non-string items would raise AttributeError at runtime. Addif isinstance(item, str)guard.group.get("hooks", [])returnsYamlValuewhich includesint | float | None— not always iterable. Add isinstance check before iterating.metadata["author"] = authorassignsdict[str, str]to a slot typed asYamlValue. Technically compatible but mypy flags due to recursive type alias limitations. Consider narrowingmetadatadict annotation.sys.stdout.reconfigure()at import time — same concern asauto_sync_manifests.py._ADAPTERSdict built at module level viaload_adapters()— triggers filesystem operations on import.HookValidatorinto its own module, CLI entry point (app, typer commands) intocli.py, auto-fix logic into_autofix.py, reporting/formatting into_reporting.py.e.add_note()(PEP 678) to attach context rather than wrapping in new exceptions.adapters/claude_code/adapter.py
self.get_schema("plugin")— verify that the schema contains a"plugin"entry infile_types, otherwisevalidate()always returns[]for JSON files.ClaudeCodeAdapterimplementsPlatformAdapterprotocol but does not declare compliance. Consider explicit inheritance or a module-level type assertion:_: PlatformAdapter = ClaudeCodeAdapter()_schema_loader.py
dict— could bedict[str, Any]for precision. NoFileNotFoundErrorhandling; consider a friendlier error message when a bundled schema file is missing.tests/test_frontmatter_utils.py
loads_frontmatter,dump_frontmatter, etc. inside every test method. Move to module level to reduce noise.Acceptance Criteria
sys.stdout.reconfigure()guarded or moved to CLI entry point in bothauto_sync_manifests.pyandplugin_validator.pyplugin_validator.pyresolved with explicit isinstance guards_ADAPTERSinitialization deferred away from module-level side effecthttps://claude.ai/code/session_01BevYUBWJm64cnqQ1E7U9uj