kanbanlan 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.
- kanbanlan-0.2.0/.agents/skills/release/SKILL.md +88 -0
- kanbanlan-0.2.0/.agents/skills/release/agents/openai.yaml +4 -0
- kanbanlan-0.2.0/.github/ISSUE_TEMPLATE/bug-report.yml +62 -0
- kanbanlan-0.2.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- kanbanlan-0.2.0/.github/ISSUE_TEMPLATE/feature-request.yml +39 -0
- kanbanlan-0.2.0/.github/dependabot.yml +14 -0
- kanbanlan-0.2.0/.github/pull_request_template.md +21 -0
- kanbanlan-0.2.0/.github/workflows/ci.yml +50 -0
- kanbanlan-0.2.0/.github/workflows/release.yaml +70 -0
- kanbanlan-0.2.0/.gitignore +8 -0
- kanbanlan-0.2.0/CONTRIBUTING.md +52 -0
- kanbanlan-0.2.0/LICENSE +21 -0
- kanbanlan-0.2.0/PKG-INFO +217 -0
- kanbanlan-0.2.0/README.md +192 -0
- kanbanlan-0.2.0/SECURITY.md +20 -0
- kanbanlan-0.2.0/pyproject.toml +56 -0
- kanbanlan-0.2.0/src/kanbanlan/__init__.py +3 -0
- kanbanlan-0.2.0/src/kanbanlan/__main__.py +3 -0
- kanbanlan-0.2.0/src/kanbanlan/cli.py +887 -0
- kanbanlan-0.2.0/src/kanbanlan/config.py +112 -0
- kanbanlan-0.2.0/src/kanbanlan/github.py +678 -0
- kanbanlan-0.2.0/src/kanbanlan/runner.py +64 -0
- kanbanlan-0.2.0/src/kanbanlan/scaffold.py +309 -0
- kanbanlan-0.2.0/src/kanbanlan/snapshot.py +424 -0
- kanbanlan-0.2.0/src/kanbanlan/workflow.py +150 -0
- kanbanlan-0.2.0/tests/test_cli.py +147 -0
- kanbanlan-0.2.0/tests/test_config.py +46 -0
- kanbanlan-0.2.0/tests/test_github.py +191 -0
- kanbanlan-0.2.0/tests/test_scaffold.py +45 -0
- kanbanlan-0.2.0/tests/test_snapshot.py +148 -0
- kanbanlan-0.2.0/tests/test_workflow.py +57 -0
- kanbanlan-0.2.0/uv.lock +108 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release
|
|
3
|
+
description: Select, prepare, publish, and verify the next Kanbanlan release on GitHub and PyPI. Use when the user invokes /release, asks to release or publish Kanbanlan, requests a version bump, or wants the next package version shipped. Choose the version without asking the user unless a non-version product decision blocks the release.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Release Kanbanlan
|
|
7
|
+
|
|
8
|
+
Release Kanbanlan end-to-end. Treat invoking this skill as authorization to
|
|
9
|
+
update versions, commit release-scoped changes, push `main` and the release tag,
|
|
10
|
+
create the GitHub Release, and publish through the `pypi` environment. Never ask
|
|
11
|
+
the user which version number to use.
|
|
12
|
+
|
|
13
|
+
## Choose the version
|
|
14
|
+
|
|
15
|
+
Inspect the latest Git tag, GitHub Release, PyPI release, current package
|
|
16
|
+
version, and changes since the latest release. Select a semantic version:
|
|
17
|
+
|
|
18
|
+
- Patch for backward-compatible fixes, documentation, tests, CI, packaging, or
|
|
19
|
+
maintenance only.
|
|
20
|
+
- Minor for new functionality or meaningful backward-compatible behavior.
|
|
21
|
+
- Major for intentional breaking changes once the project is at least `1.0`.
|
|
22
|
+
Before `1.0`, use a minor bump for breaking or substantial changes.
|
|
23
|
+
|
|
24
|
+
If there is no published release, use the prepared project version when it is
|
|
25
|
+
greater than any existing tag; otherwise choose the smallest suitable next
|
|
26
|
+
version. Never reuse a version already present on PyPI.
|
|
27
|
+
|
|
28
|
+
## Prepare
|
|
29
|
+
|
|
30
|
+
1. Read repository instructions and inspect the complete worktree, history,
|
|
31
|
+
remote, tags, GitHub Releases, Actions state, and PyPI package state.
|
|
32
|
+
2. Preserve user changes. Review every file that will ship and scan tracked and
|
|
33
|
+
untracked files for credentials or private data before staging.
|
|
34
|
+
3. Update `pyproject.toml` and `src/kanbanlan/__init__.py` to the chosen version.
|
|
35
|
+
Refresh `uv.lock`, then confirm all three versions agree and the CLI reports
|
|
36
|
+
the same value.
|
|
37
|
+
4. Update release-facing documentation when behavior, installation, supported
|
|
38
|
+
versions, or release instructions changed.
|
|
39
|
+
5. Run the full gate:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
uv lock --check
|
|
43
|
+
uv run pytest
|
|
44
|
+
uv run ruff check .
|
|
45
|
+
uv run ruff format --check .
|
|
46
|
+
uv build
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Inspect the wheel metadata and verify the source distribution and wheel use
|
|
50
|
+
the chosen version. Validate all GitHub workflow and issue-form YAML.
|
|
51
|
+
|
|
52
|
+
Do not proceed while checks fail or the worktree contains unexplained sensitive
|
|
53
|
+
material.
|
|
54
|
+
|
|
55
|
+
## Publish
|
|
56
|
+
|
|
57
|
+
1. Commit all reviewed release changes with a concise release-oriented commit
|
|
58
|
+
message and push `main`, setting its upstream when needed.
|
|
59
|
+
2. Ensure the repository has the GitHub environment `pypi`. Keep PyPI
|
|
60
|
+
authentication secretless: `.github/workflows/release.yaml` must use OIDC
|
|
61
|
+
Trusted Publishing and grant `id-token: write` only to its publish job.
|
|
62
|
+
3. Wait for every required CI job on the pushed commit. If CI fails, diagnose,
|
|
63
|
+
fix, commit, push, and wait again. Do not create the release tag before CI
|
|
64
|
+
succeeds.
|
|
65
|
+
4. Create an annotated tag named `v<version>`, push it, and create a published
|
|
66
|
+
GitHub Release from that exact tag with generated release notes.
|
|
67
|
+
5. Wait for the `release.yaml` run to finish. Do not report success based only
|
|
68
|
+
on creating the GitHub Release.
|
|
69
|
+
|
|
70
|
+
Never force-push, move a published tag, delete release history, use
|
|
71
|
+
`skip-existing`, or store a PyPI token. PyPI distributions are immutable. If a
|
|
72
|
+
published tag or partial upload makes the selected version unusable, diagnose
|
|
73
|
+
the state and prepare a new patch version instead of rewriting history.
|
|
74
|
+
|
|
75
|
+
## Verify
|
|
76
|
+
|
|
77
|
+
Confirm all of the following before declaring success:
|
|
78
|
+
|
|
79
|
+
- GitHub `main` points at the intended release commit and is clean locally.
|
|
80
|
+
- The tag and GitHub Release exist and target that commit.
|
|
81
|
+
- CI and the release workflow completed successfully.
|
|
82
|
+
- PyPI reports the chosen version for `kanbanlan`.
|
|
83
|
+
- A clean temporary `uvx --from kanbanlan==<version> kanbanlan --version`
|
|
84
|
+
invocation reports the same version.
|
|
85
|
+
|
|
86
|
+
Report the chosen version, commit, tag, GitHub Release URL, PyPI URL, workflow
|
|
87
|
+
results, and verification commands. If an external service is still processing,
|
|
88
|
+
keep monitoring rather than handing off an incomplete release.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report reproducible behavior that is incorrect or unexpected.
|
|
3
|
+
title: "[Bug] "
|
|
4
|
+
body:
|
|
5
|
+
- type: markdown
|
|
6
|
+
attributes:
|
|
7
|
+
value: |
|
|
8
|
+
Thanks for reporting a bug. Remove secrets and private repository data
|
|
9
|
+
from all commands, output, configuration, and snapshots.
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: summary
|
|
13
|
+
attributes:
|
|
14
|
+
label: Summary
|
|
15
|
+
description: What happened, and what did you expect instead?
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: reproduction
|
|
21
|
+
attributes:
|
|
22
|
+
label: Steps to reproduce
|
|
23
|
+
placeholder: |
|
|
24
|
+
1. Run `kanbanlan ...`
|
|
25
|
+
2. ...
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: input
|
|
30
|
+
id: version
|
|
31
|
+
attributes:
|
|
32
|
+
label: Kanbanlan version
|
|
33
|
+
description: Output from `kanbanlan --version`.
|
|
34
|
+
placeholder: kanbanlan X.Y.Z
|
|
35
|
+
validations:
|
|
36
|
+
required: true
|
|
37
|
+
|
|
38
|
+
- type: input
|
|
39
|
+
id: environment
|
|
40
|
+
attributes:
|
|
41
|
+
label: Environment
|
|
42
|
+
description: Operating system, Python version, and GitHub CLI version.
|
|
43
|
+
placeholder: macOS 15, Python 3.13, gh 2.x
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
|
|
47
|
+
- type: textarea
|
|
48
|
+
id: diagnostics
|
|
49
|
+
attributes:
|
|
50
|
+
label: Relevant diagnostic output
|
|
51
|
+
description: Include sanitized errors or `kanbanlan doctor` output.
|
|
52
|
+
render: text
|
|
53
|
+
|
|
54
|
+
- type: checkboxes
|
|
55
|
+
id: checks
|
|
56
|
+
attributes:
|
|
57
|
+
label: Pre-submission checks
|
|
58
|
+
options:
|
|
59
|
+
- label: I removed credentials and private repository data from this report.
|
|
60
|
+
required: true
|
|
61
|
+
- label: I searched existing issues for the same problem.
|
|
62
|
+
required: true
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest a focused improvement to Kanbanlan.
|
|
3
|
+
title: "[Feature] "
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: problem
|
|
7
|
+
attributes:
|
|
8
|
+
label: Problem
|
|
9
|
+
description: What workflow problem should Kanbanlan solve?
|
|
10
|
+
validations:
|
|
11
|
+
required: true
|
|
12
|
+
|
|
13
|
+
- type: textarea
|
|
14
|
+
id: outcome
|
|
15
|
+
attributes:
|
|
16
|
+
label: Desired outcome
|
|
17
|
+
description: Describe the behavior or result you would like.
|
|
18
|
+
validations:
|
|
19
|
+
required: true
|
|
20
|
+
|
|
21
|
+
- type: textarea
|
|
22
|
+
id: alternatives
|
|
23
|
+
attributes:
|
|
24
|
+
label: Alternatives considered
|
|
25
|
+
description: How do you handle this today, and what tradeoffs did you find?
|
|
26
|
+
|
|
27
|
+
- type: textarea
|
|
28
|
+
id: context
|
|
29
|
+
attributes:
|
|
30
|
+
label: Additional context
|
|
31
|
+
description: Add sanitized examples or links that clarify the request.
|
|
32
|
+
|
|
33
|
+
- type: checkboxes
|
|
34
|
+
id: checks
|
|
35
|
+
attributes:
|
|
36
|
+
label: Pre-submission checks
|
|
37
|
+
options:
|
|
38
|
+
- label: I searched existing issues for a similar request.
|
|
39
|
+
required: true
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: uv
|
|
4
|
+
directory: /
|
|
5
|
+
schedule:
|
|
6
|
+
interval: weekly
|
|
7
|
+
groups:
|
|
8
|
+
development-dependencies:
|
|
9
|
+
dependency-type: development
|
|
10
|
+
|
|
11
|
+
- package-ecosystem: github-actions
|
|
12
|
+
directory: /
|
|
13
|
+
schedule:
|
|
14
|
+
interval: weekly
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
<!-- What problem does this pull request solve? -->
|
|
4
|
+
|
|
5
|
+
## Changes
|
|
6
|
+
|
|
7
|
+
<!-- List the important user-visible or implementation changes. -->
|
|
8
|
+
|
|
9
|
+
## Verification
|
|
10
|
+
|
|
11
|
+
<!-- List automated checks and relevant manual verification. -->
|
|
12
|
+
|
|
13
|
+
- [ ] `uv run pytest`
|
|
14
|
+
- [ ] `uv run ruff check .`
|
|
15
|
+
- [ ] `uv run ruff format --check .`
|
|
16
|
+
- [ ] `uv build`
|
|
17
|
+
- [ ] Tests and documentation were updated where needed.
|
|
18
|
+
|
|
19
|
+
## Security and compatibility
|
|
20
|
+
|
|
21
|
+
<!-- Note credential handling, GitHub API changes, compatibility risks, or write "None". -->
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: Python ${{ matrix.python-version }}
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
python-version: ["3.11", "3.12", "3.13", "3.14"]
|
|
20
|
+
|
|
21
|
+
steps:
|
|
22
|
+
- name: Check out repository
|
|
23
|
+
uses: actions/checkout@v7
|
|
24
|
+
|
|
25
|
+
- name: Install uv
|
|
26
|
+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
27
|
+
with:
|
|
28
|
+
version: "0.11.16"
|
|
29
|
+
enable-cache: true
|
|
30
|
+
|
|
31
|
+
- name: Install Python
|
|
32
|
+
run: uv python install "${{ matrix.python-version }}"
|
|
33
|
+
|
|
34
|
+
- name: Install project
|
|
35
|
+
run: uv sync --locked --group dev --python "${{ matrix.python-version }}"
|
|
36
|
+
|
|
37
|
+
- name: Run tests
|
|
38
|
+
run: uv run pytest
|
|
39
|
+
|
|
40
|
+
- name: Run lint
|
|
41
|
+
if: matrix.python-version == '3.14'
|
|
42
|
+
run: uv run ruff check .
|
|
43
|
+
|
|
44
|
+
- name: Check formatting
|
|
45
|
+
if: matrix.python-version == '3.14'
|
|
46
|
+
run: uv run ruff format --check .
|
|
47
|
+
|
|
48
|
+
- name: Build distributions
|
|
49
|
+
if: matrix.python-version == '3.14'
|
|
50
|
+
run: uv build
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: pypi
|
|
12
|
+
cancel-in-progress: false
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
build:
|
|
16
|
+
name: Build distributions
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
timeout-minutes: 10
|
|
19
|
+
|
|
20
|
+
steps:
|
|
21
|
+
- name: Check out repository
|
|
22
|
+
uses: actions/checkout@v7
|
|
23
|
+
|
|
24
|
+
- name: Install uv
|
|
25
|
+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
26
|
+
with:
|
|
27
|
+
version: "0.11.16"
|
|
28
|
+
enable-cache: true
|
|
29
|
+
|
|
30
|
+
- name: Verify release tag
|
|
31
|
+
env:
|
|
32
|
+
RELEASE_TAG: ${{ github.event.release.tag_name }}
|
|
33
|
+
run: |
|
|
34
|
+
package_version="$(uv version --short)"
|
|
35
|
+
if [[ "$RELEASE_TAG" != "v$package_version" ]]; then
|
|
36
|
+
echo "Release tag $RELEASE_TAG does not match package version $package_version."
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
- name: Build distributions
|
|
41
|
+
run: uv build
|
|
42
|
+
|
|
43
|
+
- name: Upload distributions
|
|
44
|
+
uses: actions/upload-artifact@v7
|
|
45
|
+
with:
|
|
46
|
+
name: python-package-distributions
|
|
47
|
+
path: dist/
|
|
48
|
+
if-no-files-found: error
|
|
49
|
+
retention-days: 7
|
|
50
|
+
|
|
51
|
+
publish:
|
|
52
|
+
name: Publish to PyPI
|
|
53
|
+
needs: build
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
timeout-minutes: 10
|
|
56
|
+
environment:
|
|
57
|
+
name: pypi
|
|
58
|
+
url: https://pypi.org/p/kanbanlan
|
|
59
|
+
permissions:
|
|
60
|
+
id-token: write
|
|
61
|
+
|
|
62
|
+
steps:
|
|
63
|
+
- name: Download distributions
|
|
64
|
+
uses: actions/download-artifact@v7
|
|
65
|
+
with:
|
|
66
|
+
name: python-package-distributions
|
|
67
|
+
path: dist/
|
|
68
|
+
|
|
69
|
+
- name: Publish distributions to PyPI
|
|
70
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Contributing to Kanbanlan
|
|
2
|
+
|
|
3
|
+
Thanks for helping improve Kanbanlan. Bug reports, documentation fixes, and
|
|
4
|
+
small, focused feature changes are welcome.
|
|
5
|
+
|
|
6
|
+
## Development setup
|
|
7
|
+
|
|
8
|
+
Kanbanlan requires Python 3.11 or newer, Git, GitHub CLI, and uv.
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
git clone https://github.com/jmitchel3/kanbanlan.git
|
|
12
|
+
cd kanbanlan
|
|
13
|
+
uv sync --group dev
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Run the same checks used in CI before opening a pull request:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
uv run pytest
|
|
20
|
+
uv run ruff check .
|
|
21
|
+
uv run ruff format --check .
|
|
22
|
+
uv build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Proposing a change
|
|
26
|
+
|
|
27
|
+
1. Open an issue for bugs or substantial changes so the intended behavior can
|
|
28
|
+
be agreed on before implementation.
|
|
29
|
+
2. Keep each pull request focused on one outcome and add or update tests for
|
|
30
|
+
behavior changes.
|
|
31
|
+
3. Update user-facing documentation when commands, configuration, or workflow
|
|
32
|
+
behavior changes.
|
|
33
|
+
4. Explain the change and verification performed in the pull request template.
|
|
34
|
+
|
|
35
|
+
Never include GitHub tokens, repository snapshots, or `.kanbanlan.toml` files
|
|
36
|
+
from private repositories in reports or fixtures.
|
|
37
|
+
|
|
38
|
+
## Releasing
|
|
39
|
+
|
|
40
|
+
Releases use PyPI Trusted Publishing, so no long-lived PyPI token is stored in
|
|
41
|
+
GitHub. Before the first release:
|
|
42
|
+
|
|
43
|
+
1. Create a GitHub environment named `pypi` and add any desired deployment
|
|
44
|
+
reviewers.
|
|
45
|
+
2. Configure the PyPI Trusted Publisher for owner `jmitchel3`, repository
|
|
46
|
+
`kanbanlan`, workflow `release.yaml`, and environment `pypi`.
|
|
47
|
+
|
|
48
|
+
To publish a release, update the version in `pyproject.toml` and `uv.lock`, then
|
|
49
|
+
publish a GitHub Release whose tag is `v` followed by that exact version, such
|
|
50
|
+
as tag `v1.2.3` for package version `1.2.3`. The release workflow builds the
|
|
51
|
+
distributions in an unprivileged job and publishes them from the protected
|
|
52
|
+
`pypi` environment.
|
kanbanlan-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Justin Mitchel
|
|
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.
|
kanbanlan-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kanbanlan
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Reusable GitHub Projects request coordination for humans and coding agents.
|
|
5
|
+
Project-URL: Homepage, https://github.com/jmitchel3/kanbanlan
|
|
6
|
+
Project-URL: Documentation, https://github.com/jmitchel3/kanbanlan#readme
|
|
7
|
+
Project-URL: Issues, https://github.com/jmitchel3/kanbanlan/issues
|
|
8
|
+
Project-URL: Source, https://github.com/jmitchel3/kanbanlan
|
|
9
|
+
Author: Justin Mitchel
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: cli,coding-agents,github,kanban,project-management
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# Kanbanlan
|
|
27
|
+
|
|
28
|
+
[](https://github.com/jmitchel3/kanbanlan/actions/workflows/ci.yml)
|
|
29
|
+
[](https://github.com/jmitchel3/kanbanlan/blob/main/LICENSE)
|
|
30
|
+
|
|
31
|
+
Kanbanlan turns a GitHub repository and a GitHub Projects v2 board into one
|
|
32
|
+
coordinated request workflow for humans and coding agents.
|
|
33
|
+
|
|
34
|
+
It provides:
|
|
35
|
+
|
|
36
|
+
- one-command repository and Project setup;
|
|
37
|
+
- browser-based GitHub CLI authentication when credentials or the `project`
|
|
38
|
+
scope are missing;
|
|
39
|
+
- repository labels, issue/PR templates, and managed `AGENTS.md` /
|
|
40
|
+
`CLAUDE.md` instructions;
|
|
41
|
+
- a private local snapshot shared across Git worktrees;
|
|
42
|
+
- dry-run-first reconciliation between issue labels, Project Status, active
|
|
43
|
+
claims, and linked pull requests; and
|
|
44
|
+
- safe capture, claim, release, handoff, and review commands.
|
|
45
|
+
|
|
46
|
+
GitHub Issues remain canonical. Kanbanlan does not store API tokens and does
|
|
47
|
+
not create another server-side database.
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
Kanbanlan requires Python 3.11+, Git, and
|
|
52
|
+
[GitHub CLI](https://cli.github.com/). The examples below use
|
|
53
|
+
[uv](https://docs.astral.sh/uv/) for installation and development.
|
|
54
|
+
|
|
55
|
+
Install the latest release from PyPI:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
uv tool install kanbanlan
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Or install the unreleased development version from GitHub:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
uv tool install git+https://github.com/jmitchel3/kanbanlan.git
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
To install a local checkout instead:
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
uv tool install .
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
For development:
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
uv sync --group dev
|
|
77
|
+
uv run pytest
|
|
78
|
+
uv run ruff check .
|
|
79
|
+
uv build
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Initialize a repository
|
|
83
|
+
|
|
84
|
+
Start the guided setup wizard from any GitHub-backed repository:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
cd /path/to/repository
|
|
88
|
+
kanbanlan init
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The wizard detects the repository and default branch, lets you reuse, create,
|
|
92
|
+
or copy a GitHub Project, collects the staging and optional production branch,
|
|
93
|
+
then shows a summary for confirmation before it changes repository files or
|
|
94
|
+
Project settings.
|
|
95
|
+
|
|
96
|
+
You can also provide any choice up front. Reuse an existing Project:
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
cd /path/to/repository
|
|
100
|
+
kanbanlan init --project-url https://github.com/orgs/acme/projects/2
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Create a new Project:
|
|
104
|
+
|
|
105
|
+
```sh
|
|
106
|
+
kanbanlan init --create-project --project-title "Product Delivery" --open
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Copy a Project template, including its useful views:
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
kanbanlan init --template-project template-owner/1 --project-title "Product Delivery"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`init` authenticates through
|
|
116
|
+
`gh auth login --web` when necessary, ensures the GitHub token has the
|
|
117
|
+
`project` scope, links the Project to the repository, repairs the Status field,
|
|
118
|
+
creates the workflow labels, writes managed repository files, adds open issues,
|
|
119
|
+
and reconciles their state.
|
|
120
|
+
|
|
121
|
+
Use `--non-interactive` in automation and provide `--project-number`,
|
|
122
|
+
`--project-url`, `--create-project`, or `--template-project` explicitly.
|
|
123
|
+
Use `--local-only` to generate repository files without GitHub mutations.
|
|
124
|
+
Pass `--no-open` to suppress the wizard's browser question or `--open` to open
|
|
125
|
+
the configured Project after setup.
|
|
126
|
+
|
|
127
|
+
Kanbanlan does not yet create custom Project views or GitHub's built-in
|
|
128
|
+
auto-add workflow. Copying a template Project is the automated path when those
|
|
129
|
+
views matter. Without a template, `kanbanlan init --open` opens the Project so
|
|
130
|
+
a Board view can be added once. Kanbanlan's own `reconcile --apply` keeps item
|
|
131
|
+
states correct even when GitHub Project workflows are not configured.
|
|
132
|
+
|
|
133
|
+
## Daily use
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
kanbanlan ensure # refresh only when the worktree-shared cache is stale
|
|
137
|
+
kanbanlan next # report the first unblocked Ready issue
|
|
138
|
+
kanbanlan status # summarize the local cache
|
|
139
|
+
kanbanlan reconcile # report drift, without mutations
|
|
140
|
+
kanbanlan reconcile --apply # apply and verify the displayed repairs
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The cache lives at `<primary-checkout>/.cache/kanbanlan/` with private file
|
|
144
|
+
permissions. A failed refresh preserves the last good snapshot and records the
|
|
145
|
+
error in `health.json`.
|
|
146
|
+
|
|
147
|
+
## Request lifecycle
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
kanbanlan capture "Add export audit log" --priority priority:p1
|
|
151
|
+
kanbanlan claim 123 --touchpoints "audit API; exports UI; migrations"
|
|
152
|
+
kanbanlan review 123
|
|
153
|
+
kanbanlan release 123 --reason "Waiting for product decision" --blocked
|
|
154
|
+
kanbanlan handoff 123 --session codex-next --branch work/123-audit \\
|
|
155
|
+
--worktree /path/to/worktree --reason "Shift change"
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
By default `claim` posts the claim first, verifies that it is the earliest
|
|
159
|
+
active claim, and only then creates a dedicated worktree from the configured
|
|
160
|
+
default branch. If checkout creation fails, it releases the claim and returns
|
|
161
|
+
the card to Ready. Use `--no-worktree` only from an existing non-default
|
|
162
|
+
branch/worktree.
|
|
163
|
+
|
|
164
|
+
## Managed repository files
|
|
165
|
+
|
|
166
|
+
`init` writes:
|
|
167
|
+
|
|
168
|
+
- `.kanbanlan.toml`;
|
|
169
|
+
- `.github/ISSUE_TEMPLATE/work-request.yml`;
|
|
170
|
+
- `.github/pull_request_template.md`;
|
|
171
|
+
- `docs/workflow/kanbanlan.md`;
|
|
172
|
+
- a marked Kanbanlan section in `AGENTS.md` and `CLAUDE.md`; and
|
|
173
|
+
- `/.cache/kanbanlan/` in `.gitignore`.
|
|
174
|
+
|
|
175
|
+
Generated standalone files carry a marker. Existing custom templates are not
|
|
176
|
+
overwritten unless `--force` is passed. Agent instruction sections are
|
|
177
|
+
updated only between `kanbanlan:start` and `kanbanlan:end` markers.
|
|
178
|
+
|
|
179
|
+
## State model
|
|
180
|
+
|
|
181
|
+
| Issue label | Project Status |
|
|
182
|
+
| --- | --- |
|
|
183
|
+
| `status:intake` | Inbox |
|
|
184
|
+
| `status:ready` | Ready |
|
|
185
|
+
| `status:in-progress` | In progress |
|
|
186
|
+
| `status:blocked` | Blocked |
|
|
187
|
+
| `status:review` | In review |
|
|
188
|
+
| closed issue | Done |
|
|
189
|
+
|
|
190
|
+
Priorities are `priority:p0` through `priority:p3`. An active CLAIM forces In
|
|
191
|
+
progress; an open pull request that closes the issue forces In review; a closed
|
|
192
|
+
issue forces Done. Issue labels are the fallback status record when the
|
|
193
|
+
Project is temporarily unavailable.
|
|
194
|
+
|
|
195
|
+
## Diagnostics
|
|
196
|
+
|
|
197
|
+
```sh
|
|
198
|
+
kanbanlan auth
|
|
199
|
+
kanbanlan doctor
|
|
200
|
+
kanbanlan path
|
|
201
|
+
kanbanlan snapshot
|
|
202
|
+
kanbanlan refresh
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
`doctor` checks configuration, authentication, Project Status options, labels,
|
|
206
|
+
and cache health without mutating GitHub.
|
|
207
|
+
|
|
208
|
+
## Contributing and security
|
|
209
|
+
|
|
210
|
+
Bug reports and focused pull requests are welcome. See
|
|
211
|
+
[CONTRIBUTING.md](https://github.com/jmitchel3/kanbanlan/blob/main/CONTRIBUTING.md)
|
|
212
|
+
for the development workflow. Please report security vulnerabilities privately
|
|
213
|
+
as described in
|
|
214
|
+
[SECURITY.md](https://github.com/jmitchel3/kanbanlan/blob/main/SECURITY.md).
|
|
215
|
+
|
|
216
|
+
Kanbanlan is available under the
|
|
217
|
+
[MIT License](https://github.com/jmitchel3/kanbanlan/blob/main/LICENSE).
|