agentme 0.5.0 → 0.7.0

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.
@@ -13,11 +13,12 @@ compatibility: Python 3.12+
13
13
 
14
14
  ## Overview
15
15
 
16
- Creates a complete Python project from scratch using `uv`, `pyproject.toml`, Ruff, Pyright,
17
- Pytest, and Makefiles. The default layout uses `src/<package_name>/`, `tests/`, and `examples/`
18
- for libraries and shared utilities.
16
+ Creates a complete Python project from scratch using Mise, `uv`, `pyproject.toml`, Ruff,
17
+ Pyright, Pytest, and Makefiles. The default layout keeps the library self-contained under `lib/`,
18
+ uses a shared root `.venv/`, redirects persistent caches into `.cache/`, and places runnable
19
+ consumer projects under the sibling `examples/` folder.
19
20
 
20
- Related EDR: [agentme-edr-014](../../014-python-project-tooling.md)
21
+ Related EDRs: [agentme-edr-014](../../014-python-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md)
21
22
 
22
23
  ## Instructions
23
24
 
@@ -38,58 +39,149 @@ Ask for or infer from context:
38
39
 
39
40
  Create these files first.
40
41
 
42
+ **`./.mise.toml`**
43
+
44
+ ```toml
45
+ [tools]
46
+ python = "3.13"
47
+ uv = "latest"
48
+ ```
49
+
50
+ Replace `3.13` with the chosen Python version and pin any additional project CLIs used by the project here.
51
+
41
52
  **`./Makefile`**
42
53
 
43
54
  ```makefile
44
55
  SHELL := /bin/bash
45
-
46
- PACKAGE_NAME ?= your_package
47
56
  MISE := mise exec --
57
+ ROOT_DIR := $(abspath .)
58
+ export UV_PROJECT_ENVIRONMENT := $(ROOT_DIR)/.venv
59
+ export UV_CACHE_DIR := $(ROOT_DIR)/.cache/uv
48
60
 
49
61
  all: build lint test
50
62
 
63
+ setup:
64
+ mise install
65
+ $(MAKE) install
66
+
51
67
  install:
52
- uv sync --frozen --all-extras --dev
68
+ $(MAKE) -C lib install
53
69
 
54
- build: install
55
- uv build
70
+ build:
71
+ $(MAKE) -C lib build
56
72
 
57
73
  lint:
58
- uv run ruff format --check .
59
- uv run ruff check .
60
- uv run pyright
61
- uv run pip-audit
74
+ $(MAKE) -C lib lint
62
75
 
63
76
  lint-fix:
64
- uv run ruff format .
65
- uv run ruff check . --fix
66
- uv run pyright
67
- uv run pip-audit
77
+ $(MAKE) -C lib lint-fix
68
78
 
69
79
  test: test-unit test-examples
70
80
 
71
81
  test-unit:
72
- uv run pytest --cov=src/$(PACKAGE_NAME) --cov-branch --cov-report=term-missing --cov-fail-under=80
82
+ $(MAKE) -C lib test-unit
83
+
84
+ test-examples: build
85
+ @for dir in examples/*; do \
86
+ if [ -f "$$dir/pyproject.toml" ]; then \
87
+ echo ">>> Running $$dir"; \
88
+ UV_PROJECT_ENVIRONMENT="$(UV_PROJECT_ENVIRONMENT)" UV_CACHE_DIR="$(UV_CACHE_DIR)" $(MISE) uv sync --project "$$dir" --frozen || exit 1; \
89
+ UV_PROJECT_ENVIRONMENT="$(UV_PROJECT_ENVIRONMENT)" UV_CACHE_DIR="$(UV_CACHE_DIR)" $(MISE) uv pip install --python "$(UV_PROJECT_ENVIRONMENT)/bin/python" lib/dist/*.whl || exit 1; \
90
+ UV_PROJECT_ENVIRONMENT="$(UV_PROJECT_ENVIRONMENT)" UV_CACHE_DIR="$(UV_CACHE_DIR)" $(MISE) uv run --project "$$dir" python main.py || exit 1; \
91
+ fi; \
92
+ done
93
+
94
+ clean:
95
+ $(MAKE) -C lib clean
96
+ rm -rf .cache
97
+ rm -rf .venv
98
+ ```
99
+
100
+ The root `Makefile` keeps the repository clean by delegating package work to `lib/` and treating each example directory as an independent consumer project. Child Makefiles own the actual `mise exec -- <tool>` calls.
101
+
102
+ **`./.gitignore`**
103
+
104
+ ```gitignore
105
+ .venv/
106
+ dist/
107
+ .cache/
108
+ ```
109
+
110
+ **`./README.md`**
111
+
112
+ Keep this README focused on the repository or workspace. Put Getting Started near the top.
113
+
114
+ ````markdown
115
+ # [package-name]
116
+
117
+ [description]
118
+
119
+ ## Getting Started
120
+
121
+ ```sh
122
+ make setup
123
+ make test
124
+ ```
125
+
126
+ The published package lives in `lib/` and runnable consumer examples live in `examples/`.
127
+ ````
128
+
129
+ ### Phase 3: Create `lib/`
130
+
131
+ `lib/` contains everything the library needs: source, tests, package metadata, lockfile, build
132
+ artifacts, and library-specific Makefile targets.
73
133
 
