phx-paddock 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.
- phx_paddock-0.1.0/.gitignore +10 -0
- phx_paddock-0.1.0/LICENCE.txt +21 -0
- phx_paddock-0.1.0/PKG-INFO +262 -0
- phx_paddock-0.1.0/README.rst +241 -0
- phx_paddock-0.1.0/images/Dockerfile +36 -0
- phx_paddock-0.1.0/pyproject.toml +83 -0
- phx_paddock-0.1.0/src/paddock/__init__.py +1 -0
- phx_paddock-0.1.0/src/paddock/__main__.py +94 -0
- phx_paddock-0.1.0/src/paddock/agents/__init__.py +46 -0
- phx_paddock-0.1.0/src/paddock/agents/claude.py +16 -0
- phx_paddock-0.1.0/src/paddock/agents/shell.py +14 -0
- phx_paddock-0.1.0/src/paddock/cli.py +148 -0
- phx_paddock-0.1.0/src/paddock/config/__init__.py +0 -0
- phx_paddock-0.1.0/src/paddock/config/filters.py +71 -0
- phx_paddock-0.1.0/src/paddock/config/loader.py +353 -0
- phx_paddock-0.1.0/src/paddock/config/schema.py +61 -0
- phx_paddock-0.1.0/src/paddock/docker/__init__.py +0 -0
- phx_paddock-0.1.0/src/paddock/docker/build.py +92 -0
- phx_paddock-0.1.0/src/paddock/docker/builder.py +65 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Phoenix Zerin
|
|
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,262 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: phx-paddock
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Launch coding agents in isolated Docker containers.
|
|
5
|
+
Project-URL: Repository, https://github.com/phx/paddock
|
|
6
|
+
Author-email: Phoenix Zerin <phx@phx.nz>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENCE.txt
|
|
9
|
+
Keywords: agents,coding,docker,isolation
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
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 :: Build Tools
|
|
17
|
+
Requires-Python: <4,>=3.12
|
|
18
|
+
Requires-Dist: phx-class-registry<6.0.0,>=5.2.1
|
|
19
|
+
Requires-Dist: phx-filters<4.0.0,>=3.5.1
|
|
20
|
+
Description-Content-Type: text/x-rst
|
|
21
|
+
|
|
22
|
+
paddock
|
|
23
|
+
=======
|
|
24
|
+
|
|
25
|
+
Launch coding agents (or a plain shell) in isolated Docker containers,
|
|
26
|
+
with the current working directory mounted as the workspace.
|
|
27
|
+
|
|
28
|
+
.. image:: https://img.shields.io/pypi/v/paddock.svg
|
|
29
|
+
:target: https://pypi.org/project/paddock/
|
|
30
|
+
:alt: PyPI version
|
|
31
|
+
|
|
32
|
+
.. image:: https://img.shields.io/pypi/pyversions/paddock.svg
|
|
33
|
+
:alt: Python versions
|
|
34
|
+
|
|
35
|
+
.. image:: https://img.shields.io/badge/licence-MIT-blue.svg
|
|
36
|
+
:alt: MIT Licence
|
|
37
|
+
|
|
38
|
+
Overview
|
|
39
|
+
--------
|
|
40
|
+
|
|
41
|
+
``paddock`` assembles and executes a ``docker run`` command from a layered
|
|
42
|
+
configuration system. Config is resolved in priority order:
|
|
43
|
+
|
|
44
|
+
1. User-level TOML (``~/.config/paddock/config.toml``)
|
|
45
|
+
2. Project-level TOML (``<workdir>/.paddock/config.toml``)
|
|
46
|
+
3. Extra TOML file via ``PADDOCK_CONFIG_FILE`` env var
|
|
47
|
+
4. Extra TOML file via ``--config-file`` CLI flag
|
|
48
|
+
5. ``PADDOCK_*`` environment variables
|
|
49
|
+
6. CLI flags
|
|
50
|
+
|
|
51
|
+
Later sources overwrite earlier ones; ``volumes`` entries are additive.
|
|
52
|
+
|
|
53
|
+
Requirements
|
|
54
|
+
------------
|
|
55
|
+
|
|
56
|
+
- Python 3.12+
|
|
57
|
+
- Docker (CLI must be available on ``PATH``)
|
|
58
|
+
|
|
59
|
+
Installation
|
|
60
|
+
------------
|
|
61
|
+
|
|
62
|
+
.. code-block:: bash
|
|
63
|
+
|
|
64
|
+
pip install paddock
|
|
65
|
+
|
|
66
|
+
Or with `uv <https://github.com/astral-sh/uv>`_:
|
|
67
|
+
|
|
68
|
+
.. code-block:: bash
|
|
69
|
+
|
|
70
|
+
uv tool install paddock
|
|
71
|
+
|
|
72
|
+
Quick Start
|
|
73
|
+
-----------
|
|
74
|
+
|
|
75
|
+
Drop into a plain bash shell inside the current directory:
|
|
76
|
+
|
|
77
|
+
.. code-block:: bash
|
|
78
|
+
|
|
79
|
+
paddock --image=ubuntu:24.04 --agent=false
|
|
80
|
+
|
|
81
|
+
Run Claude Code in an isolated container:
|
|
82
|
+
|
|
83
|
+
.. code-block:: bash
|
|
84
|
+
|
|
85
|
+
paddock --image=my-claude-image --agent=claude
|
|
86
|
+
|
|
87
|
+
Print the assembled ``docker run`` command without executing it:
|
|
88
|
+
|
|
89
|
+
.. code-block:: bash
|
|
90
|
+
|
|
91
|
+
paddock --image=ubuntu:24.04 --agent=false --dry-run
|
|
92
|
+
|
|
93
|
+
Configuration
|
|
94
|
+
-------------
|
|
95
|
+
|
|
96
|
+
TOML files
|
|
97
|
+
~~~~~~~~~~
|
|
98
|
+
|
|
99
|
+
Place a ``config.toml`` at ``~/.config/paddock/`` (user-level) or
|
|
100
|
+
``<project>/.paddock/`` (project-level). Both files are optional.
|
|
101
|
+
|
|
102
|
+
.. code-block:: toml
|
|
103
|
+
|
|
104
|
+
agent = "claude"
|
|
105
|
+
image = "my-claude-image:latest"
|
|
106
|
+
network = "my-docker-network"
|
|
107
|
+
|
|
108
|
+
[volumes]
|
|
109
|
+
"/host/path" = "/container/path:ro"
|
|
110
|
+
|
|
111
|
+
[build]
|
|
112
|
+
dockerfile = "images/Dockerfile"
|
|
113
|
+
context = "."
|
|
114
|
+
policy = "daily"
|
|
115
|
+
|
|
116
|
+
[build.args]
|
|
117
|
+
AGENT = "claude"
|
|
118
|
+
PYTHON_VERSION = "3.13"
|
|
119
|
+
|
|
120
|
+
Config fields
|
|
121
|
+
~~~~~~~~~~~~~
|
|
122
|
+
|
|
123
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
124
|
+
| Field | Type | Description |
|
|
125
|
+
+====================+============================+==================================================+
|
|
126
|
+
| ``agent`` | ``string`` or ``false`` | Agent key (``"claude"``) or ``false`` for shell |
|
|
127
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
128
|
+
| ``image`` | ``string`` | Docker image to run (required) |
|
|
129
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
130
|
+
| ``network`` | ``string`` (optional) | Docker network to attach the container to |
|
|
131
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
132
|
+
| ``volumes`` | ``{host: container}`` map | Extra bind-mounts; container path may end |
|
|
133
|
+
| | | in ``:ro`` or ``:rw`` (bare path defaults to |
|
|
134
|
+
| | | ``:ro``) |
|
|
135
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
136
|
+
| ``build`` | sub-table (optional) | Image auto-build settings (see below) |
|
|
137
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
138
|
+
|
|
139
|
+
Build sub-table
|
|
140
|
+
~~~~~~~~~~~~~~~
|
|
141
|
+
|
|
142
|
+
+----------------+---------------------------------------------+-------------------------------------------+
|
|
143
|
+
| Field | Type | Description |
|
|
144
|
+
+================+=============================================+===========================================+
|
|
145
|
+
| ``dockerfile`` | ``string`` | Path to the Dockerfile (required if build |
|
|
146
|
+
| | | table is present) |
|
|
147
|
+
+----------------+---------------------------------------------+-------------------------------------------+
|
|
148
|
+
| ``context`` | ``string`` (optional) | Docker build context path |
|
|
149
|
+
+----------------+---------------------------------------------+-------------------------------------------+
|
|
150
|
+
| ``policy`` | ``"always"`` / ``"daily"`` / | When to rebuild the image |
|
|
151
|
+
| | ``"if-missing"`` / ``"weekly"`` | |
|
|
152
|
+
+----------------+---------------------------------------------+-------------------------------------------+
|
|
153
|
+
| ``args`` | ``{name: value}`` map (optional) | Build-time ``--build-arg`` values |
|
|
154
|
+
+----------------+---------------------------------------------+-------------------------------------------+
|
|
155
|
+
|
|
156
|
+
Environment variables
|
|
157
|
+
~~~~~~~~~~~~~~~~~~~~~
|
|
158
|
+
|
|
159
|
+
Any config field can be set via an environment variable by uppercasing its
|
|
160
|
+
name and prefixing with ``PADDOCK_``. Nested keys are joined with ``_``:
|
|
161
|
+
|
|
162
|
+
.. code-block:: bash
|
|
163
|
+
|
|
164
|
+
PADDOCK_IMAGE=ubuntu:24.04
|
|
165
|
+
PADDOCK_AGENT=claude
|
|
166
|
+
PADDOCK_BUILD_DOCKERFILE=images/Dockerfile
|
|
167
|
+
PADDOCK_BUILD_POLICY=daily
|
|
168
|
+
PADDOCK_CONFIG_FILE=/path/to/extra.toml # loads an additional TOML file
|
|
169
|
+
|
|
170
|
+
CLI flags
|
|
171
|
+
~~~~~~~~~
|
|
172
|
+
|
|
173
|
+
.. code-block:: text
|
|
174
|
+
|
|
175
|
+
paddock [FLAGS] [--] [COMMAND...]
|
|
176
|
+
|
|
177
|
+
--agent AGENT Agent key (e.g. "claude") or "false" for a shell
|
|
178
|
+
--build-args-KEY=VALUE Build-time ARG (repeatable)
|
|
179
|
+
--build-context PATH Docker build context
|
|
180
|
+
--build-dockerfile PATH Path to Dockerfile
|
|
181
|
+
--build-policy POLICY Build policy (always|daily|if-missing|weekly)
|
|
182
|
+
--config-file PATH Load an additional TOML config file
|
|
183
|
+
--dry-run Print the docker command and exit without running it
|
|
184
|
+
--image IMAGE Docker image
|
|
185
|
+
--network NETWORK Docker network
|
|
186
|
+
--quiet Suppress all logging and the docker command printout
|
|
187
|
+
--volume HOST:CONTAINER[:MODE] Extra bind-mount (repeatable)
|
|
188
|
+
--workdir PATH Host path to use as the workspace (default: CWD)
|
|
189
|
+
|
|
190
|
+
Everything after the first positional argument (or after ``--``) is passed
|
|
191
|
+
as the container command:
|
|
192
|
+
|
|
193
|
+
.. code-block:: bash
|
|
194
|
+
|
|
195
|
+
paddock --image=ubuntu:24.04 --agent=false -- bash -c "echo hello"
|
|
196
|
+
|
|
197
|
+
Agents
|
|
198
|
+
------
|
|
199
|
+
|
|
200
|
+
``claude``
|
|
201
|
+
~~~~~~~~~~
|
|
202
|
+
|
|
203
|
+
Runs ``claude`` inside the container. Mounts ``~/.claude`` from the host
|
|
204
|
+
to ``/root/.claude:rw`` so authentication and configuration persist between
|
|
205
|
+
sessions.
|
|
206
|
+
|
|
207
|
+
``false`` (shell)
|
|
208
|
+
~~~~~~~~~~~~~~~~~
|
|
209
|
+
|
|
210
|
+
Runs ``/bin/bash``. Useful for exploring the container environment or
|
|
211
|
+
running ad-hoc commands without a coding agent.
|
|
212
|
+
|
|
213
|
+
Adding agents
|
|
214
|
+
~~~~~~~~~~~~~
|
|
215
|
+
|
|
216
|
+
Additional agents can be registered via the ``paddock.agents`` entry-point
|
|
217
|
+
group in any installed package:
|
|
218
|
+
|
|
219
|
+
.. code-block:: toml
|
|
220
|
+
|
|
221
|
+
[project.entry-points."paddock.agents"]
|
|
222
|
+
my-agent = "mypackage.agents:MyAgent"
|
|
223
|
+
|
|
224
|
+
Each agent must subclass ``paddock.agents.BaseAgent`` and implement
|
|
225
|
+
``get_command()`` and ``get_volumes()``.
|
|
226
|
+
|
|
227
|
+
Docker Image
|
|
228
|
+
------------
|
|
229
|
+
|
|
230
|
+
A ready-to-use ``Dockerfile`` is included in ``images/``. It installs
|
|
231
|
+
Python (via the deadsnakes PPA), Node.js, and the selected coding agent.
|
|
232
|
+
|
|
233
|
+
Build arguments:
|
|
234
|
+
|
|
235
|
+
+--------------------+-------------------+----------------------------------------------+
|
|
236
|
+
| ARG | Default | Description |
|
|
237
|
+
+====================+===================+==============================================+
|
|
238
|
+
| ``UBUNTU_VERSION`` | ``24.04`` | Ubuntu base image tag |
|
|
239
|
+
+--------------------+-------------------+----------------------------------------------+
|
|
240
|
+
| ``AGENT`` | ``none`` | ``claude`` or ``none`` |
|
|
241
|
+
+--------------------+-------------------+----------------------------------------------+
|
|
242
|
+
| ``NODE_VERSION`` | ``22`` | Node.js major version |
|
|
243
|
+
+--------------------+-------------------+----------------------------------------------+
|
|
244
|
+
| ``PYTHON_VERSION`` | ``3.13`` | Python version (installed from deadsnakes) |
|
|
245
|
+
+--------------------+-------------------+----------------------------------------------+
|
|
246
|
+
|
|
247
|
+
Build the image manually:
|
|
248
|
+
|
|
249
|
+
.. code-block:: bash
|
|
250
|
+
|
|
251
|
+
docker build \
|
|
252
|
+
--build-arg AGENT=claude \
|
|
253
|
+
-t my-claude-image \
|
|
254
|
+
-f images/Dockerfile .
|
|
255
|
+
|
|
256
|
+
Or set a ``[build]`` table in your config and let paddock build it
|
|
257
|
+
automatically according to your chosen policy.
|
|
258
|
+
|
|
259
|
+
Licence
|
|
260
|
+
-------
|
|
261
|
+
|
|
262
|
+
MIT — see ``LICENCE.txt``.
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
paddock
|
|
2
|
+
=======
|
|
3
|
+
|
|
4
|
+
Launch coding agents (or a plain shell) in isolated Docker containers,
|
|
5
|
+
with the current working directory mounted as the workspace.
|
|
6
|
+
|
|
7
|
+
.. image:: https://img.shields.io/pypi/v/paddock.svg
|
|
8
|
+
:target: https://pypi.org/project/paddock/
|
|
9
|
+
:alt: PyPI version
|
|
10
|
+
|
|
11
|
+
.. image:: https://img.shields.io/pypi/pyversions/paddock.svg
|
|
12
|
+
:alt: Python versions
|
|
13
|
+
|
|
14
|
+
.. image:: https://img.shields.io/badge/licence-MIT-blue.svg
|
|
15
|
+
:alt: MIT Licence
|
|
16
|
+
|
|
17
|
+
Overview
|
|
18
|
+
--------
|
|
19
|
+
|
|
20
|
+
``paddock`` assembles and executes a ``docker run`` command from a layered
|
|
21
|
+
configuration system. Config is resolved in priority order:
|
|
22
|
+
|
|
23
|
+
1. User-level TOML (``~/.config/paddock/config.toml``)
|
|
24
|
+
2. Project-level TOML (``<workdir>/.paddock/config.toml``)
|
|
25
|
+
3. Extra TOML file via ``PADDOCK_CONFIG_FILE`` env var
|
|
26
|
+
4. Extra TOML file via ``--config-file`` CLI flag
|
|
27
|
+
5. ``PADDOCK_*`` environment variables
|
|
28
|
+
6. CLI flags
|
|
29
|
+
|
|
30
|
+
Later sources overwrite earlier ones; ``volumes`` entries are additive.
|
|
31
|
+
|
|
32
|
+
Requirements
|
|
33
|
+
------------
|
|
34
|
+
|
|
35
|
+
- Python 3.12+
|
|
36
|
+
- Docker (CLI must be available on ``PATH``)
|
|
37
|
+
|
|
38
|
+
Installation
|
|
39
|
+
------------
|
|
40
|
+
|
|
41
|
+
.. code-block:: bash
|
|
42
|
+
|
|
43
|
+
pip install paddock
|
|
44
|
+
|
|
45
|
+
Or with `uv <https://github.com/astral-sh/uv>`_:
|
|
46
|
+
|
|
47
|
+
.. code-block:: bash
|
|
48
|
+
|
|
49
|
+
uv tool install paddock
|
|
50
|
+
|
|
51
|
+
Quick Start
|
|
52
|
+
-----------
|
|
53
|
+
|
|
54
|
+
Drop into a plain bash shell inside the current directory:
|
|
55
|
+
|
|
56
|
+
.. code-block:: bash
|
|
57
|
+
|
|
58
|
+
paddock --image=ubuntu:24.04 --agent=false
|
|
59
|
+
|
|
60
|
+
Run Claude Code in an isolated container:
|
|
61
|
+
|
|
62
|
+
.. code-block:: bash
|
|
63
|
+
|
|
64
|
+
paddock --image=my-claude-image --agent=claude
|
|
65
|
+
|
|
66
|
+
Print the assembled ``docker run`` command without executing it:
|
|
67
|
+
|
|
68
|
+
.. code-block:: bash
|
|
69
|
+
|
|
70
|
+
paddock --image=ubuntu:24.04 --agent=false --dry-run
|
|
71
|
+
|
|
72
|
+
Configuration
|
|
73
|
+
-------------
|
|
74
|
+
|
|
75
|
+
TOML files
|
|
76
|
+
~~~~~~~~~~
|
|
77
|
+
|
|
78
|
+
Place a ``config.toml`` at ``~/.config/paddock/`` (user-level) or
|
|
79
|
+
``<project>/.paddock/`` (project-level). Both files are optional.
|
|
80
|
+
|
|
81
|
+
.. code-block:: toml
|
|
82
|
+
|
|
83
|
+
agent = "claude"
|
|
84
|
+
image = "my-claude-image:latest"
|
|
85
|
+
network = "my-docker-network"
|
|
86
|
+
|
|
87
|
+
[volumes]
|
|
88
|
+
"/host/path" = "/container/path:ro"
|
|
89
|
+
|
|
90
|
+
[build]
|
|
91
|
+
dockerfile = "images/Dockerfile"
|
|
92
|
+
context = "."
|
|
93
|
+
policy = "daily"
|
|
94
|
+
|
|
95
|
+
[build.args]
|
|
96
|
+
AGENT = "claude"
|
|
97
|
+
PYTHON_VERSION = "3.13"
|
|
98
|
+
|
|
99
|
+
Config fields
|
|
100
|
+
~~~~~~~~~~~~~
|
|
101
|
+
|
|
102
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
103
|
+
| Field | Type | Description |
|
|
104
|
+
+====================+============================+==================================================+
|
|
105
|
+
| ``agent`` | ``string`` or ``false`` | Agent key (``"claude"``) or ``false`` for shell |
|
|
106
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
107
|
+
| ``image`` | ``string`` | Docker image to run (required) |
|
|
108
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
109
|
+
| ``network`` | ``string`` (optional) | Docker network to attach the container to |
|
|
110
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
111
|
+
| ``volumes`` | ``{host: container}`` map | Extra bind-mounts; container path may end |
|
|
112
|
+
| | | in ``:ro`` or ``:rw`` (bare path defaults to |
|
|
113
|
+
| | | ``:ro``) |
|
|
114
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
115
|
+
| ``build`` | sub-table (optional) | Image auto-build settings (see below) |
|
|
116
|
+
+--------------------+----------------------------+--------------------------------------------------+
|
|
117
|
+
|
|
118
|
+
Build sub-table
|
|
119
|
+
~~~~~~~~~~~~~~~
|
|
120
|
+
|
|
121
|
+
+----------------+---------------------------------------------+-------------------------------------------+
|
|
122
|
+
| Field | Type | Description |
|
|
123
|
+
+================+=============================================+===========================================+
|
|
124
|
+
| ``dockerfile`` | ``string`` | Path to the Dockerfile (required if build |
|
|
125
|
+
| | | table is present) |
|
|
126
|
+
+----------------+---------------------------------------------+-------------------------------------------+
|
|
127
|
+
| ``context`` | ``string`` (optional) | Docker build context path |
|
|
128
|
+
+----------------+---------------------------------------------+-------------------------------------------+
|
|
129
|
+
| ``policy`` | ``"always"`` / ``"daily"`` / | When to rebuild the image |
|
|
130
|
+
| | ``"if-missing"`` / ``"weekly"`` | |
|
|
131
|
+
+----------------+---------------------------------------------+-------------------------------------------+
|
|
132
|
+
| ``args`` | ``{name: value}`` map (optional) | Build-time ``--build-arg`` values |
|
|
133
|
+
+----------------+---------------------------------------------+-------------------------------------------+
|
|
134
|
+
|
|
135
|
+
Environment variables
|
|
136
|
+
~~~~~~~~~~~~~~~~~~~~~
|
|
137
|
+
|
|
138
|
+
Any config field can be set via an environment variable by uppercasing its
|
|
139
|
+
name and prefixing with ``PADDOCK_``. Nested keys are joined with ``_``:
|
|
140
|
+
|
|
141
|
+
.. code-block:: bash
|
|
142
|
+
|
|
143
|
+
PADDOCK_IMAGE=ubuntu:24.04
|
|
144
|
+
PADDOCK_AGENT=claude
|
|
145
|
+
PADDOCK_BUILD_DOCKERFILE=images/Dockerfile
|
|
146
|
+
PADDOCK_BUILD_POLICY=daily
|
|
147
|
+
PADDOCK_CONFIG_FILE=/path/to/extra.toml # loads an additional TOML file
|
|
148
|
+
|
|
149
|
+
CLI flags
|
|
150
|
+
~~~~~~~~~
|
|
151
|
+
|
|
152
|
+
.. code-block:: text
|
|
153
|
+
|
|
154
|
+
paddock [FLAGS] [--] [COMMAND...]
|
|
155
|
+
|
|
156
|
+
--agent AGENT Agent key (e.g. "claude") or "false" for a shell
|
|
157
|
+
--build-args-KEY=VALUE Build-time ARG (repeatable)
|
|
158
|
+
--build-context PATH Docker build context
|
|
159
|
+
--build-dockerfile PATH Path to Dockerfile
|
|
160
|
+
--build-policy POLICY Build policy (always|daily|if-missing|weekly)
|
|
161
|
+
--config-file PATH Load an additional TOML config file
|
|
162
|
+
--dry-run Print the docker command and exit without running it
|
|
163
|
+
--image IMAGE Docker image
|
|
164
|
+
--network NETWORK Docker network
|
|
165
|
+
--quiet Suppress all logging and the docker command printout
|
|
166
|
+
--volume HOST:CONTAINER[:MODE] Extra bind-mount (repeatable)
|
|
167
|
+
--workdir PATH Host path to use as the workspace (default: CWD)
|
|
168
|
+
|
|
169
|
+
Everything after the first positional argument (or after ``--``) is passed
|
|
170
|
+
as the container command:
|
|
171
|
+
|
|
172
|
+
.. code-block:: bash
|
|
173
|
+
|
|
174
|
+
paddock --image=ubuntu:24.04 --agent=false -- bash -c "echo hello"
|
|
175
|
+
|
|
176
|
+
Agents
|
|
177
|
+
------
|
|
178
|
+
|
|
179
|
+
``claude``
|
|
180
|
+
~~~~~~~~~~
|
|
181
|
+
|
|
182
|
+
Runs ``claude`` inside the container. Mounts ``~/.claude`` from the host
|
|
183
|
+
to ``/root/.claude:rw`` so authentication and configuration persist between
|
|
184
|
+
sessions.
|
|
185
|
+
|
|
186
|
+
``false`` (shell)
|
|
187
|
+
~~~~~~~~~~~~~~~~~
|
|
188
|
+
|
|
189
|
+
Runs ``/bin/bash``. Useful for exploring the container environment or
|
|
190
|
+
running ad-hoc commands without a coding agent.
|
|
191
|
+
|
|
192
|
+
Adding agents
|
|
193
|
+
~~~~~~~~~~~~~
|
|
194
|
+
|
|
195
|
+
Additional agents can be registered via the ``paddock.agents`` entry-point
|
|
196
|
+
group in any installed package:
|
|
197
|
+
|
|
198
|
+
.. code-block:: toml
|
|
199
|
+
|
|
200
|
+
[project.entry-points."paddock.agents"]
|
|
201
|
+
my-agent = "mypackage.agents:MyAgent"
|
|
202
|
+
|
|
203
|
+
Each agent must subclass ``paddock.agents.BaseAgent`` and implement
|
|
204
|
+
``get_command()`` and ``get_volumes()``.
|
|
205
|
+
|
|
206
|
+
Docker Image
|
|
207
|
+
------------
|
|
208
|
+
|
|
209
|
+
A ready-to-use ``Dockerfile`` is included in ``images/``. It installs
|
|
210
|
+
Python (via the deadsnakes PPA), Node.js, and the selected coding agent.
|
|
211
|
+
|
|
212
|
+
Build arguments:
|
|
213
|
+
|
|
214
|
+
+--------------------+-------------------+----------------------------------------------+
|
|
215
|
+
| ARG | Default | Description |
|
|
216
|
+
+====================+===================+==============================================+
|
|
217
|
+
| ``UBUNTU_VERSION`` | ``24.04`` | Ubuntu base image tag |
|
|
218
|
+
+--------------------+-------------------+----------------------------------------------+
|
|
219
|
+
| ``AGENT`` | ``none`` | ``claude`` or ``none`` |
|
|
220
|
+
+--------------------+-------------------+----------------------------------------------+
|
|
221
|
+
| ``NODE_VERSION`` | ``22`` | Node.js major version |
|
|
222
|
+
+--------------------+-------------------+----------------------------------------------+
|
|
223
|
+
| ``PYTHON_VERSION`` | ``3.13`` | Python version (installed from deadsnakes) |
|
|
224
|
+
+--------------------+-------------------+----------------------------------------------+
|
|
225
|
+
|
|
226
|
+
Build the image manually:
|
|
227
|
+
|
|
228
|
+
.. code-block:: bash
|
|
229
|
+
|
|
230
|
+
docker build \
|
|
231
|
+
--build-arg AGENT=claude \
|
|
232
|
+
-t my-claude-image \
|
|
233
|
+
-f images/Dockerfile .
|
|
234
|
+
|
|
235
|
+
Or set a ``[build]`` table in your config and let paddock build it
|
|
236
|
+
automatically according to your chosen policy.
|
|
237
|
+
|
|
238
|
+
Licence
|
|
239
|
+
-------
|
|
240
|
+
|
|
241
|
+
MIT — see ``LICENCE.txt``.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
ARG UBUNTU_VERSION=24.04
|
|
2
|
+
|
|
3
|
+
FROM ubuntu:${UBUNTU_VERSION}
|
|
4
|
+
|
|
5
|
+
ARG AGENT=none
|
|
6
|
+
ARG NODE_VERSION=22
|
|
7
|
+
ARG PYTHON_VERSION=3.13
|
|
8
|
+
|
|
9
|
+
# Prevent interactive prompts during apt installs
|
|
10
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
11
|
+
|
|
12
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
13
|
+
ca-certificates \
|
|
14
|
+
curl \
|
|
15
|
+
git \
|
|
16
|
+
software-properties-common \
|
|
17
|
+
&& add-apt-repository ppa:deadsnakes/ppa \
|
|
18
|
+
&& apt-get update \
|
|
19
|
+
&& apt-get install -y --no-install-recommends \
|
|
20
|
+
"python${PYTHON_VERSION}" \
|
|
21
|
+
"python${PYTHON_VERSION}-venv" \
|
|
22
|
+
&& apt-get clean \
|
|
23
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
24
|
+
|
|
25
|
+
# Install Node.js (required for Claude Code)
|
|
26
|
+
RUN curl -fsSL "https://deb.nodesource.com/setup_${NODE_VERSION}.x" | bash - \
|
|
27
|
+
&& apt-get install -y nodejs \
|
|
28
|
+
&& apt-get clean \
|
|
29
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
30
|
+
|
|
31
|
+
# Install coding agent based on ARG
|
|
32
|
+
RUN case "$AGENT" in \
|
|
33
|
+
claude) npm install -g @anthropic-ai/claude-code ;; \
|
|
34
|
+
none) echo "No agent selected" ;; \
|
|
35
|
+
*) echo "Unknown agent: $AGENT" && exit 1 ;; \
|
|
36
|
+
esac
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
build-backend = "hatchling.build"
|
|
3
|
+
requires = ["hatchling"]
|
|
4
|
+
|
|
5
|
+
[dependency-groups]
|
|
6
|
+
dev = [
|
|
7
|
+
"autohooks>=26.2.0,<27.0.0",
|
|
8
|
+
"autohooks-plugin-black>=23.10.0,<24.0.0",
|
|
9
|
+
"autohooks-plugin-pytest>=23.10.0,<24.0.0",
|
|
10
|
+
"autohooks-plugin-ruff>=25.3.1,<26.0.0",
|
|
11
|
+
"pytest>=9.0.3,<10.0.0",
|
|
12
|
+
"pytest-mock>=3.15.1,<4.0.0",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project]
|
|
16
|
+
authors = [{ name = "Phoenix Zerin", email = "phx@phx.nz" }]
|
|
17
|
+
classifiers = [
|
|
18
|
+
"Development Status :: 3 - Alpha",
|
|
19
|
+
"Intended Audience :: Developers",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Programming Language :: Python :: 3.14",
|
|
24
|
+
"Topic :: Software Development :: Build Tools",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"phx-class-registry>=5.2.1,<6.0.0",
|
|
28
|
+
"phx-filters>=3.5.1,<4.0.0",
|
|
29
|
+
]
|
|
30
|
+
description = "Launch coding agents in isolated Docker containers."
|
|
31
|
+
dynamic = ["version"]
|
|
32
|
+
keywords = [
|
|
33
|
+
"agents",
|
|
34
|
+
"coding",
|
|
35
|
+
"docker",
|
|
36
|
+
"isolation",
|
|
37
|
+
]
|
|
38
|
+
license = "MIT"
|
|
39
|
+
name = "phx-paddock"
|
|
40
|
+
readme = "README.rst"
|
|
41
|
+
requires-python = ">=3.12, <4"
|
|
42
|
+
|
|
43
|
+
[project.entry-points."paddock.agents"]
|
|
44
|
+
claude = "paddock.agents.claude:ClaudeAgent"
|
|
45
|
+
false = "paddock.agents.shell:ShellAgent"
|
|
46
|
+
|
|
47
|
+
[project.scripts]
|
|
48
|
+
paddock = "paddock.__main__:main"
|
|
49
|
+
|
|
50
|
+
[project.urls]
|
|
51
|
+
Repository = "https://github.com/phx/paddock"
|
|
52
|
+
|
|
53
|
+
[tool.autohooks]
|
|
54
|
+
mode = "pythonpath"
|
|
55
|
+
pre-commit = [
|
|
56
|
+
"autohooks.plugins.black",
|
|
57
|
+
"autohooks.plugins.pytest",
|
|
58
|
+
"autohooks.plugins.ruff",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[tool.hatch.build.targets.sdist]
|
|
62
|
+
include = [
|
|
63
|
+
"src/paddock",
|
|
64
|
+
"LICENCE.txt",
|
|
65
|
+
"images",
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
[tool.hatch.build.targets.wheel]
|
|
69
|
+
include = ["src/paddock"]
|
|
70
|
+
|
|
71
|
+
[tool.hatch.build.targets.wheel.sources]
|
|
72
|
+
"src/paddock" = "paddock"
|
|
73
|
+
|
|
74
|
+
[tool.hatch.version]
|
|
75
|
+
path = "src/paddock/__init__.py"
|
|
76
|
+
|
|
77
|
+
[tool.pytest.ini_options]
|
|
78
|
+
testpaths = ["tests"]
|
|
79
|
+
|
|
80
|
+
[tool.uv]
|
|
81
|
+
keyring-provider = "subprocess"
|
|
82
|
+
# Fix SSL errors when running in Leash containers
|
|
83
|
+
system-certs = true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.1.0"
|