agent-worktree-manager 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.
- agent_worktree_manager-0.2.0/LICENSE +29 -0
- agent_worktree_manager-0.2.0/MANIFEST.in +5 -0
- agent_worktree_manager-0.2.0/PKG-INFO +125 -0
- agent_worktree_manager-0.2.0/README.md +92 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/__init__.py +3 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/__main__.py +5 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/agent_skill.py +49 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/cli.py +386 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/config.py +196 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/environments.py +385 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/errors.py +5 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/git.py +96 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/inspection.py +324 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/lifecycle.py +607 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/migration.py +125 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/process.py +63 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/registry.py +100 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/shell.py +123 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/skills/awm/SKILL.md +111 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/skills/awm/agents/openai.yaml +4 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/storage.py +85 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager/tui.py +769 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager.egg-info/PKG-INFO +125 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager.egg-info/SOURCES.txt +44 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager.egg-info/dependency_links.txt +1 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager.egg-info/entry_points.txt +2 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager.egg-info/requires.txt +14 -0
- agent_worktree_manager-0.2.0/agent_worktree_manager.egg-info/top_level.txt +1 -0
- agent_worktree_manager-0.2.0/docs/agents.md +62 -0
- agent_worktree_manager-0.2.0/docs/configuration.md +74 -0
- agent_worktree_manager-0.2.0/docs/usage.md +183 -0
- agent_worktree_manager-0.2.0/examples/awm.toml +10 -0
- agent_worktree_manager-0.2.0/pyproject.toml +86 -0
- agent_worktree_manager-0.2.0/setup.cfg +4 -0
- agent_worktree_manager-0.2.0/tests/conftest.py +141 -0
- agent_worktree_manager-0.2.0/tests/test_agent_skill.py +69 -0
- agent_worktree_manager-0.2.0/tests/test_cli.py +240 -0
- agent_worktree_manager-0.2.0/tests/test_conda.py +35 -0
- agent_worktree_manager-0.2.0/tests/test_distribution.py +105 -0
- agent_worktree_manager-0.2.0/tests/test_lifecycle.py +349 -0
- agent_worktree_manager-0.2.0/tests/test_process.py +35 -0
- agent_worktree_manager-0.2.0/tests/test_projects.py +138 -0
- agent_worktree_manager-0.2.0/tests/test_release.py +98 -0
- agent_worktree_manager-0.2.0/tests/test_shell.py +244 -0
- agent_worktree_manager-0.2.0/tests/test_tui.py +156 -0
- agent_worktree_manager-0.2.0/tests/test_tui_envs.py +109 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, Jan Wyzula
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-worktree-manager
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Manage isolated Python environments and Git worktrees across projects
|
|
5
|
+
Author: Jan Wyzula
|
|
6
|
+
License-Expression: BSD-3-Clause
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Environment :: Console :: Curses
|
|
9
|
+
Classifier: Operating System :: MacOS
|
|
10
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Classifier: Topic :: Software Development
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: packaging>=23
|
|
21
|
+
Requires-Dist: platformdirs>=3
|
|
22
|
+
Requires-Dist: pip>=23.1
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
25
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
26
|
+
Requires-Dist: twine>=5; extra == "dev"
|
|
27
|
+
Requires-Dist: ruff>=0.9; extra == "dev"
|
|
28
|
+
Provides-Extra: release
|
|
29
|
+
Requires-Dist: python-semantic-release==10.6.2; extra == "release"
|
|
30
|
+
Requires-Dist: build>=1.2; extra == "release"
|
|
31
|
+
Requires-Dist: twine>=5; extra == "release"
|
|
32
|
+
Dynamic: license-file
|
|
33
|
+
|
|
34
|
+
# Agent Worktree Manager
|
|
35
|
+
|
|
36
|
+
Working on several branches or with coding agents means keeping track of both
|
|
37
|
+
source checkouts and their Python environments. `awm` pairs Git worktrees with
|
|
38
|
+
isolated environments and provides a terminal UI to browse and clean them up
|
|
39
|
+
across projects.
|
|
40
|
+
|
|
41
|
+
Start with an environment that already works. AWM reproduces its installed
|
|
42
|
+
dependencies and points selected editable packages at new worktrees. Other
|
|
43
|
+
editable packages keep their original source links. Install AWM once, separately
|
|
44
|
+
from your project environments.
|
|
45
|
+
|
|
46
|
+
Supports Python 3.11–3.14 on macOS and Linux; Git is required. Standard venv/pip
|
|
47
|
+
is the default; uv and conda backends are optional. AWM and your project
|
|
48
|
+
environments can use different Python versions.
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
From PyPI, once the first release is published, choose either:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
uv tool install agent-worktree-manager
|
|
56
|
+
# Or install into your chosen Python environment:
|
|
57
|
+
python -m pip install agent-worktree-manager
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
To install from a source checkout now, run at this repository's root:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
uv tool install --editable .
|
|
64
|
+
# Or:
|
|
65
|
+
python -m pip install -e .
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
To activate a sandbox in your current terminal from the TUI, enable shell integration:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
eval "$(awm shell-init zsh)" # use bash for Bash
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Add the same line to `~/.zshrc` (or `~/.bashrc`) to enable it in new terminals.
|
|
75
|
+
Then press `s` on a sandbox to close AWM and activate its environment.
|
|
76
|
+
|
|
77
|
+
## Register your first project
|
|
78
|
+
|
|
79
|
+
From your project's Git checkout, register its existing Python environment:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
awm init --name my-project --base /absolute/path/to/base-env --repo app=.
|
|
83
|
+
awm doctor
|
|
84
|
+
awm create my-task --repo app
|
|
85
|
+
awm run my-task -- python --version
|
|
86
|
+
awm
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`--base` is the environment directory, not its Python executable. Use
|
|
90
|
+
`--backend uv` for a uv base or `--backend conda` for a conda base. Repeat
|
|
91
|
+
`--repo ALIAS=PATH` to include more repositories. Registration writes `awm.toml`
|
|
92
|
+
and machine-specific settings in git-ignored `.awm/`, and adds the project to
|
|
93
|
+
your global overview. From elsewhere, select it with `awm --project my-project`.
|
|
94
|
+
|
|
95
|
+
## Use with coding agents
|
|
96
|
+
|
|
97
|
+
The bundled `awm` skill guides agents through creating, resuming, inspecting,
|
|
98
|
+
and cleaning up worktrees with their environments. Install it for either agent:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
# Codex
|
|
102
|
+
awm skill --install "$HOME/.agents/skills/awm"
|
|
103
|
+
# Claude Code
|
|
104
|
+
awm skill --install "$HOME/.claude/skills/awm"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
In Codex, select it through `/skills` or mention `$awm`. In Claude Code, use
|
|
108
|
+
`/awm`. For example: “create a sandbox for fixing the login tests and work there.”
|
|
109
|
+
See the [agent guide](docs/agents.md) for custom locations and updating a skill.
|
|
110
|
+
|
|
111
|
+
## Contributing
|
|
112
|
+
|
|
113
|
+
Please follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
|
|
114
|
+
for commit messages, for example `feat(tui): add sandbox shell shortcut` or
|
|
115
|
+
`fix(env): preserve editable paths`. These messages drive automated versioning
|
|
116
|
+
and release notes.
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
[BSD 3-Clause](LICENSE) — Copyright (c) 2026, Jan Wyzula.
|
|
121
|
+
|
|
122
|
+
## Documentation
|
|
123
|
+
|
|
124
|
+
[Usage](docs/usage.md) · [Configuration](docs/configuration.md) ·
|
|
125
|
+
[AI agent skill](docs/agents.md)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Agent Worktree Manager
|
|
2
|
+
|
|
3
|
+
Working on several branches or with coding agents means keeping track of both
|
|
4
|
+
source checkouts and their Python environments. `awm` pairs Git worktrees with
|
|
5
|
+
isolated environments and provides a terminal UI to browse and clean them up
|
|
6
|
+
across projects.
|
|
7
|
+
|
|
8
|
+
Start with an environment that already works. AWM reproduces its installed
|
|
9
|
+
dependencies and points selected editable packages at new worktrees. Other
|
|
10
|
+
editable packages keep their original source links. Install AWM once, separately
|
|
11
|
+
from your project environments.
|
|
12
|
+
|
|
13
|
+
Supports Python 3.11–3.14 on macOS and Linux; Git is required. Standard venv/pip
|
|
14
|
+
is the default; uv and conda backends are optional. AWM and your project
|
|
15
|
+
environments can use different Python versions.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
From PyPI, once the first release is published, choose either:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
uv tool install agent-worktree-manager
|
|
23
|
+
# Or install into your chosen Python environment:
|
|
24
|
+
python -m pip install agent-worktree-manager
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
To install from a source checkout now, run at this repository's root:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
uv tool install --editable .
|
|
31
|
+
# Or:
|
|
32
|
+
python -m pip install -e .
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
To activate a sandbox in your current terminal from the TUI, enable shell integration:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
eval "$(awm shell-init zsh)" # use bash for Bash
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Add the same line to `~/.zshrc` (or `~/.bashrc`) to enable it in new terminals.
|
|
42
|
+
Then press `s` on a sandbox to close AWM and activate its environment.
|
|
43
|
+
|
|
44
|
+
## Register your first project
|
|
45
|
+
|
|
46
|
+
From your project's Git checkout, register its existing Python environment:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
awm init --name my-project --base /absolute/path/to/base-env --repo app=.
|
|
50
|
+
awm doctor
|
|
51
|
+
awm create my-task --repo app
|
|
52
|
+
awm run my-task -- python --version
|
|
53
|
+
awm
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`--base` is the environment directory, not its Python executable. Use
|
|
57
|
+
`--backend uv` for a uv base or `--backend conda` for a conda base. Repeat
|
|
58
|
+
`--repo ALIAS=PATH` to include more repositories. Registration writes `awm.toml`
|
|
59
|
+
and machine-specific settings in git-ignored `.awm/`, and adds the project to
|
|
60
|
+
your global overview. From elsewhere, select it with `awm --project my-project`.
|
|
61
|
+
|
|
62
|
+
## Use with coding agents
|
|
63
|
+
|
|
64
|
+
The bundled `awm` skill guides agents through creating, resuming, inspecting,
|
|
65
|
+
and cleaning up worktrees with their environments. Install it for either agent:
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
# Codex
|
|
69
|
+
awm skill --install "$HOME/.agents/skills/awm"
|
|
70
|
+
# Claude Code
|
|
71
|
+
awm skill --install "$HOME/.claude/skills/awm"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
In Codex, select it through `/skills` or mention `$awm`. In Claude Code, use
|
|
75
|
+
`/awm`. For example: “create a sandbox for fixing the login tests and work there.”
|
|
76
|
+
See the [agent guide](docs/agents.md) for custom locations and updating a skill.
|
|
77
|
+
|
|
78
|
+
## Contributing
|
|
79
|
+
|
|
80
|
+
Please follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)
|
|
81
|
+
for commit messages, for example `feat(tui): add sandbox shell shortcut` or
|
|
82
|
+
`fix(env): preserve editable paths`. These messages drive automated versioning
|
|
83
|
+
and release notes.
|
|
84
|
+
|
|
85
|
+
## License
|
|
86
|
+
|
|
87
|
+
[BSD 3-Clause](LICENSE) — Copyright (c) 2026, Jan Wyzula.
|
|
88
|
+
|
|
89
|
+
## Documentation
|
|
90
|
+
|
|
91
|
+
[Usage](docs/usage.md) · [Configuration](docs/configuration.md) ·
|
|
92
|
+
[AI agent skill](docs/agents.md)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Export the bundled, agent-independent worktree skill."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import shutil
|
|
7
|
+
import tempfile
|
|
8
|
+
from importlib.resources import files
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from .errors import AWMError
|
|
12
|
+
|
|
13
|
+
SKILL_FILES = ("SKILL.md", "agents/openai.yaml")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def bundled_files() -> dict[str, bytes]:
|
|
17
|
+
root = files("agent_worktree_manager").joinpath("skills", "awm")
|
|
18
|
+
return {name: root.joinpath(*name.split("/")).read_bytes() for name in SKILL_FILES}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def install_skill(destination: Path) -> Path:
|
|
22
|
+
destination = Path(os.path.abspath(destination.expanduser()))
|
|
23
|
+
content = bundled_files()
|
|
24
|
+
if destination.is_symlink():
|
|
25
|
+
raise AWMError(f"Skill destination must not be a symlink: {destination}")
|
|
26
|
+
if destination.exists():
|
|
27
|
+
if destination.is_dir() and all(
|
|
28
|
+
(destination / name).is_file()
|
|
29
|
+
and not (destination / name).is_symlink()
|
|
30
|
+
and (destination / name).read_bytes() == value
|
|
31
|
+
for name, value in content.items()
|
|
32
|
+
):
|
|
33
|
+
return destination
|
|
34
|
+
raise AWMError(
|
|
35
|
+
f"Skill destination already exists with different contents: {destination}; "
|
|
36
|
+
"review or move the existing skill before installing"
|
|
37
|
+
)
|
|
38
|
+
destination.parent.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
temporary = Path(tempfile.mkdtemp(prefix=".awm-skill-", dir=destination.parent))
|
|
40
|
+
try:
|
|
41
|
+
for name, value in content.items():
|
|
42
|
+
path = temporary / name
|
|
43
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
44
|
+
path.write_bytes(value)
|
|
45
|
+
temporary.rename(destination)
|
|
46
|
+
finally:
|
|
47
|
+
if temporary.exists():
|
|
48
|
+
shutil.rmtree(temporary)
|
|
49
|
+
return destination
|