---
phase: 12-packaging
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - pyproject.toml
  - common.py
  - LICENSE
  - README.md
autonomous: true

must_haves:
  truths:
    - "`pip install -e .` succeeds without errors"
    - "`gitsl` command is available in PATH after install"
    - "`gitsl --version` displays version from git tag"
    - "All Python modules are importable after install"
  artifacts:
    - path: "pyproject.toml"
      provides: "Package configuration with setuptools and entry points"
      contains: "[project.scripts]"
    - path: "common.py"
      provides: "Dynamic version from importlib.metadata"
      contains: "importlib.metadata"
    - path: "LICENSE"
      provides: "MIT license for package"
      min_lines: 10
    - path: "README.md"
      provides: "Package description for PyPI"
      min_lines: 5
  key_links:
    - from: "pyproject.toml"
      to: "gitsl:main"
      via: "console_scripts entry point"
      pattern: 'gitsl = "gitsl:main"'
    - from: "common.py"
      to: "gitsl package"
      via: "importlib.metadata.version()"
      pattern: 'version\\("gitsl"\\)'
---

<objective>
Create Python package configuration for gitsl with pip installability.

Purpose: Enable installation via `pip install -e .` (local) and prepare for PyPI publishing (Phase 13).
Output: pyproject.toml with setuptools configuration, dynamic version from git tags, LICENSE, minimal README.
</objective>

<execution_context>
@~/.claude/get-shit-done/workflows/execute-plan.md
@~/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/12-packaging/12-RESEARCH.md

@gitsl.py
@common.py
</context>

<tasks>

<task type="auto">
  <name>Task 1: Create package configuration files</name>
  <files>pyproject.toml, LICENSE, README.md</files>
  <action>
Create three files for package configuration:

1. **pyproject.toml** with:
   - Build system: setuptools>=80, setuptools-scm>=8
   - Project name: "gitsl"
   - Description: "Git to Sapling CLI shim"
   - License: MIT
   - requires-python: ">=3.8"
   - Classifiers: Beta, Console, Developers, MIT, OS Independent, Python 3.8-3.12, VCS
   - dynamic = ["version"] (setuptools-scm)
   - Entry point: `gitsl = "gitsl:main"`
   - Explicit py-modules list (CRITICAL for flat layout):
     - gitsl, common, cmd_add, cmd_commit, cmd_diff, cmd_init, cmd_log, cmd_rev_parse, cmd_status
   - [tool.setuptools_scm] with fallback_version = "0.0.0"
   - Project URLs pointing to GitHub (use placeholder owner/gitsl for now)

2. **LICENSE** - MIT license with current year and placeholder author

3. **README.md** - Minimal placeholder:
   - Title: gitsl
   - One-line description
   - Note: "Full documentation in Phase 14"
   - This is required for pyproject.toml readme field

Reference research example in 12-RESEARCH.md for exact pyproject.toml structure.
  </action>
  <verify>All three files exist and pyproject.toml is valid TOML: `python -c "import tomllib; tomllib.load(open('pyproject.toml', 'rb'))"`</verify>
  <done>pyproject.toml, LICENSE, README.md exist with correct content</done>
</task>

<task type="auto">
  <name>Task 2: Update common.py for dynamic version</name>
  <files>common.py</files>
  <action>
Modify common.py to get VERSION from package metadata instead of hardcoded string.

Replace the hardcoded `VERSION = "0.1.0"` with:

```python
from importlib.metadata import version, PackageNotFoundError

try:
    VERSION = version("gitsl")
except PackageNotFoundError:
    VERSION = "0.0.0"  # Fallback for uninstalled development
```

Add the import at the top with other imports. Remove the old hardcoded VERSION line.

This enables `gitsl --version` to show the correct version derived from git tags when installed.
  </action>
  <verify>`python -c "from common import VERSION; print(VERSION)"` prints "0.0.0" (not installed yet)</verify>
  <done>common.py uses importlib.metadata for VERSION with fallback</done>
</task>

<task type="auto">
  <name>Task 3: Verify package installation</name>
  <files>None (verification only)</files>
  <action>
Verify the package installs correctly and the gitsl command works:

1. Install in editable mode:
   ```bash
   pip install -e .
   ```

2. Verify command is available:
   ```bash
   which gitsl
   gitsl --version
   ```
   Version should show git-derived version (from v1.0 tag or dev version)

3. Verify all modules are importable:
   ```bash
   python -c "import gitsl; import common; import cmd_status; import cmd_log; import cmd_diff; import cmd_init; import cmd_rev_parse; import cmd_add; import cmd_commit"
   ```

4. Build wheel and check contents:
   ```bash
   pip install build
   python -m build --wheel
   unzip -l dist/gitsl-*.whl | grep -E '\.(py|txt)$'
   ```
   Wheel should contain all cmd_*.py files and NOT contain tests/

5. Run existing tests to confirm nothing broken:
   ```bash
   ./test
   ```
  </action>
  <verify>All verification steps pass: install succeeds, gitsl command works, version displays, modules import, wheel contains correct files</verify>
  <done>Package installs correctly, gitsl command available in PATH, version from git tag displayed</done>
</task>

</tasks>

<verification>
Phase 12 complete when:
1. `pip install -e .` succeeds without errors
2. `which gitsl` returns path in venv bin
3. `gitsl --version` shows version (1.0.devN or similar from git)
4. `python -c "import gitsl, common, cmd_status"` succeeds
5. `python -m build --wheel` creates wheel with all modules
6. `./test` passes (existing functionality preserved)
</verification>

<success_criteria>
- PACK-01: pyproject.toml exists with metadata and entry points
- PACK-02: (Phase 13) - local install works as prerequisite
- PACK-03: `gitsl` command available in PATH after `pip install -e .`
- PACK-04: Version from git tag via setuptools-scm
</success_criteria>

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