74
- test-examples:
75
- @if [ -d examples ]; then $(MAKE) -C examples test PACKAGE_NAME=$(PACKAGE_NAME); else echo "No examples/ directory. Skipping"; fi
134
+ **`lib/Makefile`**
76
135
 
77
- run:
78
- uv run python -m $(PACKAGE_NAME)
136
+ ```makefile
137
+ SHELL := /bin/bash
138
+ MISE := mise exec --
139
+ ROOT_DIR := $(abspath ..)
140
+ export UV_PROJECT_ENVIRONMENT := $(ROOT_DIR)/.venv
141
+ export UV_CACHE_DIR := $(ROOT_DIR)/.cache/uv
142
+ export RUFF_CACHE_DIR := $(abspath .cache/ruff)
143
+ export PYTHONPYCACHEPREFIX := $(abspath .cache/pycache)
144
+ export COVERAGE_FILE := $(abspath .cache/coverage)
145
+
146
+ PACKAGE_NAME ?= your_package
147
+
148
+ all: build lint test-unit
149
+
150
+ install:
151
+ $(MISE) uv sync --project . --frozen --all-extras --dev
152
+
153
+ build: install
154
+ rm -rf dist
155
+ $(MISE) uv build --project . --out-dir dist
156
+
157
+ lint: install
158
+ $(MISE) uv run --project . ruff format --check .
159
+ $(MISE) uv run --project . ruff check .
160
+ $(MISE) uv run --project . pyright
161
+ $(MISE) uv run --project . pip-audit
162
+
163
+ lint-fix: install
164
+ $(MISE) uv run --project . ruff format .
165
+ $(MISE) uv run --project . ruff check . --fix
166
+ $(MISE) uv run --project . pyright
167
+ $(MISE) uv run --project . pip-audit
168
+
169
+ test-unit: install
170
+ $(MISE) uv run --project . pytest -o cache_dir=.cache/pytest --cov=src/$(PACKAGE_NAME) --cov-branch --cov-report=term-missing --cov-report=html:.cache/htmlcov --cov-fail-under=80
171
+
172
+ run: install
173
+ $(MISE) uv run --project . python -m $(PACKAGE_NAME)
79
174
 
80
175
  dev: run
81
176
 
82
177
  update-lockfile:
83
- uv lock --upgrade
178
+ $(MISE) uv lock --project . --upgrade
84
179
 
85
180
  clean:
86
- rm -rf .venv dist .pytest_cache .ruff_cache .coverage htmlcov
87
- find . -type d -name __pycache__ -prune -exec rm -rf {} +
181
+ rm -rf dist .cache
88
182
  ```
89
183
 
90
- If the repository already uses Mise, adapt the commands to `$(MISE) uv ...` and pin both Python and uv in `.mise.toml`.
91
-
92
- **`./pyproject.toml`**
184
+ **`lib/pyproject.toml`**
93
185
 
94
186
  Replace placeholders such as `[package-name]`, `[description]`, `[author]`, and `[python-version]`.
95
187
 
