-
Drop the cross-exclusivity in
_main(): keep--topic/--skill/--rulemutually exclusive with each other (existing argparse group, unchanged), but remove--mode's membership in the extranum_exclusiveassert, so any of {--topic,--skill,--rule, default-inferred} can be combined with any of {one_shot,session,stateless}. -
Generalize the incremental branch (
_process_file_incrementally/_build_incremental_messages), used when--modeissession/stateless, to build message chunks from whichever "what" was actually specified, instead of only the filename-inferred topic:--topic(or default): unchanged — one chunk per H1 section across all oftopic_info["rules"]'s files.--rule:hmarsele.extract_rule_from_file()'s text, split into H1 sections when it contains more than one (whole-file rule spec), else a single chunk (line-anchored spec already extracts one section).--skill: a single, non-decomposed chunk equal to the existing/{skill} {file_path}slash-command string — kept as-is because a skill invocation is a command for Claude Code's own skill loader, not declarative rule prose to split.
-
Leave the
one_shotpath's prompts/execution untouched: the existingtopic/skill/rule/default branches in_process_file()that call_build_prompt()+_run_claude_code()(subprocessccwrapper) keep their current prompt construction and behavior exactly as today; only their reachability changes (no longer blocked from coexisting with a non-default--modeelsewhere). -
Factor the H1-splitting core out of file I/O: split
_extract_h1_sections(rule_file)into a purelist[str]-based helper plus a thin file-reading wrapper, so the same splitting logic can run overextract_rule_from_file()'s in-memory string (for--rule) without writing a temp file. -
Tests in
linters2/test/test_cc_lint.py, covering--mode×{topic, skill, rule, default}(the 3×4 = 12 combinations from task 2), each in two flavors against the same input file:- fake: mock
claude_agent_sdk.ClaudeSDKClient(mirrorsTest_PromptSequencer_executeindev_scripts_helpers/ai/test/test_cc_lib.py) forsession/stateless, and mock the subprocess call forone_shot; assert the right chunks/messages get built and dispatched. - live:
pytest.importorskip("claude_agent_sdk")+ class-level@pytest.mark.skip(reason="Run manually: makes a real Claude Agent SDK call and costs tokens"), cheapest model,assertIn-style loose checks — mirrorsTest_PromptSequencer_execute_end_to_endin the same file. Also updatecc_lint.README.md's "Invariants"/architecture section, which currently documents "exactly one action mode is active" — that invariant is being intentionally removed.
- fake: mock