handover 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- handover-0.2.0/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- handover-0.2.0/.github/ISSUE_TEMPLATE/feature_request.md +34 -0
- handover-0.2.0/.github/PULL_REQUEST_TEMPLATE.md +19 -0
- handover-0.2.0/.github/dependabot.yml +13 -0
- handover-0.2.0/.github/workflows/ci.yml +40 -0
- handover-0.2.0/.github/workflows/release.yml +89 -0
- handover-0.2.0/.gitignore +102 -0
- handover-0.2.0/.pre-commit-config.yaml +19 -0
- handover-0.2.0/CHANGELOG.md +25 -0
- handover-0.2.0/CLAUDE.md +39 -0
- handover-0.2.0/CODE_OF_CONDUCT.md +65 -0
- handover-0.2.0/CONTRIBUTING.md +62 -0
- handover-0.2.0/LICENSE +21 -0
- handover-0.2.0/PKG-INFO +144 -0
- handover-0.2.0/README.md +116 -0
- handover-0.2.0/SECURITY.md +24 -0
- handover-0.2.0/docs/adding-an-adapter.md +137 -0
- handover-0.2.0/docs/getting-started.md +79 -0
- handover-0.2.0/docs/output-format.md +126 -0
- handover-0.2.0/handover/__init__.py +7 -0
- handover-0.2.0/handover/cli.py +309 -0
- handover-0.2.0/handover/generator.py +98 -0
- handover-0.2.0/handover/heuristics.py +409 -0
- handover-0.2.0/handover/models.py +83 -0
- handover-0.2.0/handover/parsers/__init__.py +119 -0
- handover-0.2.0/handover/parsers/base.py +85 -0
- handover-0.2.0/handover/parsers/chatgpt.py +180 -0
- handover-0.2.0/handover/parsers/claude.py +283 -0
- handover-0.2.0/handover/parsers/gemini.py +93 -0
- handover-0.2.0/handover/parsers/perplexity.py +143 -0
- handover-0.2.0/handover/summarizer.py +155 -0
- handover-0.2.0/handover/templates/claude_md.j2 +46 -0
- handover-0.2.0/handover/templates/plan_md.j2 +19 -0
- handover-0.2.0/pyproject.toml +54 -0
- handover-0.2.0/scripts/install-hooks.sh +9 -0
- handover-0.2.0/scripts/pre-push +10 -0
- handover-0.2.0/tests/__init__.py +1 -0
- handover-0.2.0/tests/fixtures/chatgpt_single.json +108 -0
- handover-0.2.0/tests/fixtures/claude_bulk.jsonl +3 -0
- handover-0.2.0/tests/fixtures/claude_single.json +38 -0
- handover-0.2.0/tests/fixtures/claude_single.md +25 -0
- handover-0.2.0/tests/fixtures/gemini_single.json +41 -0
- handover-0.2.0/tests/fixtures/perplexity_bulk.json +39 -0
- handover-0.2.0/tests/fixtures/perplexity_single.json +34 -0
- handover-0.2.0/tests/test_cli.py +326 -0
- handover-0.2.0/tests/test_generator.py +141 -0
- handover-0.2.0/tests/test_heuristics.py +244 -0
- handover-0.2.0/tests/test_models.py +76 -0
- handover-0.2.0/tests/test_parser.py +360 -0
- handover-0.2.0/tests/test_summarizer.py +164 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: Report a bug or unexpected behavior in handover
|
|
4
|
+
title: '[BUG] '
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Description
|
|
10
|
+
|
|
11
|
+
A clear and concise description of what the bug is.
|
|
12
|
+
|
|
13
|
+
## Steps to Reproduce
|
|
14
|
+
|
|
15
|
+
1. Run `handover ...`
|
|
16
|
+
2. With input file of type: ...
|
|
17
|
+
3. See error
|
|
18
|
+
|
|
19
|
+
## Expected Behavior
|
|
20
|
+
|
|
21
|
+
What you expected to happen.
|
|
22
|
+
|
|
23
|
+
## Actual Behavior
|
|
24
|
+
|
|
25
|
+
What actually happened. Include the full error message or output.
|
|
26
|
+
|
|
27
|
+
## Environment
|
|
28
|
+
|
|
29
|
+
- **CLI version:** `handover --version`
|
|
30
|
+
- **Python version:** `python --version`
|
|
31
|
+
- **OS:** (e.g. macOS 14, Ubuntu 22.04, Windows 11)
|
|
32
|
+
- **Input format:** (e.g. single JSON, bulk JSONL, Markdown)
|
|
33
|
+
- **Mode:** (e.g. default / `--no-llm` / `--dry-run`)
|
|
34
|
+
|
|
35
|
+
## Additional Context
|
|
36
|
+
|
|
37
|
+
Any other context that might help (e.g. anonymized snippet of the input file that triggers the issue).
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature request
|
|
3
|
+
about: Suggest a new feature or improvement for handover
|
|
4
|
+
title: '[FEATURE] '
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ''
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem Statement
|
|
10
|
+
|
|
11
|
+
What problem does this feature solve? Who is the user experiencing it?
|
|
12
|
+
(e.g. "As a developer using Gemini for design and Claude Code for implementation, I have no way to...")
|
|
13
|
+
|
|
14
|
+
## Proposed Solution
|
|
15
|
+
|
|
16
|
+
A clear description of the feature you'd like to see. How would it work from the user's perspective?
|
|
17
|
+
|
|
18
|
+
## Alternatives Considered
|
|
19
|
+
|
|
20
|
+
What other solutions or workarounds have you considered? Why are they not sufficient?
|
|
21
|
+
|
|
22
|
+
## Phase
|
|
23
|
+
|
|
24
|
+
Which project phase does this belong to?
|
|
25
|
+
|
|
26
|
+
- [ ] Phase 1 — Claude chat → Claude Code (current)
|
|
27
|
+
- [ ] Phase 2 — Universal chat sources (ChatGPT, Gemini, Perplexity adapters)
|
|
28
|
+
- [ ] Phase 3 — Reverse handover (terminal → chat)
|
|
29
|
+
- [ ] Phase 4 — Additional target agent adapters (Aider, Goose, Codex CLI)
|
|
30
|
+
- [ ] Other / cross-cutting
|
|
31
|
+
|
|
32
|
+
## Additional Context
|
|
33
|
+
|
|
34
|
+
Any mockups, examples, or related issues that provide more context.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- Briefly describe what this PR does and why. -->
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
<!-- List the key changes made. -->
|
|
8
|
+
|
|
9
|
+
## Checklist
|
|
10
|
+
|
|
11
|
+
- [ ] Tests added (or updated) for new/changed behaviour
|
|
12
|
+
- [ ] Docs updated (README, docstrings, relevant docs/ page)
|
|
13
|
+
- [ ] If adding a new adapter: `docs/adding-an-adapter.md` guide was followed
|
|
14
|
+
- [ ] `PLAN.md` updated if any implementation tasks are now complete
|
|
15
|
+
- [ ] CI passes (no new test failures)
|
|
16
|
+
|
|
17
|
+
## Related Issues
|
|
18
|
+
|
|
19
|
+
<!-- Closes #<issue_number> -->
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "pip"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "daily"
|
|
7
|
+
open-pull-requests-limit: 5
|
|
8
|
+
|
|
9
|
+
- package-ecosystem: "github-actions"
|
|
10
|
+
directory: "/"
|
|
11
|
+
schedule:
|
|
12
|
+
interval: "weekly"
|
|
13
|
+
open-pull-requests-limit: 3
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, feature/**]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.11"
|
|
17
|
+
- name: Install dev dependencies
|
|
18
|
+
run: pip install -e ".[dev]"
|
|
19
|
+
- name: Ruff lint
|
|
20
|
+
run: ruff check handover/ tests/
|
|
21
|
+
- name: Ruff format check
|
|
22
|
+
run: ruff format --check handover/ tests/
|
|
23
|
+
- name: Mypy
|
|
24
|
+
run: mypy handover/
|
|
25
|
+
|
|
26
|
+
test:
|
|
27
|
+
needs: lint
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
strategy:
|
|
30
|
+
matrix:
|
|
31
|
+
python-version: ["3.11", "3.12"]
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
- uses: actions/setup-python@v5
|
|
35
|
+
with:
|
|
36
|
+
python-version: ${{ matrix.python-version }}
|
|
37
|
+
- name: Install dependencies
|
|
38
|
+
run: pip install -e ".[dev]"
|
|
39
|
+
- name: Run tests
|
|
40
|
+
run: pytest tests/ -v --cov=handover --cov-report=term-missing --cov-fail-under=80
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test-before-release:
|
|
10
|
+
name: Test before release
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- uses: actions/setup-python@v5
|
|
15
|
+
with:
|
|
16
|
+
python-version: "3.11"
|
|
17
|
+
- name: Install dev dependencies
|
|
18
|
+
run: pip install -e ".[dev]"
|
|
19
|
+
- name: Ruff lint
|
|
20
|
+
run: ruff check handover/ tests/
|
|
21
|
+
- name: Ruff format check
|
|
22
|
+
run: ruff format --check handover/ tests/
|
|
23
|
+
- name: Mypy
|
|
24
|
+
run: mypy handover/
|
|
25
|
+
- name: Run tests with coverage gate
|
|
26
|
+
run: pytest tests/ -v --cov=handover --cov-fail-under=80
|
|
27
|
+
|
|
28
|
+
build:
|
|
29
|
+
name: Build distribution
|
|
30
|
+
needs: test-before-release
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
- uses: actions/setup-python@v5
|
|
35
|
+
with:
|
|
36
|
+
python-version: "3.11"
|
|
37
|
+
- name: Install build tools
|
|
38
|
+
run: pip install hatchling build
|
|
39
|
+
- name: Build package
|
|
40
|
+
run: python -m build
|
|
41
|
+
- name: Store distribution packages
|
|
42
|
+
uses: actions/upload-artifact@v4
|
|
43
|
+
with:
|
|
44
|
+
name: python-package-distributions
|
|
45
|
+
path: dist/
|
|
46
|
+
|
|
47
|
+
publish-to-testpypi:
|
|
48
|
+
name: Publish to TestPyPI (dry run)
|
|
49
|
+
needs: build
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
environment:
|
|
52
|
+
name: testpypi
|
|
53
|
+
url: https://test.pypi.org/p/handover
|
|
54
|
+
permissions:
|
|
55
|
+
id-token: write # Required for TestPyPI Trusted Publisher
|
|
56
|
+
steps:
|
|
57
|
+
- name: Download distribution packages
|
|
58
|
+
uses: actions/download-artifact@v4
|
|
59
|
+
with:
|
|
60
|
+
name: python-package-distributions
|
|
61
|
+
path: dist/
|
|
62
|
+
- name: Publish to TestPyPI
|
|
63
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
64
|
+
with:
|
|
65
|
+
repository-url: https://test.pypi.org/legacy/
|
|
66
|
+
- name: Verify install from TestPyPI
|
|
67
|
+
run: |
|
|
68
|
+
pip install --index-url https://test.pypi.org/simple/ \
|
|
69
|
+
--extra-index-url https://pypi.org/simple/ \
|
|
70
|
+
handover
|
|
71
|
+
handover --version
|
|
72
|
+
|
|
73
|
+
publish-to-pypi:
|
|
74
|
+
name: Publish to PyPI
|
|
75
|
+
needs: [build, publish-to-testpypi]
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
environment:
|
|
78
|
+
name: pypi
|
|
79
|
+
url: https://pypi.org/p/handover
|
|
80
|
+
permissions:
|
|
81
|
+
id-token: write # Required for PyPI Trusted Publisher
|
|
82
|
+
steps:
|
|
83
|
+
- name: Download distribution packages
|
|
84
|
+
uses: actions/download-artifact@v4
|
|
85
|
+
with:
|
|
86
|
+
name: python-package-distributions
|
|
87
|
+
path: dist/
|
|
88
|
+
- name: Publish to PyPI
|
|
89
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
*.egg
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
eggs/
|
|
11
|
+
parts/
|
|
12
|
+
var/
|
|
13
|
+
sdist/
|
|
14
|
+
develop-eggs/
|
|
15
|
+
.installed.cfg
|
|
16
|
+
lib/
|
|
17
|
+
lib64/
|
|
18
|
+
conversations.json
|
|
19
|
+
|
|
20
|
+
# Virtual environments
|
|
21
|
+
.env
|
|
22
|
+
.venv
|
|
23
|
+
env/
|
|
24
|
+
venv/
|
|
25
|
+
ENV/
|
|
26
|
+
env.bak/
|
|
27
|
+
venv.bak/
|
|
28
|
+
|
|
29
|
+
# Distribution / packaging
|
|
30
|
+
.Python
|
|
31
|
+
pip-log.txt
|
|
32
|
+
pip-delete-this-directory.txt
|
|
33
|
+
.tox/
|
|
34
|
+
.nox/
|
|
35
|
+
.coverage
|
|
36
|
+
.coverage.*
|
|
37
|
+
.cache
|
|
38
|
+
nosetests.xml
|
|
39
|
+
coverage.xml
|
|
40
|
+
*.cover
|
|
41
|
+
*.py,cover
|
|
42
|
+
.hypothesis/
|
|
43
|
+
.pytest_cache/
|
|
44
|
+
htmlcov/
|
|
45
|
+
|
|
46
|
+
# Installers
|
|
47
|
+
*.manifest
|
|
48
|
+
*.spec
|
|
49
|
+
|
|
50
|
+
# Jupyter Notebook
|
|
51
|
+
.ipynb_checkpoints
|
|
52
|
+
|
|
53
|
+
# pyenv
|
|
54
|
+
.python-version
|
|
55
|
+
|
|
56
|
+
# Celery
|
|
57
|
+
celerybeat-schedule
|
|
58
|
+
celerybeat.pid
|
|
59
|
+
|
|
60
|
+
# SageMath parsed files
|
|
61
|
+
*.sage.py
|
|
62
|
+
|
|
63
|
+
# Environments
|
|
64
|
+
.env
|
|
65
|
+
.env.local
|
|
66
|
+
.env.*.local
|
|
67
|
+
|
|
68
|
+
# mypy
|
|
69
|
+
.mypy_cache/
|
|
70
|
+
.dmypy.json
|
|
71
|
+
dmypy.json
|
|
72
|
+
|
|
73
|
+
# Pyre type checker
|
|
74
|
+
.pyre/
|
|
75
|
+
|
|
76
|
+
# macOS
|
|
77
|
+
.DS_Store
|
|
78
|
+
.AppleDouble
|
|
79
|
+
.LSOverride
|
|
80
|
+
Icon
|
|
81
|
+
._*
|
|
82
|
+
.DocumentRevisions-V100
|
|
83
|
+
.fseventsd
|
|
84
|
+
.Spotlight-V100
|
|
85
|
+
.TemporaryItems
|
|
86
|
+
.Trashes
|
|
87
|
+
.VolumeIcon.icns
|
|
88
|
+
.com.apple.timemachine.donotpresent
|
|
89
|
+
|
|
90
|
+
# IDE
|
|
91
|
+
.idea/
|
|
92
|
+
.vscode/
|
|
93
|
+
*.swp
|
|
94
|
+
*.swo
|
|
95
|
+
*~
|
|
96
|
+
|
|
97
|
+
# handover-specific
|
|
98
|
+
.handover/
|
|
99
|
+
dev_docs/
|
|
100
|
+
|
|
101
|
+
# Claude Code project config (local only — machine-specific permissions)
|
|
102
|
+
.claude/
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.4.4
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
9
|
+
rev: v1.10.0
|
|
10
|
+
hooks:
|
|
11
|
+
- id: mypy
|
|
12
|
+
additional_dependencies: [click, anthropic, jinja2]
|
|
13
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
14
|
+
rev: v4.6.0
|
|
15
|
+
hooks:
|
|
16
|
+
- id: trailing-whitespace
|
|
17
|
+
- id: end-of-file-fixer
|
|
18
|
+
- id: check-yaml
|
|
19
|
+
- id: check-toml
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
Format based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
5
|
+
Versioning follows [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.2.0] - 2026-04-05
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- Claude adapter (`parsers/claude.py`) supporting both `.jsonl` (bulk export) and `.json` (single chat / browser extension) input formats
|
|
13
|
+
- Support for Claude bulk JSON array export format (`conversations.json`)
|
|
14
|
+
- Adapter pattern with `BaseParser` in `parsers/base.py` — extensible to future sources (ChatGPT, Gemini, etc.)
|
|
15
|
+
- Heuristic summarizer (`heuristics.py`) for keyword-based context extraction when `--no-llm` is passed
|
|
16
|
+
- LLM summarizer using Anthropic SDK (`claude-sonnet-4-6`) for AI-generated `CLAUDE.md` and `PLAN.md` artifacts
|
|
17
|
+
- Jinja2-based generator with templates for `CLAUDE.md` and `PLAN.md`
|
|
18
|
+
- CLI (`handover`) with subcommands: `run`, `list`, `init`
|
|
19
|
+
- `--no-llm` flag for offline/heuristic-only mode
|
|
20
|
+
- Full test suite with 80% coverage gate
|
|
21
|
+
- GitHub Actions CI (lint + test matrix on Python 3.11 + 3.12)
|
|
22
|
+
- GitHub Actions release pipeline to TestPyPI and PyPI via Trusted Publisher
|
|
23
|
+
|
|
24
|
+
[Unreleased]: https://github.com/mohankrishnaalavala/handover/compare/v0.2.0...HEAD
|
|
25
|
+
[0.2.0]: https://github.com/mohankrishnaalavala/handover/releases/tag/v0.2.0
|
handover-0.2.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# handover — Universal AI Chat to Local Agent Handover Tool
|
|
2
|
+
|
|
3
|
+
## Project Goal
|
|
4
|
+
CLI tool that parses AI chat exports and generates CLAUDE.md + PLAN.md
|
|
5
|
+
artifacts for local terminal agents to ingest. Phase 1: Claude chat only.
|
|
6
|
+
|
|
7
|
+
## Tech Stack
|
|
8
|
+
- Language: Python 3.11+
|
|
9
|
+
- CLI: Click (with subcommands: main, list, init)
|
|
10
|
+
- Templates: Jinja2
|
|
11
|
+
- API: Anthropic SDK (claude-sonnet-4-6 for summarization)
|
|
12
|
+
- Testing: pytest + pytest-cov
|
|
13
|
+
- Packaging: pyproject.toml / hatchling
|
|
14
|
+
|
|
15
|
+
## Architecture Rules
|
|
16
|
+
- Parser uses adapter pattern: one class per source in parsers/
|
|
17
|
+
- BaseParser in parsers/base.py defines the interface all adapters must implement
|
|
18
|
+
- Summarizer calls Claude API unless --no-llm; then delegates to heuristics.py
|
|
19
|
+
- Heuristics are keyword-rule-based — keep them simple and documented
|
|
20
|
+
- Generator uses Jinja2 templates only — never hardcode output format in Python
|
|
21
|
+
- All data models are dataclasses in models.py with full type hints
|
|
22
|
+
- schema_version must be bumped in models.py when HandoverContext fields change
|
|
23
|
+
|
|
24
|
+
## Coding Standards
|
|
25
|
+
- Type hints on all functions and methods
|
|
26
|
+
- Docstrings on all public methods
|
|
27
|
+
- Tests required for: parser output, heuristics rules, generator file output
|
|
28
|
+
- Mocked API calls in test_summarizer.py — never hit real API in tests
|
|
29
|
+
- No dependencies beyond: click, anthropic, jinja2, pytest, pytest-cov
|
|
30
|
+
|
|
31
|
+
## Key Commands
|
|
32
|
+
- Run tests: pytest tests/ -v --cov=handover
|
|
33
|
+
- Install locally: pip install -e .
|
|
34
|
+
- Run CLI: handover --help
|
|
35
|
+
|
|
36
|
+
## Phase 1 Focus
|
|
37
|
+
- Claude adapter only (parsers/claude.py)
|
|
38
|
+
- Do NOT build ChatGPT adapter yet — that is Phase 2
|
|
39
|
+
- Both input formats: .jsonl (bulk) and .json (single chat via browser extension)
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
7
|
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
8
|
+
identity and expression, level of experience, education, socio-economic status,
|
|
9
|
+
nationality, personal appearance, race, caste, color, religion, or sexual
|
|
10
|
+
identity and orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
13
|
+
diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our Standards
|
|
16
|
+
|
|
17
|
+
Examples of behavior that contributes to a positive environment:
|
|
18
|
+
|
|
19
|
+
* Demonstrating empathy and kindness toward other people
|
|
20
|
+
* Being respectful of differing opinions, viewpoints, and experiences
|
|
21
|
+
* Giving and gracefully accepting constructive feedback
|
|
22
|
+
* Accepting responsibility and apologizing to those affected by our mistakes
|
|
23
|
+
* Focusing on what is best not just for us as individuals, but for the overall community
|
|
24
|
+
|
|
25
|
+
Examples of unacceptable behavior:
|
|
26
|
+
|
|
27
|
+
* The use of sexualized language or imagery, and sexual attention or advances of any kind
|
|
28
|
+
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
29
|
+
* Public or private harassment
|
|
30
|
+
* Publishing others' private information without explicit permission
|
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
|
32
|
+
|
|
33
|
+
## Enforcement Responsibilities
|
|
34
|
+
|
|
35
|
+
Project maintainers are responsible for clarifying and enforcing our standards of
|
|
36
|
+
acceptable behavior and will take appropriate and fair corrective action in
|
|
37
|
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
38
|
+
or harmful.
|
|
39
|
+
|
|
40
|
+
## Scope
|
|
41
|
+
|
|
42
|
+
This Code of Conduct applies within all community spaces, and also applies when
|
|
43
|
+
an individual is officially representing the community in public spaces.
|
|
44
|
+
|
|
45
|
+
## Enforcement
|
|
46
|
+
|
|
47
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
48
|
+
reported by following the instructions in [SECURITY.md](SECURITY.md) or by
|
|
49
|
+
contacting the maintainer via the [GitHub profile](https://github.com/mohankrishnaalavala).
|
|
50
|
+
|
|
51
|
+
All complaints will be reviewed and investigated promptly and fairly.
|
|
52
|
+
|
|
53
|
+
## Enforcement Guidelines
|
|
54
|
+
|
|
55
|
+
**1. Correction** — Private written warning, clarity around the violation.
|
|
56
|
+
|
|
57
|
+
**2. Warning** — A warning with consequences for continued behavior.
|
|
58
|
+
|
|
59
|
+
**3. Temporary Ban** — Temporary ban from any interaction or public communication.
|
|
60
|
+
|
|
61
|
+
**4. Permanent Ban** — Permanent ban from any public interaction within the community.
|
|
62
|
+
|
|
63
|
+
## Attribution
|
|
64
|
+
|
|
65
|
+
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Contributing to handover
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing! `handover` is an open-source project and contributions are very welcome.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/mohankrishnaalavala/handover.git
|
|
9
|
+
cd handover
|
|
10
|
+
pip install -e ".[dev]"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Running Tests
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pytest tests/ -v --cov=handover --cov-report=term-missing
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
All tests must pass before submitting a PR. Never commit code that breaks existing tests.
|
|
20
|
+
|
|
21
|
+
## Primary Contribution Path: Adding a New Source Adapter
|
|
22
|
+
|
|
23
|
+
Adding a new source (ChatGPT, Gemini, Perplexity, etc.) is the primary way to contribute. Each adapter is one self-contained class in `handover/parsers/`. A contributor can own an adapter end-to-end as an isolated PR.
|
|
24
|
+
|
|
25
|
+
See **[docs/adding-an-adapter.md](docs/adding-an-adapter.md)** for the complete step-by-step guide.
|
|
26
|
+
|
|
27
|
+
In brief, adding a new adapter means:
|
|
28
|
+
1. Create `handover/parsers/{source_name}.py` — subclass `BaseParser`
|
|
29
|
+
2. Register the adapter in `parsers/__init__.py`
|
|
30
|
+
3. Add a test fixture in `tests/fixtures/`
|
|
31
|
+
4. Add tests in `tests/test_parser.py`
|
|
32
|
+
5. Update the supported formats table in `README.md`
|
|
33
|
+
6. Add the source name to the `--source` flag in `cli.py`
|
|
34
|
+
|
|
35
|
+
## Code Standards
|
|
36
|
+
|
|
37
|
+
The following standards are taken directly from `CLAUDE.md` and apply to all contributions:
|
|
38
|
+
|
|
39
|
+
- **Type hints** on all functions and methods
|
|
40
|
+
- **Docstrings** on all public methods
|
|
41
|
+
- **Tests required** for: parser output, heuristics rules, generator file output
|
|
42
|
+
- Mocked API calls in `test_summarizer.py` — never hit the real Anthropic API in tests
|
|
43
|
+
- No additional dependencies beyond: `click`, `anthropic`, `jinja2`, `pytest`, `pytest-cov`
|
|
44
|
+
|
|
45
|
+
## Submitting a Pull Request
|
|
46
|
+
|
|
47
|
+
1. Fork the repo and create a feature branch
|
|
48
|
+
2. Make your changes, add tests, update docs
|
|
49
|
+
3. Run `pytest tests/ -v` — all tests must pass
|
|
50
|
+
4. Update `PLAN.md` if your PR completes any listed tasks
|
|
51
|
+
5. Open a PR against `main` using the PR template
|
|
52
|
+
|
|
53
|
+
## Project Phases
|
|
54
|
+
|
|
55
|
+
Before contributing, it helps to understand the roadmap:
|
|
56
|
+
|
|
57
|
+
- **Phase 1** (current): Claude chat → Claude Code. This is what we're building now.
|
|
58
|
+
- **Phase 2**: Universal chat sources — ChatGPT, Gemini, Perplexity adapters. **This is the main open contribution path.**
|
|
59
|
+
- **Phase 3**: Reverse handover — Claude Code session logs → readable handover doc.
|
|
60
|
+
- **Phase 4**: Additional target agents (Aider, Goose, Codex CLI).
|
|
61
|
+
|
|
62
|
+
Please check open issues and the `PLAN.md` before starting work to avoid duplicating effort.
|
handover-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mohan Krishnaa Alavala
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|