@@ -130,7 +222,7 @@ select = ["E", "F", "I", "B", "UP"]
130
222
 
131
223
  [tool.pyright]
132
224
  include = ["src", "tests"]
133
- venvPath = "."
225
+ venvPath = ".."
134
226
  venv = ".venv"
135
227
  typeCheckingMode = "standard"
136
228
 
@@ -139,28 +231,14 @@ testpaths = ["tests"]
139
231
  addopts = "-q"
140
232
  ```
141
233
 
142
- Use `pyproject.toml` as the single configuration file. Do not add `requirements.txt`,
143
- `setup.py`, `setup.cfg`, `ruff.toml`, or `pyrightconfig.json` by default.
144
-
145
- **`./.gitignore`**
146
-
147
- ```gitignore
148
- .venv/
149
- dist/
150
- build/
151
- .pytest_cache/
152
- .ruff_cache/
153
- .coverage
154
- htmlcov/
155
- __pycache__/
156
- *.pyc
157
- ```
234
+ Use `lib/pyproject.toml` as the single configuration file for the package. Do not add
235
+ `requirements.txt`, `setup.py`, `setup.cfg`, `ruff.toml`, or `pyrightconfig.json` by default.
158
236
 
159
- **`./README.md`**
237
+ **`lib/README.md`**
160
238
 
161
- Put Getting Started near the top.
239
+ This README is the published package README referenced by `lib/pyproject.toml`.
162
240
 
163
- ```markdown
241
+ ````markdown
164
242
  # [package-name]
165
243
 
166
244
  [description]
@@ -168,7 +246,7 @@ Put Getting Started near the top.
168
246
  ## Getting Started
169
247
 
170
248
  ```sh
171
- uv sync --dev
249
+ make setup
172
250
  make test
173
251
  ```
174
252
 
@@ -177,13 +255,21 @@ from [package-name] import hello
177
255
 
178
256
  print(hello("world"))
179
257
  ```
258
+
259
+ ## Development
260
+
261
+ ```sh
262
+ make build
263
+ make lint
264
+ make test
180
265
  ```
266
+ ````
181
267
 
182
- ### Phase 3: Create the package and tests
268
+ ### Phase 4: Create the package and tests inside `lib/`
183
269
 
184
270
  Create this baseline structure.
185
271
 
186
- **`src/[package_name]/__init__.py`**
272
+ **`lib/src/[package_name]/__init__.py`**
187
273
 
188
274
  ```python
189
275
  from .core import hello
@@ -191,14 +277,14 @@ from .core import hello
191
277
  __all__ = ["hello"]
192
278
  ```
193
279
 
194
- **`src/[package_name]/core.py`**
280
+ **`lib/src/[package_name]/core.py`**
195
281
 
196
282
  ```python
197
283
  def hello(name: str) -> str:
198
284
  return f"Hello, {name}!"
199
285
  ```
200
286
 
201
- **`src/[package_name]/__main__.py`**
287
+ **`lib/src/[package_name]/__main__.py`**
202
288
 
203
289
  Use this only for CLI-oriented projects.
204
290
 
@@ -214,7 +300,7 @@ if __name__ == "__main__":
214
300
  main()
215
301
  ```
216
302
 
217
- **`tests/test_core.py`**
303
+ **`lib/tests/test_core.py`**
218
304
 
219
305
  ```python
220
306
  from [package_name].core import hello
@@ -224,26 +310,27 @@ def test_hello() -> None:
224
310
  assert hello("world") == "Hello, world!"
225
311
  ```
226
312
 
227
- If two or more test files need shared fixtures, create `tests/conftest.py` and move shared setup there.
313
+ If two or more test files need shared fixtures, create `lib/tests/conftest.py` and move shared setup there.
228
314
 
229
- ### Phase 4: Create examples for libraries and utilities
315
+ If the module needs slower end-to-end coverage, place those tests in `lib/tests_integration/`. Put dedicated benchmark harnesses in `lib/tests_benchmark/`.
230
316
 
231
- If the project is a library or shared utility, add an `examples/` directory and execute it from the root `test` target.
317
+ ### Phase 5: Create examples for libraries and utilities
232
318
 
