Extract all subprocess calls to `gh` and `claude` into dedicated Python modules. No callers yet — just the modules + 100% test coverage.
New files
`kennel/github.py`
All `gh` CLI wrappers: repo info, PR CRUD, GraphQL queries, thread resolution, user status. Every function calls `subprocess.run(["gh", ...])` and returns parsed results.
Key functions:
- `get_repo_info()`, `get_user()`, `get_default_branch()`
- `find_issues()`, `view_issue()`, `close_issue()`, `comment_issue()`
- `find_pr()`, `create_pr()`, `edit_pr_body()`, `pr_checks()`, `pr_ready()`, `pr_merge()`
- `get_review_threads()`, `get_reviews()`, `resolve_thread()`
- `set_user_status()`
`kennel/claude.py`
All `claude` CLI wrappers:
- `one_shot(model, prompt, system_prompt=None, timeout=30) -> str` — `--print` mode
- `start_session(model, system_prompt_file, prompt_file, stream_file) -> str` — returns session_id, streams to file
- `resume_session(model, session_id, prompt_file) -> None`
`kennel/hooks.py`
`.claude/settings.local.json` hook management:
- `install_hooks(work_dir, sub_dir, sync_cmd)` — adds PostCompact + PostToolUse hooks
- `remove_hooks(work_dir, hook_cmd, sync_cmd)` — cleanup on exit
`kennel/prompts.py`
Prompt building:
- `load_persona(sub_dir) -> str`
- `build_prompt(sub_dir, skill_name, context) -> tuple[Path, Path]` — returns (system_file, prompt_file)
- `generate_slug(request) -> str` — haiku call + fallback
Constraints
- 100% test coverage (CI enforced)
- All subprocess calls mocked in tests
- No existing code changes — these are new standalone modules
- Reference work.sh for the exact gh/claude invocations to wrap
Extract all subprocess calls to `gh` and `claude` into dedicated Python modules. No callers yet — just the modules + 100% test coverage.
New files
`kennel/github.py`
All `gh` CLI wrappers: repo info, PR CRUD, GraphQL queries, thread resolution, user status. Every function calls `subprocess.run(["gh", ...])` and returns parsed results.
Key functions:
`kennel/claude.py`
All `claude` CLI wrappers:
`kennel/hooks.py`
`.claude/settings.local.json` hook management:
`kennel/prompts.py`
Prompt building:
Constraints