---
phase: 01-script-skeleton
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - gitsl.py
autonomous: true

must_haves:
  truths:
    - "User can invoke 'gitsl status' and script identifies 'status' as the command"
    - "User can invoke 'gitsl commit -m msg' and script identifies 'commit' with args ['-m', 'msg']"
    - "User can run with GITSL_DEBUG=1 and see debug output showing what would execute"
    - "Running 'gitsl' with no arguments shows usage message and exits with code 1"
    - "Running 'gitsl --version' shows version and exits with code 0"
  artifacts:
    - path: "gitsl.py"
      provides: "Git-to-Sapling CLI shim entry point"
      min_lines: 80
      exports: ["main", "parse_argv", "ParsedCommand", "is_debug_mode"]
  key_links:
    - from: "gitsl.py"
      to: "sys.argv"
      via: "main() receives argv[1:]"
      pattern: "sys\\.argv\\[1:\\]"
    - from: "gitsl.py"
      to: "os.environ"
      via: "is_debug_mode() checks GITSL_DEBUG"
      pattern: "GITSL_DEBUG"
---

<objective>
Create the foundational gitsl.py script with argument parsing and debug mode.

Purpose: Establish the script entry point that all subsequent phases will build upon. This phase creates the skeleton that parses git-style commands without executing anything.

Output: A single Python file (gitsl.py) that:
- Parses git-style argv and extracts command + arguments
- Supports GITSL_DEBUG=1 environment variable to show what would run
- Handles edge cases (no args, --help, --version)
- Returns appropriate exit codes
</objective>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/phases/01-script-skeleton/01-RESEARCH.md
</context>

<tasks>

<task type="auto">
  <name>Task 1: Create gitsl.py script skeleton with argument parsing</name>
  <files>gitsl.py</files>
  <action>
Create gitsl.py in the project root with the following structure:

1. Shebang and module docstring explaining purpose
2. Imports: sys, os, shlex (stdlib only)
3. VERSION constant set to "0.1.0"
4. ParsedCommand dataclass with fields:
   - command: Optional[str] (the git command like "status", "commit")
   - args: List[str] (remaining arguments after command)
   - raw_argv: List[str] (original argv for debugging)
5. parse_argv(argv: List[str]) -> ParsedCommand function:
   - Handle empty argv: return ParsedCommand(command=None, args=[], raw_argv=[])
   - Extract first element as command, rest as args
   - Preserve raw_argv for debugging
6. is_debug_mode() -> bool function:
   - Check os.environ.get("GITSL_DEBUG", "").lower()
   - Return True if value in ("1", "true", "yes", "on")
7. print_debug_info(parsed: ParsedCommand) -> None function:
   - Print to stderr: command, args, what would execute
   - Use shlex.join() for safe command formatting
8. main(argv: List[str] = None) -> int function:
   - Default argv to sys.argv[1:] if None
   - Parse argv
   - Handle command=None: print usage to stderr, return 1
   - Handle --version/-v: print version, return 0
   - Handle --help/-h/help: print help, return 0
   - If debug mode: call print_debug_info(), return 0
   - Otherwise: print "[STUB] Would process: git {command}" to stderr, return 0
9. if __name__ == "__main__" guard calling sys.exit(main())

Reference the complete example in 01-RESEARCH.md "Complete Minimal Script Skeleton" section.

Key points from research:
- Use dataclass (not NamedTuple) for ParsedCommand
- Debug output goes to stderr (not stdout)
- Use shlex.join() for safe command display (not manual string join)
- Accept multiple debug values: "1", "true", "yes", "on" (case-insensitive)
  </action>
  <verify>
Run these commands and verify outputs:

```bash
# Make executable
chmod +x gitsl.py

# Test no arguments (should show usage, exit 1)
python3 gitsl.py
echo "Exit code: $?"

# Test version
python3 gitsl.py --version

# Test help
python3 gitsl.py --help

# Test command parsing
python3 gitsl.py status
python3 gitsl.py commit -m "test message"

# Test debug mode
GITSL_DEBUG=1 python3 gitsl.py status
GITSL_DEBUG=1 python3 gitsl.py commit -m "test message"
```