233
- **`examples/Makefile`**
319
+ If the project is a library or shared utility, add an `examples/` directory with one subdirectory per runnable consumer example. Each example must be its own Python project.
234
320
 
235
- ```makefile
236
- test:
237
- $(MAKE) -C basic-usage run PACKAGE_NAME=$(PACKAGE_NAME)
238
- ```
239
-
240
- **`examples/basic-usage/Makefile`**
321
+ **`examples/basic-usage/pyproject.toml`**
241
322
 
242
- ```makefile
243
- run:
244
- uv run python main.py
323
+ ```toml
324
+ [project]
325
+ name = "basic-usage"
326
+ version = "0.0.0"
327
+ requires-python = ">=[python-version]"
328
+ dependencies = []
245
329
  ```
246
330
 
331
+ The root `test-examples` target installs the wheel built into `lib/dist/` before running each
332
+ example. Do not point examples back to `../../lib` or `lib/src/`.
333
+
247
334
  **`examples/basic-usage/main.py`**
248
335
 
249
336
  ```python
@@ -253,34 +340,37 @@ from [package_name] import hello
253
340
  print(hello("world"))
254
341
  ```
255
342
 
256
- Examples must import the built package as a consumer would. Avoid relative imports back into `src/`.
343
+ Examples must import the package as a consumer would. Avoid relative imports back into `lib/src/`.
257
344
 
258
- ### Phase 5: Verify
345
+ ### Phase 6: Verify
259
346
 
260
347
  After creating the files:
261
348
 
262
- 1. Run `uv lock`.
263
- 2. Run `make lint-fix`.
264
- 3. Run `make test`.
265
- 4. Run `make build`.
266
- 5. Fix all failures before finishing.
349
+ 1. Run `make setup`.
350
+ 2. Run `make install`.
351
+ 3. Run `make lint-fix`.
352
+ 4. Run `make test`.
353
+ 5. Run `make build`.
354
+ 6. Fix all failures before finishing.
267
355
 
268
356
  ## Examples
269
357
 
270
358
  **Input:** "Create a Python library called `event_tools`"
271
- - Create `pyproject.toml`, `Makefile`, `src/event_tools/`, `tests/`, and `examples/`
359
+ - Create `Makefile`, `README.md`, `lib/pyproject.toml`, `lib/Makefile`, `lib/src/event_tools/`, `lib/tests/`, and `examples/`
360
+ - Add `lib/README.md`, `.cache/` handling, and install examples from the built wheel in `lib/dist/`
272
361
  - Configure `uv`, Ruff, Pyright, Pytest, `pytest-cov`, and `pip-audit`
273
362
  - Verify with `make lint-fix`, `make test`, and `make build`
274
363
 
275
364
  **Input:** "Scaffold a Python CLI package"
276
- - Add `src/<package_name>/__main__.py`
277
- - Add `[project.scripts]` in `pyproject.toml` when the command name must differ from the module name
365
+ - Add `lib/src/<package_name>/__main__.py`
366
+ - Add `[project.scripts]` in `lib/pyproject.toml` when the command name must differ from the module name
278
367
  - Keep the same Makefile and quality checks
279
368
 
280
369
  ## Edge Cases
281
370
 
282
- - If the repository already has a root `.mise.toml`, pin Python and uv there instead of assuming host-installed tools.
371
+ - Pin Python and uv in the root `.mise.toml`; do not assume host-installed tools.
283
372
  - If the project is fewer than 100 lines and explicitly marked as a spike or experiment, examples and linting may be skipped only when another applicable XDR allows it.
373
+ - If an example needs extra dependencies, keep them in that example's `pyproject.toml`; do not move them into `lib/pyproject.toml` unless the library truly needs them.
284
374
  - If the user asks for an app with framework-specific needs such as FastAPI or Django, keep this baseline and add the framework config on top instead of replacing it.
285
375
 
286
376
  ## References
@@ -13,9 +13,10 @@ What monorepo structure, naming conventions, tooling, and build standards should
13
13
 
14
14
  ## Decision Outcome
15
15
 
16
- **Adopt a standardized monorepo layout with top-level application folders, a shared library area, Mise-managed tooling, and Makefiles at every level so any contributor can build, lint, and test any part of the monorepo with a single, predictable command.**
16
+ **Adopt a standardized monorepo layout with top-level application folders that aggregate independent module roots, shared parent-level example and test areas, Mise-managed tooling, and Makefiles at every level.**
17
17
 
18
18
  For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/002-monorepo-setup/SKILL.md).
19
+ Module folder responsibilities, artifact locations, and test-folder conventions follow [agentme-edr-016](../principles/016-cross-language-module-structure.md).
19
20
 
20
21
  ### Policies
21
22
 
@@ -23,16 +24,26 @@ For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/
23
24
 
24
25
  ```
