# ops CLI Cleanup — Implementation Plan

> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.

**Goal:** Split ops CLI into focused modules: ops = server management, helm = session intelligence, it2 = terminal control (already done), infra = backup.

**Architecture:** Extract session intelligence functions + CLI commands from `ops/sessions.py` into `helm/sessions.py`. Move `ops/pool.py` → `helm/pool.py`, `ops/corpus.py` → `helm/corpus.py`. Delete terminal control commands (badge/color/activate/panes/attach) from ops since it2 already has them. Add `inv infra.backup` task. Update imports everywhere.

**Tech Stack:** Python, Click, asyncio, iterm2 library

---

### Task 1: Create helm/sessions.py with session intelligence code

**Files:**
- Create: `helm/sessions.py` (replace the current stub)
- Read: `ops/sessions.py` (source of code to extract)

**Step 1: Write helm/sessions.py**

Extract from `ops/sessions.py` into `helm/sessions.py`:
- Imports and constants: `CLAUDE_PROJECTS_DIR`, `COORD_DIR`, `LAST_ACTIVE_FILE`, `SESSION_CACHE_DIR`, `SESSION_CACHE_TTL`, `_SPINNER_CHARS`, `_IDLE_STAR`
- Data model: `Session`, `FindResult` dataclasses
- `_ITerm` class (async iTerm2 wrapper)
- `_is_claude_title()`, `_parse_title()`
- `_get_session_cache()`, `cache_session()`
- `_resolve_session()`
- Async API: `list_sessions()`, `find_sessions()`, `raise_window()`, `restart_session()`
- Non-async helpers: `_axraise()`, `_cwd_to_project_dir()`, `_find_jsonl()`, `detect_session_version()`, `detect_wait_state()`, `_read_jsonl_metadata()`, `_get_badge()`, `_days_to_cutoff()`, `search_jsonl_content()`, `load_last_active()`, `idle_minutes()`, `get_cc_version_cached()`, `_session_to_dict()`
- CLI commands: `list`, `grep`, `inspect`, `restart-cc`, `cycle-warm`, `idle`, `observe`

The CLI group should be named `sessions` and added to the helm main CLI.

**Step 2: Verify it imports cleanly**

Run: `python -c "from helm.sessions import idle_minutes, list_sessions, Session"`
Expected: no errors

**Step 3: Commit**

```bash
git add helm/sessions.py
git commit -m "refactor(helm): extract session intelligence from ops to helm/sessions.py"
```

---

### Task 2: Move pool.py and corpus.py to helm

**Files:**
- Move: `ops/pool.py` → `helm/pool.py`
- Move: `ops/corpus.py` → `helm/corpus.py`

**Step 1: Copy files with import updates**

- Copy `ops/pool.py` → `helm/pool.py`
  - Update the import of `detect_wait_state` from `ops.sessions` to `helm.sessions`
  - Update help text reference from `ops pool status` to `helm pool status`
- Copy `ops/corpus.py` → `helm/corpus.py`
  - No ops imports to update — it only imports from `lib/`

**Step 2: Register in helm CLI**

In `helm/cli.py`, add:
```python
from helm.pool import cli as pool_cli
from helm.corpus import cli as corpus_cli
cli.add_command(pool_cli, "pool")
cli.add_command(corpus_cli, "corpus")
```

Also register the sessions subgroup from Task 1.

**Step 3: Verify**

Run: `python -m helm.cli pool status`
Run: `python -m helm.cli corpus stats`
Expected: same output as before

**Step 4: Commit**

```bash
git add helm/pool.py helm/corpus.py helm/cli.py
git commit -m "refactor(helm): move pool and corpus CLIs from ops to helm"
```

---

### Task 3: Strip ops/sessions.py to server-only commands

**Files:**
- Modify: `ops/sessions.py`
- Modify: `ops/__main__.py`

**Step 1: Remove from ops/sessions.py**

Delete these commands and their supporting functions that are no longer needed:
- `list_cmd`, `grep_cmd`, `inspect_cmd`, `restart_cc_cmd`, `cycle_warm_cmd`, `idle_cmd`, `observe_cmd` (moved to helm)
- `activate_cmd`, `color_cmd`, `badge_cmd` (duplicated by it2)
- `panes_cmd`, `attach_cmd` (duplicated by it2 tmux)
- `backup_cmd` (moving to inv infra)
- `push_cmd` (thin wrapper, `/notify` skill covers it)

Delete supporting code no longer needed by remaining commands:
- `Session`, `FindResult` dataclasses
- `_ITerm` class
- `_is_claude_title()`, `_parse_title()`, `_resolve_session()`
- `_get_session_cache()`, `cache_session()`, `list_sessions()`, `find_sessions()`, `raise_window()`, `restart_session()`
- `_axraise()`, `_cwd_to_project_dir()`, `_find_jsonl()`, `detect_session_version()`, `detect_wait_state()`, `_read_jsonl_metadata()`, `_get_badge()`, `_days_to_cutoff()`, `search_jsonl_content()`, `load_last_active()`, `idle_minutes()`, `get_cc_version_cached()`, `_session_to_dict()`

Keep:
- `cli` group (rename help text to "Server management")
- Server commands: `servers_cmd`, `start_cmd`, `stop_cmd`, `restart_server_cmd`, `reload_cmd`, `logs_cmd`, `free_port_cmd`
- Server helpers: `_get_port_util()`, `_discover_services()`, `_tmux_*` functions
- `colors.py` import (used by servers for emoji display? check — may be removable)

