---
phase: 03-execution-pipeline
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - gitsl.py
  - common.py
  - cmd_status.py
autonomous: true

must_haves:
  truths:
    - "gitsl.py contains only entry point dispatch, no command logic"
    - "Shared utilities live in common.py"
    - "Command handlers are in separate cmd_*.py files"
  artifacts:
    - path: "gitsl.py"
      provides: "Entry point with dispatch only"
      max_lines: 60
    - path: "common.py"
      provides: "ParsedCommand, parse_argv, is_debug_mode, print_debug_info"
      exports: ["ParsedCommand", "parse_argv", "is_debug_mode", "print_debug_info"]
    - path: "cmd_status.py"
      provides: "Handler for status command"
      exports: ["handle"]
  key_links:
    - from: "gitsl.py"
      to: "common.py"
      via: "import parse_argv, is_debug_mode"
      pattern: "from common import"
    - from: "gitsl.py"
      to: "cmd_status.py"
      via: "handler dispatch"
      pattern: "cmd_status\\.handle"
---

<objective>
Refactor gitsl.py into multi-file architecture

Purpose: Satisfy ARCH-01 through ARCH-04 - separate entry point from shared logic and command handlers
Output: gitsl.py (entry point only), common.py (shared utilities), cmd_status.py (first command handler)
</objective>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/phases/03-execution-pipeline/03-RESEARCH.md
@gitsl.py
</context>

<tasks>

<task type="auto">
  <name>Task 1: Create common.py with shared utilities</name>
  <files>common.py</files>
  <action>
Create common.py containing all shared utilities currently in gitsl.py:

1. Move these from gitsl.py to common.py:
   - `ParsedCommand` dataclass (unchanged)
   - `parse_argv()` function (unchanged)
   - `is_debug_mode()` function (unchanged)
   - `print_debug_info()` function (unchanged)
   - `VERSION` constant

2. Add new stub function for subprocess execution (implementation in Plan 02):
   ```python
   def run_sl(args: List[str]) -> int:
       """Execute sl command with I/O passthrough. Stub for Plan 02."""
       print(f"[STUB] Would run: sl {shlex.join(args)}", file=sys.stderr)
       return 0
   ```

3. Ensure all imports are present (sys, os, shlex, dataclass, List, Optional)

4. Add module docstring explaining purpose
  </action>
  <verify>python -c "from common import ParsedCommand, parse_argv, is_debug_mode, print_debug_info, run_sl, VERSION"</verify>
  <done>common.py exports all shared utilities and passes import check</done>
</task>

<task type="auto">
  <name>Task 2: Create cmd_status.py handler</name>
  <files>cmd_status.py</files>
  <action>
Create cmd_status.py following the handler interface pattern from research:

```python
"""Handler for 'git status' command."""

from common import ParsedCommand, run_sl


def handle(parsed: ParsedCommand) -> int:
    """
    Handle 'git status' command.

    Translates to 'sl status' and passes through all arguments.
    """
    return run_sl(["status"] + parsed.args)
```

This is the template for all future cmd_*.py files.
  </action>
  <verify>python -c "from cmd_status import handle; print('OK')"</verify>
  <done>cmd_status.py exports handle() function</done>
</task>

<task type="auto">
  <name>Task 3: Refactor gitsl.py to entry-point-only</name>
  <files>gitsl.py</files>
  <action>
Refactor gitsl.py to be entry-point-only:

1. Remove: ParsedCommand, parse_argv, is_debug_mode, print_debug_info, VERSION
2. Import from common: parse_argv, is_debug_mode, print_debug_info, VERSION
3. Import command handler: import cmd_status

4. Update main() to dispatch to handler:
   ```python
   # Replace the [STUB] Would process block with:
   if parsed.command == "status":
       return cmd_status.handle(parsed)

   # Keep fallback for unimplemented commands
   print(f"[STUB] Would process: git {parsed.command}", file=sys.stderr)
   return 0
   ```

5. Keep the shebang, module docstring, sys import
6. Keep special flag handling (--version, --help)
7. Keep if __name__ == "__main__" guard

Target: gitsl.py should be ~50-60 lines (currently 125 lines)
  </action>
  <verify>
python gitsl.py status 2>&1 | grep -q "STUB.*Would run" && echo "Dispatch works"
python gitsl.py --version | grep -q "gitsl version" && echo "Version works"
python gitsl.py 2>&1 | grep -q "usage:" && echo "No-args works"
GITSL_DEBUG=1 python gitsl.py status 2>&1 | grep -q "DEBUG" && echo "Debug works"
  </verify>
  <done>gitsl.py is entry-point-only (~50-60 lines), dispatches status to handler, all existing behavior preserved</done>
</task>

</tasks>

<verification>
All architectural requirements verified:
- ARCH-01: gitsl.py contains only dispatch (wc -l shows ~50-60 lines)
- ARCH-02: common.py contains shared utilities
- ARCH-03: cmd_status.py exists as separate file
- ARCH-04: cmd_status.py exports handle() function

Run existing tests to ensure no regressions:
```bash
python -m pytest tests/ -v
```
</verification>

<success_criteria>
1. gitsl.py is ~50-60 lines (down from 125)
2. common.py exports: ParsedCommand, parse_argv, is_debug_mode, print_debug_info, run_sl, VERSION
3. cmd_status.py exports: handle
4. `python gitsl.py status` dispatches to cmd_status and shows stub message
5. All existing behaviors preserved (--version, --help, empty args, debug mode)
6. pytest passes (existing tests still work)
</success_criteria>

<output>
After completion, create `.planning/phases/03-execution-pipeline/03-01-SUMMARY.md`
</output>