25
26
  /
27
+ ├── .cache/ # Optional shared cache for repo-level tooling
26
28
  ├── shared/ # Resources shared across ALL applications
27
29
  │ ├── libs/ # Reusable libraries consumed by applications
28
30
  │ └── scripts/ # Build/CI/dev scripts used across applications
29
31
 
30
32
  ├── <application>/ # One folder per application or project
31
33
  │ ├── README.md # REQUIRED
32
- │ ├── <module>/ # One folder per compilable module
34
+ │ ├── Makefile # REQUIRED
35
+ │ ├── <module>/ # One folder per buildable/publishable module
36
+ │ │ ├── Makefile # REQUIRED
37
+ │ │ ├── README.md # REQUIRED
38
+ │ │ ├── dist/ # REQUIRED when the module publishes/builds artifacts
39
+ │ │ └── .cache/ # REQUIRED when caches are not shared above
40
+ │ ├── examples/ # Optional sibling consumer examples for modules in this app
41
+ │ ├── tests_integration/# Optional cross-module integration tests for this app
42
+ │ ├── tests_benchmark/ # Optional cross-module benchmarks for this app
33
43
  │ └── shared/ # Resources shared by modules within THIS application
34
44
 
35
45
  ├── Makefile # Root Makefile coordinating all areas
46
+ ├── .gitignore # MUST ignore dist/ and .cache/
36
47
  ├── README.md # REQUIRED — onboarding and quickstart guide
37
48
  └── .mise.toml # Mise tool version configuration
