planpilot 1.0.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.
Files changed (33) hide show
  1. planpilot-1.0.0/LICENSE +21 -0
  2. planpilot-1.0.0/PKG-INFO +199 -0
  3. planpilot-1.0.0/README.md +175 -0
  4. planpilot-1.0.0/pyproject.toml +119 -0
  5. planpilot-1.0.0/src/planpilot/__init__.py +4 -0
  6. planpilot-1.0.0/src/planpilot/__main__.py +8 -0
  7. planpilot-1.0.0/src/planpilot/cli.py +196 -0
  8. planpilot-1.0.0/src/planpilot/config.py +41 -0
  9. planpilot-1.0.0/src/planpilot/exceptions.py +45 -0
  10. planpilot-1.0.0/src/planpilot/models/__init__.py +45 -0
  11. planpilot-1.0.0/src/planpilot/models/enums.py +13 -0
  12. planpilot-1.0.0/src/planpilot/models/plan.py +98 -0
  13. planpilot-1.0.0/src/planpilot/models/project.py +137 -0
  14. planpilot-1.0.0/src/planpilot/models/sync.py +38 -0
  15. planpilot-1.0.0/src/planpilot/plan/__init__.py +7 -0
  16. planpilot-1.0.0/src/planpilot/plan/hasher.py +22 -0
  17. planpilot-1.0.0/src/planpilot/plan/loader.py +41 -0
  18. planpilot-1.0.0/src/planpilot/plan/validator.py +70 -0
  19. planpilot-1.0.0/src/planpilot/providers/__init__.py +8 -0
  20. planpilot-1.0.0/src/planpilot/providers/base.py +202 -0
  21. planpilot-1.0.0/src/planpilot/providers/github/__init__.py +5 -0
  22. planpilot-1.0.0/src/planpilot/providers/github/client.py +115 -0
  23. planpilot-1.0.0/src/planpilot/providers/github/mapper.py +168 -0
  24. planpilot-1.0.0/src/planpilot/providers/github/provider.py +541 -0
  25. planpilot-1.0.0/src/planpilot/providers/github/queries.py +127 -0
  26. planpilot-1.0.0/src/planpilot/rendering/__init__.py +10 -0
  27. planpilot-1.0.0/src/planpilot/rendering/base.py +95 -0
  28. planpilot-1.0.0/src/planpilot/rendering/components.py +60 -0
  29. planpilot-1.0.0/src/planpilot/rendering/markdown.py +120 -0
  30. planpilot-1.0.0/src/planpilot/slice.py +75 -0
  31. planpilot-1.0.0/src/planpilot/sync/__init__.py +5 -0
  32. planpilot-1.0.0/src/planpilot/sync/engine.py +460 -0
  33. planpilot-1.0.0/src/planpilot/sync/relations.py +54 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 aryeko
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.
@@ -0,0 +1,199 @@
1
+ Metadata-Version: 2.4
2
+ Name: planpilot
3
+ Version: 1.0.0
4
+ Summary: Sync roadmap plans (epics, stories, tasks) to GitHub Issues and Projects v2
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Keywords: github,projects,roadmap,sync,issues
8
+ Author: aryeko
9
+ Requires-Python: >=3.11
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Topic :: Software Development :: Build Tools
19
+ Requires-Dist: pydantic (>=2.12.5,<3.0.0)
20
+ Project-URL: Homepage, https://github.com/aryeko/planpilot
21
+ Project-URL: Repository, https://github.com/aryeko/planpilot
22
+ Description-Content-Type: text/markdown
23
+
24
+ # planpilot
25
+
26
+ [![CI](https://github.com/aryeko/planpilot/actions/workflows/ci.yml/badge.svg)](https://github.com/aryeko/planpilot/actions/workflows/ci.yml)
27
+ [![codecov](https://codecov.io/gh/aryeko/planpilot/graph/badge.svg?token=3I2A515YTI)](https://codecov.io/gh/aryeko/planpilot)
28
+ [![PyPI](https://img.shields.io/pypi/v/planpilot)](https://pypi.org/project/planpilot/)
29
+ [![Python](https://img.shields.io/pypi/pyversions/planpilot)](https://pypi.org/project/planpilot/)
30
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
31
+
32
+ Sync roadmap plans (epics, stories, tasks) to GitHub Issues and Projects v2.
33
+
34
+ ## What it does
35
+
36
+ **planpilot** takes structured plan files and turns them into a fully linked project board:
37
+
38
+ ```mermaid
39
+ flowchart LR
40
+ A["roadmap.md"] --> B["epics.json\nstories.json\ntasks.json"]
41
+ B -->|planpilot| C["GitHub Issues\n+ Projects v2"]
42
+ C --> D["Epic / Story / Task\nissue types"]
43
+ C --> E["Sub-issue\nhierarchy"]
44
+ C --> F["Blocked-by\ndependencies"]
45
+ C --> G["Project fields\nstatus, priority,\niteration, size"]
46
+ ```
47
+
48
+ - **One-way sync**: local plan files -> GitHub
49
+ - **Idempotent**: safe to rerun -- updates existing issues via markers
50
+ - **Dry-run first**: preview all changes before applying
51
+ - **Multi-epic**: slice large plans and sync each epic sequentially
52
+ - **Provider-agnostic**: adapter pattern supports GitHub today, with Jira/Linear planned
53
+ - **Async-first**: built on asyncio for fast, concurrent sync operations
54
+
55
+ ## Architecture
56
+
57
+ planpilot follows SOLID principles with a modular, provider-agnostic design:
58
+
59
+ ```text
60
+ src/planpilot/
61
+ ├── models/ # Pydantic domain models (Plan, Epic, Story, Task, …)
62
+ ├── plan/ # Plan loading, validation, and hashing
63
+ ├── providers/ # Provider adapter pattern (ABC + implementations)
64
+ │ └── github/ # GitHub adapter (gh CLI)
65
+ ├── rendering/ # Issue body rendering (Protocol + Markdown impl)
66
+ ├── sync/ # Sync engine orchestrator + relation logic
67
+ ├── config.py # SyncConfig (pydantic)
68
+ ├── exceptions.py # Custom exception hierarchy
69
+ ├── cli.py # CLI entry point
70
+ └── slice.py # Multi-epic plan slicing
71
+ ```
72
+
73
+ The sync engine depends only on abstract interfaces (`Provider` ABC and `BodyRenderer` Protocol), making it easy to add new providers (Jira, Linear) without touching the core sync logic.
74
+
75
+ See [docs/architecture.md](docs/architecture.md) for the full architecture guide.
76
+
77
+ ## Requirements
78
+
79
+ - Python 3.11+
80
+ - [`gh` CLI](https://cli.github.com/) installed and authenticated
81
+ - GitHub token scopes: `repo`, `project`
82
+
83
+ ## Installation
84
+
85
+ ```bash
86
+ pip install planpilot
87
+ ```
88
+
89
+ Or with Poetry:
90
+
91
+ ```bash
92
+ poetry add planpilot
93
+ ```
94
+
95
+ ## Quickstart
96
+
97
+ ### 1. Dry-run (preview changes)
98
+
99
+ ```bash
100
+ planpilot \
101
+ --repo your-org/your-repo \
102
+ --project-url https://github.com/orgs/your-org/projects/1 \
103
+ --epics-path .plans/epics.json \
104
+ --stories-path .plans/stories.json \
105
+ --tasks-path .plans/tasks.json \
106
+ --sync-path .plans/github-sync-map.json \
107
+ --dry-run
108
+ ```
109
+
110
+ ### 2. Apply changes
111
+
112
+ ```bash
113
+ planpilot \
114
+ --repo your-org/your-repo \
115
+ --project-url https://github.com/orgs/your-org/projects/1 \
116
+ --epics-path .plans/epics.json \
117
+ --stories-path .plans/stories.json \
118
+ --tasks-path .plans/tasks.json \
119
+ --sync-path .plans/github-sync-map.json \
120
+ --apply
121
+ ```
122
+
123
+ ### 3. Multi-epic plans
124
+
125
+ The sync tool expects one epic per run. For multi-epic plans, slice first:
126
+
127
+ ```bash
128
+ planpilot-slice \
129
+ --epics-path .plans/epics.json \
130
+ --stories-path .plans/stories.json \
131
+ --tasks-path .plans/tasks.json \
132
+ --out-dir .plans/tmp
133
+ ```
134
+
135
+ Then sync each epic:
136
+
137
+ ```bash
138
+ for f in .plans/tmp/epics.*.json; do
139
+ id=$(basename "$f" .json | sed 's/epics\.//')
140
+ planpilot \
141
+ --repo your-org/your-repo \
142
+ --project-url https://github.com/orgs/your-org/projects/1 \
143
+ --epics-path ".plans/tmp/epics.${id}.json" \
144
+ --stories-path ".plans/tmp/stories.${id}.json" \
145
+ --tasks-path ".plans/tmp/tasks.${id}.json" \
146
+ --sync-path ".plans/github-sync-map.${id}.json" \
147
+ --apply
148
+ done
149
+ ```
150
+
151
+ ## Optional flags
152
+
153
+ | Flag | Default | Description |
154
+ |------|---------|-------------|
155
+ | `--label` | `codex` | Label applied to created issues |
156
+ | `--status` | `Backlog` | Project status field value |
157
+ | `--priority` | `P1` | Project priority field value |
158
+ | `--iteration` | `active` | Iteration title, `active`, or `none` |
159
+ | `--size-field` | `Size` | Project size field name |
160
+ | `--no-size-from-tshirt` | off | Disable t-shirt size mapping |
161
+ | `--verbose` | off | Enable verbose logging |
162
+
163
+ Full CLI reference: [docs/cli-reference.md](docs/cli-reference.md)
164
+
165
+ ## Plan file schemas
166
+
167
+ See [docs/schemas.md](docs/schemas.md) for the expected structure of `epics.json`, `stories.json`, and `tasks.json`, with full examples.
168
+
169
+ A complete working example is in the [examples/](examples/) directory, including sample rendered issue bodies and a sync-map output.
170
+
171
+ ## Documentation
172
+
173
+ - [How It Works](docs/how-it-works.md) -- sync pipeline, idempotency, what gets created
174
+ - [CLI Reference](docs/cli-reference.md) -- all flags and commands
175
+ - [Plan Schemas](docs/schemas.md) -- JSON format with examples and validation rules
176
+ - [Architecture](docs/architecture.md) -- module map, data flow, provider pattern, extension guide
177
+ - [Release Guide](RELEASE.md) -- automated versioning, publishing, and release pipeline
178
+
179
+ ## Development
180
+
181
+ Development tasks use [poethepoet](https://github.com/nat-n/poethepoet):
182
+
183
+ ```bash
184
+ poe lint # ruff check
185
+ poe format # ruff format
186
+ poe test # pytest -v
187
+ poe coverage # pytest + HTML coverage report
188
+ poe typecheck # mypy
189
+ poe check # lint + format-check + tests (all-in-one)
190
+ ```
191
+
192
+ ## Contributing
193
+
194
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and development instructions.
195
+
196
+ ## License
197
+
198
+ [MIT](LICENSE)
199
+
@@ -0,0 +1,175 @@
1
+ # planpilot
2
+
3
+ [![CI](https://github.com/aryeko/planpilot/actions/workflows/ci.yml/badge.svg)](https://github.com/aryeko/planpilot/actions/workflows/ci.yml)
4
+ [![codecov](https://codecov.io/gh/aryeko/planpilot/graph/badge.svg?token=3I2A515YTI)](https://codecov.io/gh/aryeko/planpilot)
5
+ [![PyPI](https://img.shields.io/pypi/v/planpilot)](https://pypi.org/project/planpilot/)
6
+ [![Python](https://img.shields.io/pypi/pyversions/planpilot)](https://pypi.org/project/planpilot/)
7
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
+
9
+ Sync roadmap plans (epics, stories, tasks) to GitHub Issues and Projects v2.
10
+
11
+ ## What it does
12
+
13
+ **planpilot** takes structured plan files and turns them into a fully linked project board:
14
+
15
+ ```mermaid
16
+ flowchart LR
17
+ A["roadmap.md"] --> B["epics.json\nstories.json\ntasks.json"]
18
+ B -->|planpilot| C["GitHub Issues\n+ Projects v2"]
19
+ C --> D["Epic / Story / Task\nissue types"]
20
+ C --> E["Sub-issue\nhierarchy"]
21
+ C --> F["Blocked-by\ndependencies"]
22
+ C --> G["Project fields\nstatus, priority,\niteration, size"]
23
+ ```
24
+
25
+ - **One-way sync**: local plan files -> GitHub
26
+ - **Idempotent**: safe to rerun -- updates existing issues via markers
27
+ - **Dry-run first**: preview all changes before applying
28
+ - **Multi-epic**: slice large plans and sync each epic sequentially
29
+ - **Provider-agnostic**: adapter pattern supports GitHub today, with Jira/Linear planned
30
+ - **Async-first**: built on asyncio for fast, concurrent sync operations
31
+
32
+ ## Architecture
33
+
34
+ planpilot follows SOLID principles with a modular, provider-agnostic design:
35
+
36
+ ```text
37
+ src/planpilot/
38
+ ├── models/ # Pydantic domain models (Plan, Epic, Story, Task, …)
39
+ ├── plan/ # Plan loading, validation, and hashing
40
+ ├── providers/ # Provider adapter pattern (ABC + implementations)
41
+ │ └── github/ # GitHub adapter (gh CLI)
42
+ ├── rendering/ # Issue body rendering (Protocol + Markdown impl)
43
+ ├── sync/ # Sync engine orchestrator + relation logic
44
+ ├── config.py # SyncConfig (pydantic)
45
+ ├── exceptions.py # Custom exception hierarchy
46
+ ├── cli.py # CLI entry point
47
+ └── slice.py # Multi-epic plan slicing
48
+ ```
49
+
50
+ The sync engine depends only on abstract interfaces (`Provider` ABC and `BodyRenderer` Protocol), making it easy to add new providers (Jira, Linear) without touching the core sync logic.
51
+
52
+ See [docs/architecture.md](docs/architecture.md) for the full architecture guide.
53
+
54
+ ## Requirements
55
+
56
+ - Python 3.11+
57
+ - [`gh` CLI](https://cli.github.com/) installed and authenticated
58
+ - GitHub token scopes: `repo`, `project`
59
+
60
+ ## Installation
61
+
62
+ ```bash
63
+ pip install planpilot
64
+ ```
65
+
66
+ Or with Poetry:
67
+
68
+ ```bash
69
+ poetry add planpilot
70
+ ```
71
+
72
+ ## Quickstart
73
+
74
+ ### 1. Dry-run (preview changes)
75
+
76
+ ```bash
77
+ planpilot \
78
+ --repo your-org/your-repo \
79
+ --project-url https://github.com/orgs/your-org/projects/1 \
80
+ --epics-path .plans/epics.json \
81
+ --stories-path .plans/stories.json \
82
+ --tasks-path .plans/tasks.json \
83
+ --sync-path .plans/github-sync-map.json \
84
+ --dry-run
85
+ ```
86
+
87
+ ### 2. Apply changes
88
+
89
+ ```bash
90
+ planpilot \
91
+ --repo your-org/your-repo \
92
+ --project-url https://github.com/orgs/your-org/projects/1 \
93
+ --epics-path .plans/epics.json \
94
+ --stories-path .plans/stories.json \
95
+ --tasks-path .plans/tasks.json \
96
+ --sync-path .plans/github-sync-map.json \
97
+ --apply
98
+ ```
99
+
100
+ ### 3. Multi-epic plans
101
+
102
+ The sync tool expects one epic per run. For multi-epic plans, slice first:
103
+
104
+ ```bash
105
+ planpilot-slice \
106
+ --epics-path .plans/epics.json \
107
+ --stories-path .plans/stories.json \
108
+ --tasks-path .plans/tasks.json \
109
+ --out-dir .plans/tmp
110
+ ```
111
+
112
+ Then sync each epic:
113
+
114
+ ```bash
115
+ for f in .plans/tmp/epics.*.json; do
116
+ id=$(basename "$f" .json | sed 's/epics\.//')
117
+ planpilot \
118
+ --repo your-org/your-repo \
119
+ --project-url https://github.com/orgs/your-org/projects/1 \
120
+ --epics-path ".plans/tmp/epics.${id}.json" \
121
+ --stories-path ".plans/tmp/stories.${id}.json" \
122
+ --tasks-path ".plans/tmp/tasks.${id}.json" \
123
+ --sync-path ".plans/github-sync-map.${id}.json" \
124
+ --apply
125
+ done
126
+ ```
127
+
128
+ ## Optional flags
129
+
130
+ | Flag | Default | Description |
131
+ |------|---------|-------------|
132
+ | `--label` | `codex` | Label applied to created issues |
133
+ | `--status` | `Backlog` | Project status field value |
134
+ | `--priority` | `P1` | Project priority field value |
135
+ | `--iteration` | `active` | Iteration title, `active`, or `none` |
136
+ | `--size-field` | `Size` | Project size field name |
137
+ | `--no-size-from-tshirt` | off | Disable t-shirt size mapping |
138
+ | `--verbose` | off | Enable verbose logging |
139
+
140
+ Full CLI reference: [docs/cli-reference.md](docs/cli-reference.md)
141
+
142
+ ## Plan file schemas
143
+
144
+ See [docs/schemas.md](docs/schemas.md) for the expected structure of `epics.json`, `stories.json`, and `tasks.json`, with full examples.
145
+
146
+ A complete working example is in the [examples/](examples/) directory, including sample rendered issue bodies and a sync-map output.
147
+
148
+ ## Documentation
149
+
150
+ - [How It Works](docs/how-it-works.md) -- sync pipeline, idempotency, what gets created
151
+ - [CLI Reference](docs/cli-reference.md) -- all flags and commands
152
+ - [Plan Schemas](docs/schemas.md) -- JSON format with examples and validation rules
153
+ - [Architecture](docs/architecture.md) -- module map, data flow, provider pattern, extension guide
154
+ - [Release Guide](RELEASE.md) -- automated versioning, publishing, and release pipeline
155
+
156
+ ## Development
157
+
158
+ Development tasks use [poethepoet](https://github.com/nat-n/poethepoet):
159
+
160
+ ```bash
161
+ poe lint # ruff check
162
+ poe format # ruff format
163
+ poe test # pytest -v
164
+ poe coverage # pytest + HTML coverage report
165
+ poe typecheck # mypy
166
+ poe check # lint + format-check + tests (all-in-one)
167
+ ```
168
+
169
+ ## Contributing
170
+
171
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for setup and development instructions.
172
+
173
+ ## License
174
+
175
+ [MIT](LICENSE)
@@ -0,0 +1,119 @@
1
+ [tool.poetry]
2
+ name = "planpilot"
3
+ version = "1.0.0"
4
+ description = "Sync roadmap plans (epics, stories, tasks) to GitHub Issues and Projects v2"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ authors = ["aryeko"]
8
+ homepage = "https://github.com/aryeko/planpilot"
9
+ repository = "https://github.com/aryeko/planpilot"
10
+ keywords = ["github", "projects", "roadmap", "sync", "issues"]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Intended Audience :: Developers",
14
+ "Topic :: Software Development :: Build Tools",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ "Programming Language :: Python :: 3.14",
21
+ ]
22
+ packages = [{include = "planpilot", from = "src"}]
23
+
24
+ [tool.poetry.scripts]
25
+ planpilot = "planpilot.cli:main"
26
+ planpilot-slice = "planpilot.slice:slice_cli"
27
+
28
+ [tool.poetry.dependencies]
29
+ python = ">=3.11"
30
+ pydantic = "^2.12.5"
31
+
32
+ [tool.poetry.group.dev.dependencies]
33
+ pytest = ">=7.0"
34
+ ruff = ">=0.4"
35
+ mypy = ">=1.0"
36
+ pytest-cov = "^7.0.0"
37
+ pytest-asyncio = "^1.3.0"
38
+ commitlint = ">=1.3"
39
+ poethepoet = "^0.40.0"
40
+
41
+ [build-system]
42
+ requires = ["poetry-core"]
43
+ build-backend = "poetry.core.masonry.api"
44
+
45
+ [tool.poe.tasks]
46
+ lint = "ruff check ."
47
+ format = "ruff format ."
48
+ format-check = "ruff format --check ."
49
+ test = "pytest -v"
50
+ coverage = "pytest -v --cov-report=html:.coverage/html"
51
+ typecheck = "mypy src/planpilot"
52
+ check = ["lint", "format-check", "test"]
53
+
54
+ [tool.pytest.ini_options]
55
+ testpaths = ["tests"]
56
+ addopts = "--cov=planpilot --cov-report=term-missing --cov-report=xml:.coverage/coverage.xml"
57
+ asyncio_mode = "auto"
58
+
59
+ [tool.coverage.run]
60
+ source = ["planpilot"]
61
+ branch = true
62
+ data_file = ".coverage/coverage.db"
63
+
64
+ [tool.coverage.report]
65
+ show_missing = true
66
+ skip_empty = true
67
+ exclude_lines = [
68
+ "pragma: no cover",
69
+ "if __name__ == .__main__.",
70
+ "if TYPE_CHECKING:",
71
+ ]
72
+
73
+ [tool.ruff]
74
+ target-version = "py311"
75
+ line-length = 120
76
+ src = ["src", "tests"]
77
+
78
+ [tool.ruff.lint]
79
+ select = [
80
+ "E", # pycodestyle errors
81
+ "F", # pyflakes
82
+ "I", # isort
83
+ "UP", # pyupgrade
84
+ "B", # bugbear
85
+ "SIM", # simplify
86
+ "RUF", # ruff-specific
87
+ ]
88
+
89
+ [tool.ruff.lint.isort]
90
+ known-first-party = ["planpilot"]
91
+
92
+ [tool.mypy]
93
+ python_version = "3.11"
94
+ warn_return_any = true
95
+ warn_unused_configs = true
96
+ disallow_untyped_defs = true
97
+ plugins = ["pydantic.mypy"]
98
+
99
+ [tool.semantic_release]
100
+ version_toml = ["pyproject.toml:tool.poetry.version"]
101
+ version_variables = ["src/planpilot/__init__.py:__version__"]
102
+ commit_parser = "conventional"
103
+ commit_message = "chore(release): {version}"
104
+ tag_format = "v{version}"
105
+ major_on_zero = true
106
+ allow_zero_version = true
107
+
108
+ [tool.semantic_release.commit_parser_options]
109
+ minor_tags = ["feat"]
110
+ patch_tags = ["fix", "perf"]
111
+
112
+ [tool.semantic_release.branches.main]
113
+ match = "main"
114
+
115
+ [tool.semantic_release.changelog]
116
+ mode = "update"
117
+
118
+ [tool.semantic_release.remote]
119
+ type = "github"
@@ -0,0 +1,4 @@
1
+ """planpilot — sync roadmap plans to GitHub Issues and Projects v2."""
2
+
3
+ __all__ = ["__version__"]
4
+ __version__ = "1.0.0"
@@ -0,0 +1,8 @@
1
+ """Allow running planpilot as ``python -m planpilot``."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from planpilot.cli import main
6
+
7
+ if __name__ == "__main__":
8
+ raise SystemExit(main())