Expected:
- No args: "usage: git <command> [<args>]" on stderr, exit 1
- --version: "gitsl version 0.1.0", exit 0
- --help: usage text, exit 0
- status: "[STUB] Would process: git status", exit 0
- commit -m "test message": "[STUB] Would process: git commit", exit 0
- Debug mode: Shows "[DEBUG] Command: status" etc. on stderr, exit 0
  </verify>
  <done>
gitsl.py exists, is executable, correctly parses commands and arguments, shows debug info when GITSL_DEBUG=1, handles empty/help/version cases with correct exit codes.
  </done>
</task>

<task type="auto">
  <name>Task 2: Add type hints and verify Python 3.8+ compatibility</name>
  <files>gitsl.py</files>
  <action>
Ensure gitsl.py has proper type hints throughout:

1. Import from typing: List, Optional
2. All function signatures have type hints:
   - parse_argv(argv: List[str]) -> ParsedCommand
   - is_debug_mode() -> bool
   - print_debug_info(parsed: ParsedCommand) -> None
   - main(argv: List[str] = None) -> int
3. Verify no Python 3.9+ only features are used:
   - Use List[str] not list[str]
   - Use Optional[str] not str | None
   - Use typing.Dict if needed (not used in this phase)
4. Run syntax check with Python 3.8 compatible checker

Note: shlex.join() requires Python 3.8+ which is our minimum version per PROJECT.md constraints.
  </action>
  <verify>
```bash
# Check syntax is valid Python
python3 -m py_compile gitsl.py

# Run quick import test
python3 -c "import gitsl; print('Import OK')"

# Verify no syntax errors in type hints
python3 -c "from gitsl import parse_argv, is_debug_mode, main, ParsedCommand; print('All exports OK')"
```
  </verify>
  <done>
gitsl.py passes Python syntax validation, all public functions have type hints, code is compatible with Python 3.8+.
  </done>
</task>

</tasks>

<verification>
Run the complete verification sequence:

```bash
cd /Users/vmakaev/Non-Work/gitsl

# 1. File exists and is executable
test -f gitsl.py && echo "File exists: OK"
test -x gitsl.py && echo "Executable: OK"

# 2. Syntax valid
python3 -m py_compile gitsl.py && echo "Syntax: OK"

# 3. No args -> exit 1
python3 gitsl.py 2>/dev/null; test $? -eq 1 && echo "No args exit 1: OK"

# 4. Version -> exit 0
python3 gitsl.py --version >/dev/null; test $? -eq 0 && echo "Version exit 0: OK"

# 5. Help -> exit 0
python3 gitsl.py --help >/dev/null; test $? -eq 0 && echo "Help exit 0: OK"

# 6. Command parsing (stub mode)
python3 gitsl.py status 2>&1 | grep -q "STUB" && echo "Stub mode: OK"

# 7. Debug mode
GITSL_DEBUG=1 python3 gitsl.py status 2>&1 | grep -q "DEBUG" && echo "Debug mode: OK"

# 8. Debug shows would execute
GITSL_DEBUG=1 python3 gitsl.py commit -m "msg" 2>&1 | grep -q "Would execute" && echo "Debug output: OK"
```

All 8 checks should pass.
</verification>

<success_criteria>
1. gitsl.py exists in project root with 80+ lines of code
2. Script correctly identifies command from argv (status, commit, log, etc.)
3. Script preserves arguments after command (-m, --short, file paths, etc.)
4. GITSL_DEBUG=1 shows what would execute without running anything
5. Empty arguments show usage and exit 1
6. --version shows version and exits 0
7. --help shows help and exits 0
8. All verification commands pass
</success_criteria>

<output>
After completion, create `.planning/phases/01-script-skeleton/01-01-SUMMARY.md`
</output>
