do-again 0.1.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.
- do_again-0.1.0/.github/workflows/ci.yml +23 -0
- do_again-0.1.0/.github/workflows/release.yml +40 -0
- do_again-0.1.0/.gitignore +9 -0
- do_again-0.1.0/LICENSE +9 -0
- do_again-0.1.0/PKG-INFO +111 -0
- do_again-0.1.0/README.md +76 -0
- do_again-0.1.0/pyproject.toml +40 -0
- do_again-0.1.0/src/do_again/__init__.py +0 -0
- do_again-0.1.0/src/do_again/cli.py +63 -0
- do_again-0.1.0/src/do_again/core/__init__.py +0 -0
- do_again-0.1.0/src/do_again/core/agent.py +402 -0
- do_again-0.1.0/src/do_again/core/executor.py +1298 -0
- do_again-0.1.0/src/do_again/core/schema.py +116 -0
- do_again-0.1.0/src/do_again/platforms/__init__.py +0 -0
- do_again-0.1.0/src/do_again/platforms/base.py +10 -0
- do_again-0.1.0/src/do_again/platforms/detect.py +16 -0
- do_again-0.1.0/src/do_again/platforms/linux.py +7 -0
- do_again-0.1.0/src/do_again/platforms/macos.py +7 -0
- do_again-0.1.0/src/do_again/platforms/windows.py +5 -0
- do_again-0.1.0/src/do_again/service/__init__.py +0 -0
- do_again-0.1.0/templates/policy.json +137 -0
- do_again-0.1.0/tests/test_executor.py +708 -0
- do_again-0.1.0/tests/test_platforms.py +29 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
14
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
15
|
+
runs-on: ${{ matrix.os }}
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: ${{ matrix.python-version }}
|
|
21
|
+
- run: python -m pip install -e .
|
|
22
|
+
- run: python -m unittest discover -s tests -v
|
|
23
|
+
- run: do-again doctor
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.13"
|
|
19
|
+
- run: python -m pip install --upgrade build twine
|
|
20
|
+
- run: python -m build
|
|
21
|
+
- run: python -m twine check dist/*
|
|
22
|
+
- uses: actions/upload-artifact@v4
|
|
23
|
+
with:
|
|
24
|
+
name: python-package-distributions
|
|
25
|
+
path: dist/
|
|
26
|
+
|
|
27
|
+
publish:
|
|
28
|
+
needs: build
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
environment:
|
|
31
|
+
name: pypi
|
|
32
|
+
url: https://pypi.org/p/do-again
|
|
33
|
+
permissions:
|
|
34
|
+
id-token: write
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/download-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: python-package-distributions
|
|
39
|
+
path: dist/
|
|
40
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
do_again-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Steven Tran
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
do_again-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: do-again
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Policy-controlled local execution for agent-driven development workflows
|
|
5
|
+
Project-URL: Homepage, https://github.com/Tran-Steven/do-again
|
|
6
|
+
Project-URL: Repository, https://github.com/Tran-Steven/do-again
|
|
7
|
+
Project-URL: Issues, https://github.com/Tran-Steven/do-again/issues
|
|
8
|
+
Author: Steven Tran
|
|
9
|
+
License: MIT License
|
|
10
|
+
|
|
11
|
+
Copyright (c) 2026 Steven Tran
|
|
12
|
+
|
|
13
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Keywords: agents,automation,developer-tools,github,local-execution,orchestration
|
|
20
|
+
Classifier: Development Status :: 3 - Alpha
|
|
21
|
+
Classifier: Environment :: Console
|
|
22
|
+
Classifier: Intended Audience :: Developers
|
|
23
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
24
|
+
Classifier: Operating System :: MacOS
|
|
25
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
26
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
27
|
+
Classifier: Programming Language :: Python :: 3
|
|
28
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
29
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
30
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
31
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
32
|
+
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
33
|
+
Requires-Python: >=3.11
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# Do Again
|
|
37
|
+
|
|
38
|
+
[](https://github.com/Tran-Steven/do-again/actions/workflows/ci.yml)
|
|
39
|
+
[](https://pypi.org/project/do-again/)
|
|
40
|
+
[](https://pypi.org/project/do-again/)
|
|
41
|
+
[](LICENSE)
|
|
42
|
+
|
|
43
|
+
Do Again is a policy-controlled local execution layer for agent-driven development workflows. It lets an agent submit scoped work to a developer machine, receive auditable receipts and artifacts, inspect the result, and continue working when another pass is needed.
|
|
44
|
+
|
|
45
|
+
## Install
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pip install do-again
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The installed command is:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
do-again
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Quick start
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
do-again doctor
|
|
61
|
+
do-again init
|
|
62
|
+
do-again status
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Why Do Again
|
|
66
|
+
|
|
67
|
+
- Explicit policy-based command permissions
|
|
68
|
+
- GitHub-backed request and receipt transport
|
|
69
|
+
- Persistent local background execution architecture
|
|
70
|
+
- Project-scoped filesystem and command access
|
|
71
|
+
- Deterministic audit trail and recovery
|
|
72
|
+
- No agent API keys embedded in the project
|
|
73
|
+
- A shared platform interface for macOS, Linux, and Windows
|
|
74
|
+
|
|
75
|
+
## Platform status
|
|
76
|
+
|
|
77
|
+
| Platform | Status | Service backend |
|
|
78
|
+
| --- | --- | --- |
|
|
79
|
+
| macOS | Core working | launchd |
|
|
80
|
+
| Linux | Adapter scaffolded | systemd user service |
|
|
81
|
+
| Windows | Adapter scaffolded | Windows service |
|
|
82
|
+
|
|
83
|
+
Do Again is currently alpha software. macOS is the first active platform while Linux and Windows service integration are being completed behind the same interface.
|
|
84
|
+
|
|
85
|
+
## Development
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
git clone https://github.com/Tran-Steven/do-again.git
|
|
89
|
+
cd do-again
|
|
90
|
+
python -m pip install -e .
|
|
91
|
+
python -m unittest discover -s tests -v
|
|
92
|
+
do-again doctor
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Release model
|
|
96
|
+
|
|
97
|
+
Releases use semantic versioning. Pushing a version tag such as `v0.1.0` builds a wheel and source distribution, validates both artifacts, and publishes them to PyPI through Trusted Publishing.
|
|
98
|
+
|
|
99
|
+
PyPI distribution name: `do-again`
|
|
100
|
+
|
|
101
|
+
CLI command: `do-again`
|
|
102
|
+
|
|
103
|
+
Python package: `do_again`
|
|
104
|
+
|
|
105
|
+
## Security
|
|
106
|
+
|
|
107
|
+
Do Again is designed around explicit allowlists, scoped filesystem roots, bounded execution, and auditable request/receipt records. It should not be configured as unrestricted shell access.
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
MIT
|
do_again-0.1.0/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Do Again
|
|
2
|
+
|
|
3
|
+
[](https://github.com/Tran-Steven/do-again/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/do-again/)
|
|
5
|
+
[](https://pypi.org/project/do-again/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
Do Again is a policy-controlled local execution layer for agent-driven development workflows. It lets an agent submit scoped work to a developer machine, receive auditable receipts and artifacts, inspect the result, and continue working when another pass is needed.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install do-again
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The installed command is:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
do-again
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
do-again doctor
|
|
26
|
+
do-again init
|
|
27
|
+
do-again status
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Why Do Again
|
|
31
|
+
|
|
32
|
+
- Explicit policy-based command permissions
|
|
33
|
+
- GitHub-backed request and receipt transport
|
|
34
|
+
- Persistent local background execution architecture
|
|
35
|
+
- Project-scoped filesystem and command access
|
|
36
|
+
- Deterministic audit trail and recovery
|
|
37
|
+
- No agent API keys embedded in the project
|
|
38
|
+
- A shared platform interface for macOS, Linux, and Windows
|
|
39
|
+
|
|
40
|
+
## Platform status
|
|
41
|
+
|
|
42
|
+
| Platform | Status | Service backend |
|
|
43
|
+
| --- | --- | --- |
|
|
44
|
+
| macOS | Core working | launchd |
|
|
45
|
+
| Linux | Adapter scaffolded | systemd user service |
|
|
46
|
+
| Windows | Adapter scaffolded | Windows service |
|
|
47
|
+
|
|
48
|
+
Do Again is currently alpha software. macOS is the first active platform while Linux and Windows service integration are being completed behind the same interface.
|
|
49
|
+
|
|
50
|
+
## Development
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
git clone https://github.com/Tran-Steven/do-again.git
|
|
54
|
+
cd do-again
|
|
55
|
+
python -m pip install -e .
|
|
56
|
+
python -m unittest discover -s tests -v
|
|
57
|
+
do-again doctor
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Release model
|
|
61
|
+
|
|
62
|
+
Releases use semantic versioning. Pushing a version tag such as `v0.1.0` builds a wheel and source distribution, validates both artifacts, and publishes them to PyPI through Trusted Publishing.
|
|
63
|
+
|
|
64
|
+
PyPI distribution name: `do-again`
|
|
65
|
+
|
|
66
|
+
CLI command: `do-again`
|
|
67
|
+
|
|
68
|
+
Python package: `do_again`
|
|
69
|
+
|
|
70
|
+
## Security
|
|
71
|
+
|
|
72
|
+
Do Again is designed around explicit allowlists, scoped filesystem roots, bounded execution, and auditable request/receipt records. It should not be configured as unrestricted shell access.
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
MIT
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "do-again"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Policy-controlled local execution for agent-driven development workflows"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = {file = "LICENSE"}
|
|
12
|
+
authors = [{name = "Steven Tran"}]
|
|
13
|
+
keywords = ["agents", "automation", "developer-tools", "github", "orchestration", "local-execution"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: MacOS",
|
|
20
|
+
"Operating System :: Microsoft :: Windows",
|
|
21
|
+
"Operating System :: POSIX :: Linux",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Programming Language :: Python :: 3.13",
|
|
26
|
+
"Topic :: Software Development :: Build Tools",
|
|
27
|
+
"Topic :: Software Development :: Version Control :: Git",
|
|
28
|
+
]
|
|
29
|
+
dependencies = []
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/Tran-Steven/do-again"
|
|
33
|
+
Repository = "https://github.com/Tran-Steven/do-again"
|
|
34
|
+
Issues = "https://github.com/Tran-Steven/do-again/issues"
|
|
35
|
+
|
|
36
|
+
[project.scripts]
|
|
37
|
+
do-again = "do_again.cli:main"
|
|
38
|
+
|
|
39
|
+
[tool.hatch.build.targets.wheel]
|
|
40
|
+
packages = ["src/do_again"]
|
|
File without changes
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import shutil
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from .platforms.detect import detect_platform
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def doctor() -> int:
|
|
13
|
+
info = detect_platform()
|
|
14
|
+
checks = {
|
|
15
|
+
"python": sys.version_info >= (3, 11),
|
|
16
|
+
"git": shutil.which("git") is not None,
|
|
17
|
+
"platform": info.supported,
|
|
18
|
+
}
|
|
19
|
+
for key, ok in checks.items():
|
|
20
|
+
print(f"{'OK' if ok else 'FAIL'} {key}")
|
|
21
|
+
print(f"platform_name={info.name}")
|
|
22
|
+
print(f"service_manager={info.service_manager}")
|
|
23
|
+
return 0 if all(checks.values()) else 1
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def status() -> int:
|
|
27
|
+
info = detect_platform()
|
|
28
|
+
print(f"platform={info.name}")
|
|
29
|
+
print(f"service_manager={info.service_manager}")
|
|
30
|
+
return 0
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def init_project(path: str) -> int:
|
|
34
|
+
target = Path(path).expanduser().resolve()
|
|
35
|
+
target.mkdir(parents=True, exist_ok=True)
|
|
36
|
+
config = target / "do-again.toml"
|
|
37
|
+
if config.exists():
|
|
38
|
+
print(str(config))
|
|
39
|
+
return 0
|
|
40
|
+
config.write_text('[do_again]\ncontrol_branch = "operator-control"\n')
|
|
41
|
+
print(str(config))
|
|
42
|
+
return 0
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def main() -> int:
|
|
46
|
+
parser = argparse.ArgumentParser(prog="do-again")
|
|
47
|
+
sub = parser.add_subparsers(dest="command", required=True)
|
|
48
|
+
sub.add_parser("doctor")
|
|
49
|
+
sub.add_parser("status")
|
|
50
|
+
init_parser = sub.add_parser("init")
|
|
51
|
+
init_parser.add_argument("path", nargs="?", default=".")
|
|
52
|
+
args = parser.parse_args()
|
|
53
|
+
if args.command == "doctor":
|
|
54
|
+
return doctor()
|
|
55
|
+
if args.command == "status":
|
|
56
|
+
return status()
|
|
57
|
+
if args.command == "init":
|
|
58
|
+
return init_project(args.path)
|
|
59
|
+
return 2
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if __name__ == "__main__":
|
|
63
|
+
raise SystemExit(main())
|
|
File without changes
|