38
49
  ```
@@ -42,6 +53,7 @@ For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/
42
53
  - Represent a cohesive unit with its own lifecycle (e.g., `mymobileapp`, `graph-visualizer`).
43
54
  - **MUST** depend only on resources in `/shared/`. Direct cross-application dependencies are forbidden; use published artifacts (container images, published libraries) instead.
44
55
  - **MUST** contain a `README.md` with: purpose, architecture overview, how to build, and how to run.
56
+ - **MAY** contain `examples/`, `tests_integration/`, and `tests_benchmark/` when those artifacts apply to multiple modules inside the application.
45
57
 
46
58
  *Why:* Isolating applications prevents implicit coupling and makes the `shared/` boundary explicit and intentional.
47
59
 
@@ -50,6 +62,9 @@ For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/
50
62
  - A module is a subfolder inside an application that is independently compilable and produces a build artifact.
51
63
  - May depend on sibling modules within the same application or on `/shared/` resources.
52
64
  - **MUST NOT** depend on modules from other applications.
65
+ - **MUST** contain its own `Makefile`, `README.md`, and language/tooling configuration.
66
+ - **MUST** keep build outputs under `dist/` and persistent caches under `.cache/`, following [agentme-edr-016](../principles/016-cross-language-module-structure.md).
67
+ - **MUST NOT** keep consumer examples inside the module folder; those belong in a sibling `examples/` folder at the nearest parent aggregation root.
53
68
 
54
69
  #### 4. Naming conventions
55
70
 
@@ -61,9 +76,14 @@ For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/
61
76
 
62
77
  A `Makefile` **MUST** be present at the repository root, in every application folder, and in every module folder.
63
78
 
64
- Each Makefile **MUST** define at minimum: `build`, `lint`, and `test` targets.
79
+ All Makefiles **MUST** use the shared target vocabulary from [agentme-edr-008](008-common-targets.md).
80
+
81
+ Repository, application, and module Makefiles **MUST** define at minimum: `all`, `build`, `lint`, `test`, and `clean`.
82
+
83
+ Module Makefiles **SHOULD** also provide `lint-fix` and `install` when the underlying tooling supports them.
65
84
 
66
85
  The root `Makefile` **MUST** also define a `setup` target that guides a new contributor to prepare their machine.
86
+ The root `setup` target **MUST** run `mise install` and any small repository bootstrap required before routine targets work.
67
87
 
68
88
  *Why:* Makefiles provide a universal, stack-agnostic entry point regardless of programming language.
69
89
 
@@ -72,11 +92,11 @@ The root `Makefile` **MUST** also define a `setup` target that guides a new cont
72
92
  - [Mise](https://mise.jdx.dev/) **MUST** be used to pin all tool versions (compilers, runtimes, CLI tools).
73
93
  - A `.mise.toml` **MUST** exist at the repository root.
74
94
  - Every language runtime or CLI referenced by any module `Makefile`, CI workflow, or README command **MUST** be pinned in `.mise.toml`.
75
- - Contributors run `mise install` once after cloning.
95
+ - Contributors and CI run `make setup` after cloning or checkout; this target must call `mise install`.
76
96
  - Agents and contributors **MUST** check `.mise.toml` before using a system-installed compiler, runtime, or CLI.
77
- - When `.mise.toml` exists, all build, test, lint, and code-generation commands **MUST** run inside the Mise-managed environment, preferably via `mise exec -- <command>` or an activated Mise shell.
97
+ - When `.mise.toml` exists, all build, test, lint, and code-generation commands **MUST** run through `make <target>`, and the Makefile recipes **MUST** execute the underlying tools via `mise exec -- <command>`.
78
98
  - If a required tool is missing, the first remediation step **MUST** be to update `.mise.toml` or run `mise install`, not to install ad-hoc global tools with language-specific installers such as `go install`, `npm install -g`, `pip install --user`, or `cargo install`.
79
- - Root and module `Makefile` targets **SHOULD** work correctly when invoked through `mise exec -- make <target>`.
99
+ - Root and module `Makefile` targets **MUST** work when invoked as plain `make <target>` after `make setup`.
80
100
 
81
101
  *Why:* Eliminates "works on my machine" build failures by ensuring identical tool versions across all environments.
82
102
 
@@ -84,7 +104,11 @@ The root `Makefile` **MUST** also define a `setup` target that guides a new cont
84
104
 
85
105
  The root `README.md` **MUST** include: overview, machine setup, quickstart, and a repository map.
86
106
 
87
- #### 8. Git tagging and artifact versioning
107
+ #### 8. Root `.gitignore`
108
+
109
+ The repository root **MUST** ignore `dist/` and `.cache/` so module artifacts and tool caches are never committed accidentally.
110
+
111
+ #### 9. Git tagging and artifact versioning
88
112
 
89
113
  All releases **MUST** be tagged using the format `<module-name>/<semver>` (e.g., `graphvisualizer/renderer/1.0.0`, `shared/libs/mylib/2.1.0`).
90
114
 
@@ -100,10 +124,14 @@ All releases **MUST** be tagged using the format `<module-name>/<semver>` (e.g.,
100
124
  |---|---|---|
101
125
  | Lowercase folder/file names | All | Yes |
102
126
  | `README.md` per application | Application folders | Yes |
103
- | `Makefile` with `build`, `lint`, `test` | All modules and applications | Yes |
127
+ | `README.md` per module | Module folders | Yes |
128
+ | `Makefile` with `all`, `build`, `lint`, `test`, `clean` | Root, applications, modules | Yes |
104
129
  | Root `Makefile` with `setup` target | Repository root | Yes |
105
130
  | Root `README.md` with setup + quickstart | Repository root | Yes |
131
+ | Ignore `dist/` and `.cache/` | Repository root | Yes |
106
132
  | Mise `.mise.toml` at root | Repository root | Yes |
107
133
  | Applications depend only on `/shared/` | Application folders | Yes |
108
134
  | Modules depend only on siblings or `/shared/` | Module folders | Yes |
135
+ | Module outputs live in `dist/` | Module folders | Yes |
136
+ | Persistent caches live in `.cache/` | Repo or module folders | Yes |
109
137
  | Git tags follow `<module-name>/<semver>` format | All modules | Yes |