**Step 2: Update ops/__main__.py**

Remove pool and corpus imports:
```python
"""Entry point: python -m ops"""
from ops.sessions import cli
from ops.resmon.__main__ import cli as resmon_cli

cli.add_command(resmon_cli, "resmon")

cli()
```

**Step 3: Verify**

Run: `python -m ops servers`
Run: `python -m ops resmon check`
Expected: work as before

Run: `python -m ops list` — should error (command removed)

**Step 4: Commit**

```bash
git add ops/sessions.py ops/__main__.py
git commit -m "refactor(ops): strip to server-management only"
```

---

### Task 4: Update all imports from ops.sessions → helm.sessions

**Files:**
- Modify: `helm/state_poller.py` (lines 30, 398)
- Modify: `helm/autodo/engine.py` (line 28)
- Modify: `tests/test_tmux_pane_reuse.py` (lines 87, 98)
- Modify: `tools/cli/Makefile` (lines 43-45)

**Step 1: Fix imports**

- `helm/state_poller.py:30`: `from ops.sessions import idle_minutes` → `from helm.sessions import idle_minutes`
- `helm/state_poller.py:398`: `from ops.pool import ...` → `from helm.pool import ...`
- `helm/autodo/engine.py:28`: `from ops.sessions import idle_minutes` → `from helm.sessions import idle_minutes`
- `tests/test_tmux_pane_reuse.py:87,98`: `from ops.sessions import _tmux_find_pane` → update to import from ops.sessions (tmux helpers stay in ops)
- `tools/cli/Makefile:43-45`: Update ops completions generation — remove corpus/pool references (they're now in helm)

**Step 2: Add helm CLI completions to Makefile**

Add a target for `helm` completions alongside `ops`.

**Step 3: Verify**

Run: `python -c "from helm.state_poller import StatePollLoop"`
Run: `python -c "from helm.autodo.engine import AutonomousEngine"`

**Step 4: Commit**

```bash
git add helm/state_poller.py helm/autodo/engine.py tests/test_tmux_pane_reuse.py tools/cli/Makefile
git commit -m "refactor: update imports from ops.sessions to helm.sessions"
```

---

### Task 5: Add inv infra.backup task

**Files:**
- Modify: `infra/tasks.py`

**Step 1: Add backup task**

```python
@task(name="backup")
def backup(c):
    """Run backup to SanDisk + Cloudflare R2 (parallel)."""
    c.run(f"bash {HERE / 'backup.sh'}", pty=True)
```

**Step 2: Verify**

Run: `inv infra.backup --help`
Expected: shows help text

**Step 3: Commit**

```bash
git add infra/tasks.py
git commit -m "feat(infra): add inv infra.backup task"
```

---

### Task 6: Delete old ops pool/corpus files

**Files:**
- Delete: `ops/pool.py`
- Delete: `ops/corpus.py`

**Step 1: Remove files**

```bash
trash ops/pool.py ops/corpus.py
```

**Step 2: Verify no remaining imports**

Run: `rg "from ops\.(pool|corpus)" --type py`
Expected: no results (or only the now-unused Makefile line)

**Step 3: Commit**

```bash
git add -u ops/pool.py ops/corpus.py
git commit -m "refactor(ops): remove migrated pool.py and corpus.py"
```

---

### Task 7: Update CLAUDE.md and rebuild completions

**Files:**
- Modify: `CLAUDE.md`
- Modify: `helm/CLAUDE.md`

**Step 1: Update root CLAUDE.md**

- Remove "Known overlap in ops" section and the follow-up table
- Update CLI Tools table to reflect new locations:
  - `ops` — `ops servers`, `ops restart`, `ops resmon` — Server management + resource monitoring
  - `helm` — add `helm list`, `helm grep`, `helm pool status`, `helm corpus sync` — Session intelligence + pool
- Update the `watch/` vs `helm/` responsibility table if needed

**Step 2: Update helm/CLAUDE.md**

Add documentation for the new session intelligence commands:
```
| `sessions.py`     | Session discovery, grep, inspect, restart, idle    |
| `pool.py`         | Warm session pool management                        |
| `corpus.py`       | Chat history sync and search                        |
```

**Step 3: Rebuild completions**

```bash
cd tools/cli && make completions
```

**Step 4: Commit**

```bash
git add CLAUDE.md helm/CLAUDE.md
git commit -m "docs: update CLAUDE.md for ops CLI cleanup"
```

---

### Task 8: End-to-end verification

**Step 1: Verify ops commands**

```bash
python -m ops servers
python -m ops resmon check
python -m ops free-port --help
```

**Step 2: Verify helm commands**

```bash
python -m helm.cli list
python -m helm.cli grep "test"
python -m helm.cli idle
python -m helm.cli pool status
python -m helm.cli corpus stats
python -m helm.cli inspect --help
```

**Step 3: Verify bash wrappers**

```bash
ops servers
helm list
helm pool status
```

**Step 4: Verify imports**

```bash
python -c "from helm.sessions import idle_minutes, list_sessions, Session, cache_session"
python -c "from helm.pool import cli"
python -c "from helm.corpus import cli"
```
