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,7 +13,7 @@ What tooling and project structure should JavaScript/TypeScript projects follow
13
13
 
14
14
  ## Decision Outcome
15
15
 
16
- **Use a Mise-managed Node.js and pnpm toolchain together with pnpm, tsc, esbuild, eslint, and jest in a standard layout separating library code (`lib/`) from runnable usage examples (`examples/`), coordinated by root-level Makefiles.**
16
+ **Use a Mise-managed Node.js and pnpm toolchain together with pnpm, tsc, esbuild, eslint, and jest in a module-root layout that follows [agentme-edr-016](../principles/016-cross-language-module-structure.md), with runnable usage examples in sibling `examples/` folders and Makefiles as the only entry points.**
17
17
 
18
18
  Clear, consistent tooling and layout enable fast onboarding, reliable CI pipelines, and a predictable developer experience across projects.
19
19
 
@@ -23,14 +23,14 @@ Clear, consistent tooling and layout enable fast onboarding, reliable CI pipelin
23
23
 
24
24
  | Tool | Purpose |
25
25
  |------|---------|
26
- | **Mise** | Tool version management for Node.js, pnpm, and project CLIs |
26
+ | **Mise** | Mandatory tool version management and command runner for Node.js, pnpm, and project CLIs |
27
27
  | **pnpm** | Package manager — strict linking, workspace support, fast installs |
28
28
  | **tsc** | TypeScript compilation — type checking, declaration generation |
29
29
  | **esbuild** | Bundling — fast bundling for distribution or single-binary outputs |
30
30
  | **eslint** | Linting — code style and quality enforcement |
31
31
  | **jest** | Testing — unit and integration test runner |
32
32
 
33
- All commands are run exclusively through Makefiles, not through `package.json` scripts. The repository root must define a `.mise.toml` that pins at least Node.js and pnpm, and Makefile targets must run through `mise exec --` or an activated Mise shell.
33
+ All commands are run exclusively through Makefiles, not through `package.json` scripts. The repository root MUST define a `.mise.toml` that pins at least Node.js and pnpm. Contributors and CI MUST bootstrap with `make setup` or `mise install`, then invoke routine work with `make <target>`. Each Makefile recipe MUST execute the underlying tool through `mise exec -- <tool> ...` so command behavior does not depend on an activated shell. Using host-installed `node`, `pnpm`, or other project CLIs directly for routine project work is not allowed.
34
34
 
35
35
  #### ESLint
36
36
 
@@ -47,57 +47,73 @@ When `tsconfig.json` extends `@tsconfig/node24/tsconfig.json`, the default `modu
47
47
  #### Project structure
48
48
 
49
49
  ```
50
- / # workspace root
50
+ / # workspace root or parent aggregation root
51
51
  ├── .mise.toml # pinned Node.js and pnpm versions
52
+ ├── .gitignore # MUST ignore dist/ and .cache/
52
53
  ├── Makefile # delegates build/lint/test to /lib and /examples
53
- ├── README.md # Quick Start first; used as npm registry page
54
- ├── lib/ # the published npm package
54
+ ├── README.md # workspace overview and quickstart
55
+ ├── lib/ # one JavaScript/TypeScript module root
55
56
  │ ├── Makefile # build, lint, test, publish targets
57
+ │ ├── README.md # package README used for publishing
56
58
  │ ├── package.json # package manifest
57
59
  │ ├── tsconfig.json # TypeScript config for build and linting
58
60
  │ ├── jest.config.js # Jest config
59
61
  │ ├── eslint.config.mjs # ESLint config (ESLint 9 flat config)
62
+ │ ├── .cache/ # eslint, jest, tsc incremental state, coverage
63
+ │ ├── dist/ # compiled files and packed .tgz artifacts
60
64
  │ └── src/ # all TypeScript source files
61
65
  │ ├── index.ts # public API re-exports
62
66
  │ └── *.test.ts # test files co-located with source
63
- └── examples/ # runnable usage examples
64
- ├── Makefile # build + test all examples in sequence
65
- ├── usage-x/ # first example
66
- │ └── package.json
67
- └── usage-y/ # second example
68
- └── package.json
67
+ ├── examples/ # runnable usage examples outside the module root
68
+ ├── Makefile # build + test all examples in sequence
69
+ ├── usage-x/ # first example
70
+ └── package.json
71
+ └── usage-y/ # second example
72
+ └── package.json
73
+ ├── tests_integration/ # optional cross-example or cross-module integration tests
74
+ └── tests_benchmark/ # optional benchmark harnesses
69
75
  ```
70
76
 
71
- The root `Makefile` delegates every target to `/lib` then `/examples` in sequence and is expected to execute module commands inside the repository's Mise-managed environment.
77
+ The root `Makefile` delegates every target to `/lib` then `/examples` in sequence. Parent Makefiles should call child Makefiles directly, and each module Makefile is responsible for running its actual tool commands through `mise exec --`.
72
78
 
73
- The commands below assume they are invoked through `mise exec -- make <target>` or from an activated Mise shell.
79
+ When a repository contains multiple JavaScript/TypeScript packages, each package MUST live in its own module folder such as `lib/my-package/` or `services/my-service/`, each with its own `Makefile`, `README.md`, `dist/`, and `.cache/`.
80
+
81
+ Persistent caches MUST live under `.cache/`. Recommended locations are Jest `cacheDirectory`, ESLint `--cache-location`, TypeScript `tsBuildInfoFile`, and coverage outputs.
82
+
83
+ Contributors and CI MUST invoke the commands below as `make <target>`. The Makefile recipes themselves MUST call the underlying tools through `mise exec -- <tool> ...`.
74
84
 
75
85
  #### lib/Makefile targets
76
86
 
77
87
  | Target | Description |
78
88
  |--------|-------------|
79
- | `install` | `pnpm install --frozen-lockfile` |
80
- | `build` | compile with `tsc`, strip test files from `dist/`, then `pnpm pack` for local use by examples |
81
- | `build-module` | compile with `tsc` only (no pack) |
82
- | `lint` | `pnpm exec eslint ./src` |
83
- | `lint-fix` | `pnpm exec eslint ./src --fix` |
84
- | `test` | `pnpm exec jest --verbose` |
85
- | `test-watch` | `pnpm exec jest --watch` |
86
- | `clean` | remove `node_modules/` and `dist/` |
89
+ | `install` | `mise exec -- pnpm install --frozen-lockfile` |
90
+ | `build` | `mise exec -- pnpm exec tsc ...`, strip test files from `dist/`, then `mise exec -- pnpm pack` for local use by examples |
91
+ | `build-module` | `mise exec -- pnpm exec tsc ...` only (no pack) |
92
+ | `lint` | `mise exec -- pnpm exec eslint ./src` |
93
+ | `lint-fix` | `mise exec -- pnpm exec eslint ./src --fix` |
94
+ | `test` | `mise exec -- pnpm exec jest --verbose` |
95
+ | `test-watch` | `mise exec -- pnpm exec jest --watch` |
96
+ | `clean` | remove `node_modules/`, `dist/`, and `.cache/` |
87
97
  | `all` | `build lint test` |
88
- | `publish` | version-bump with `monotag`, then `npm publish --provenance` |
98
+ | `publish` | `mise exec -- npx -y monotag ...`, then `mise exec -- npm publish --provenance` |
89
99
 
90
100
  #### lib/package.json key fields
91
101
 
92
102
  - `"main"`: `dist/index.js`
93
103
  - `"types"`: `dist/index.d.ts`
94
104
  - `"files"`: `["dist/**", "package.json", "README.md"]`
95
- - `"scripts"`: empty all commands are driven by the Makefile
105
+ - `"scripts"`: empty by default. If reverse compatibility requires scripts, each script must be a direct one-line delegation to one Makefile target.
96
106
 
97
107
  #### examples/
98
108
 
99
109
  Each sub-folder under `examples/` is an independent package. The Makefile installs the locally built `.tgz` pack from `lib/dist/` so examples simulate real external usage.
100
110
 
111
+ Examples MUST remain outside the module root and MUST consume the package through the packed artifact in `dist/`, never through `../src` imports or other direct source links.
112
+
113
+ Module-specific integration tests that are not just runnable examples belong in `lib/tests_integration/` or a sibling `tests_integration/` when they cover multiple modules.
114
+
115
+ Benchmarks belong in `lib/tests_benchmark/` when they require dedicated harnesses; simple micro-benchmarks may stay co-located only if the local testing stack makes that idiomatic.
116
+
101
117
  The examples folder MUST exist for any libraries and utilities that are published or have more than 500 lines of code
102
118
 
103
119
  ### Related Skills
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: agentme-edr-010-go-project-tooling-and-structure
3
- description: Defines the standard Go project toolchain, layout, and Makefile workflow for agentme-based projects. Use when scaffolding or reviewing Go projects.
3
+ description: Defines the standard Go project toolchain, layout, and Makefile workflow using Mise for agentme-based projects. Use when scaffolding or reviewing Go projects.
4
4
  ---
5
5
 
6
6
  # agentme-edr-010: Go project tooling and structure
@@ -13,7 +13,7 @@ What tooling and project structure should Go projects follow to ensure consisten
13
13
 
14
14
  ## Decision Outcome
15
15
 
16
- **Use the standard Go toolchain (`go build`, `go test`) with `golangci-lint` for linting, feature packages in subdirectories (no `internal/` by default), a `cli/` package for command wiring, and a Makefile as the single entry point for all development tasks, with the Go toolchain and related CLIs sourced from the repository's Mise-managed environment when the repository defines `.mise.toml`.**
16
+ **Use a Mise-managed Go toolchain with `go build`, `go test`, and `golangci-lint`, module-root folder responsibilities from [agentme-edr-016](../principles/016-cross-language-module-structure.md), feature packages in subdirectories, a `cli/` package for command wiring, and a Makefile as the single entry point for all development tasks.**
17
17
 
18
18
  A predictable layout and minimal external tooling keep Go projects approachable, fast to build, and easy to distribute as cross-platform binaries.
19
19
 
@@ -23,80 +23,88 @@ A predictable layout and minimal external tooling keep Go projects approachable,
23
23
 
24
24
  | Tool | Purpose |
25
25
  |------|---------|
26
+ | **Mise** | Mandatory tool version management and command runner for Go, `golangci-lint`, and project CLIs |
26
27
  | **go toolchain** | Compilation, testing, formatting (`go build`, `go test`, `go fmt`, `go vet`, `go mod`) |
27
28
  | **golangci-lint** | Linting — aggregates many linters in one fast run; configured via `.golangci.yml` |
28
29
  | **monotag** | Version tagging from git history for the `publish` target |
29
30
 
30
- All commands are run exclusively through the Makefile, never ad-hoc.
31
- When the repository has a root `.mise.toml`, `go`, `golangci-lint`, and any other Go-related CLIs used by the project **MUST** be pinned there and resolved from the Mise-managed environment rather than the host machine.
31
+ All commands are run exclusively through the Makefile, never ad-hoc. The project root **MUST** define a `.mise.toml` that pins `go`, `golangci-lint`, and any other Go-related CLIs used by the project. Contributors and CI **MUST** bootstrap with `make setup` or `mise install`, then invoke routine work with `make <target>`. Each Makefile recipe **MUST** execute the underlying tool through `mise exec -- <tool> ...`.
32
32
  Direct installation of project-required Go CLIs with `go install ...@latest` as a repair step is **NOT** allowed unless an XDR for that repository explicitly permits it.
33
33
 
34
34
  #### Project structure
35
35
 
36
36
  ```
37
- / # project root (single Go module)
37
+ / # project root or Go module root inside a monorepo
38
+ ├── .mise.toml # pinned Go, golangci-lint, and related CLIs
38
39
  ├── Makefile # build, lint, test, publish, and utility targets
40
+ ├── README.md # module README with usage and development commands
41
+ ├── .gitignore # MUST ignore dist/ and .cache/
42
+ ├── .golangci.yml # golangci-lint configuration
39
43
  ├── go.mod # module declaration (github.com/<owner>/<project>)
40
44
  ├── go.sum # locked dependency checksums
41
45
  ├── main.go # binary entry point — argument dispatch only, no logic
42
- ├── .golangci.yml # golangci-lint configuration
43
- ├── .gitignore
44
- ├── README.md
46
+ ├── .cache/ # GOCACHE, GOMODCACHE, golangci-lint cache, coverage
47
+ ├── dist/ # built binaries and packaged outputs
45
48
  ├── <feature-a>/ # domain package (e.g. ownership/, changes/, utils/)
46
49
  │ ├── *.go # business logic
47
50
  │ └── *_test.go # unit tests co-located with source
48
51
  ├── <feature-b>/
49
52
  │ └── ...
50
- └── cli/ # CLI wiring — ties flags to domain packages
51
- ├── <feature-a>/
52
- │ └── *.go
53
- └── <feature-b>/
54
- └── *.go
53
+ ├── cli/ # CLI wiring — ties flags to domain packages
54
+ ├── <feature-a>/
55
+ └── *.go
56
+ └── <feature-b>/
57
+ └── *.go
58
+ ├── tests_integration/ # optional integration tests for this module
59
+ ├── tests_benchmark/ # optional benchmark harnesses and datasets
60
+ └── examples/ # optional sibling consumer examples for libraries
55
61
  ```
56
62
 
57
63
  **Key layout rules:**
58
64
 
59
65
  - One Go module per project (`go.mod` at the project root). In a monorepo, each Go project has its own `go.mod` in its subdirectory. No nested modules within a single project unless explicitly justified.
66
+ - In a multi-module repository, each Go module MUST live in its own folder root with its own `Makefile`, `README.md`, `dist/`, and `.cache/`.
60
67
  - `main.go` is solely an argument dispatcher — it reads `os.Args[1]` and delegates to a `cli/<feature>/Run*()` function. No domain logic lives in `main.go`.
61
68
  - Business logic lives in named feature packages at the root (e.g., `ownership/`, `changes/`, `utils/`). These packages are importable and testable without any CLI concerns.
62
69
  - `cli/` packages own flag parsing, output formatting, and the wiring between flags and domain functions. No business logic lives in `cli/`.
63
70
  - Packages are flat by default; sub-packages are only introduced when a feature package itself exceeds ~400 lines or has clearly separable sub-concerns.
71
+ - Consumer examples for reusable libraries belong in a sibling `examples/` folder and MUST import the public module path rather than reaching into internal source paths. Because Go libraries are not typically consumed from a local packaged artifact, local example validation may use a temporary module replacement for resolution, but the import path MUST remain the public module path.
64
72
 
65
73
  #### go.mod
66
74
 
67
75
  - Module path: `github.com/<owner>/<project>` (or the relevant VCS path for the project)
68
76
  - Use the latest stable Go version (e.g. `go 1.24`).
69
77
  - Separate `require` blocks: direct dependencies first, then `// indirect` dependencies.
70
- - If the repository uses Mise, the Go version declared in `go.mod` and the Go version pinned in `.mise.toml` **MUST** stay aligned.
78
+ - The Go version declared in `go.mod` and the Go version pinned in `.mise.toml` **MUST** stay aligned.
71
79
 
72
80
  #### Makefile targets
73
81
 
74
82
  | Target | Description |
75
83
  |--------|-------------|
76
84
  | `all` | Default; runs `build lint test` in sequence |
77
- | `build` | `go mod download && go build -o dist/<binary>` |
85
+ | `build` | `mise exec -- go mod download && mise exec -- go build -o dist/<binary>` with Go caches redirected into `.cache/` |
78
86
  | `build-all` | Cross-compile for all target platforms (darwin/linux/windows × amd64/arm64) |
79
87
  | `build-arch-os` | Compile for a specific `OS` and `ARCH` environment variable pair; output to `dist/${OS}-${ARCH}/<binary>` |
80
- | `install` | `go mod download` |
81
- | `lint` | `golangci-lint run ./...` |
82
- | `lint-fix` | `golangci-lint run --fix ./...` |
83
- | `test` | `go test -cover ./...` — runs all tests with coverage |
84
- | `test-unit` | `go test -cover ./...` — alias for unit tests only (same here; integration tests get a separate tag) |
85
- | `coverage` | `go tool cover -func ./coverage.out` — displays coverage summary |
86
- | `clean` | Remove `dist/` and any coverage files |
87
- | `start` | `go run ./ <default-args>` — launch the binary locally for dev use |
88
- | `publish` | Tag with `monotag`, then push tag + binaries to GitHub Releases |
89
-
90
- When the repository uses Mise, the intended invocation pattern is:
88
+ | `install` | `mise exec -- go mod download` |
89
+ | `lint` | `mise exec -- golangci-lint run ./...` with its cache redirected into `.cache/` |
90
+ | `lint-fix` | `mise exec -- golangci-lint run --fix ./...` with its cache redirected into `.cache/` |
91
+ | `test` | `mise exec -- go test -cover ./...` — runs all tests with coverage and stores disposable outputs under `.cache/` |
92
+ | `test-unit` | `mise exec -- go test -cover ./...` — alias for unit tests only (same here; integration tests get a separate tag) |
93
+ | `coverage` | `mise exec -- go tool cover -func .cache/coverage.out` — displays coverage summary |
94
+ | `clean` | Remove `dist/` and `.cache/` |
95
+ | `start` | `mise exec -- go run ./ <default-args>` — launch the binary locally for dev use |
96
+ | `publish` | Tag with `mise exec -- npx -y monotag ...`, then push tag + binaries to GitHub Releases |
97
+
98
+ The required invocation pattern is:
91
99
 
92
100
  ```sh
93
- mise install
94
- mise exec -- make build
95
- mise exec -- make test
96
- mise exec -- make lint
101
+ make setup
102
+ make build
103
+ make test
104
+ make lint
97
105
  ```
98
106
 
99
- Using `make build`, `make test`, or `make lint` from an already activated Mise shell is equivalent.
107
+ The Makefile recipes themselves must use `mise exec --` for the underlying tool commands.
100
108
 
101
109
  #### Cross-platform binary distribution
102
110
 
@@ -112,8 +120,10 @@ When the project produces a CLI binary for end-users:
112
120
  - Tests are co-located with source: `<feature>/<file>_test.go`.
113
121
  - Use `github.com/stretchr/testify` (`assert`, `require`) for test assertions.
114
122
  - Run all tests: `go test -cover ./...`
115
- - Benchmarks: `go test -bench . -benchmem -count 20`
116
- - Integration or slow tests: guard with `//go:build integration` and skip in unit runs via `-tags=unit`.
123
+ - Benchmarks: keep simple `Benchmark*` functions co-located in `*_test.go`; use `tests_benchmark/` when the benchmark needs dedicated harnesses or datasets.
124
+ - Integration or slow tests: guard with `//go:build integration` and keep them in `tests_integration/` when they are not naturally co-located with one package.
125
+
126
+ Redirect Go tool caches into `.cache/` using `GOCACHE`, `GOMODCACHE`, and `GOLANGCI_LINT_CACHE` from the module `Makefile` so the repository does not accumulate scattered cache directories.
117
127
 
118
128
  #### Linting
119
129
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: agentme-edr-014-python-project-tooling-and-structure
3
- description: Defines the standard Python project toolchain, layout, and Makefile workflow using uv, ruff, pyright, pytest, and pip-audit. Use when scaffolding or reviewing Python projects.
3
+ description: Defines the standard Python project toolchain, layout, and Makefile workflow using Mise, uv, ruff, pyright, pytest, and pip-audit. Use when scaffolding or reviewing Python projects.
4
4
  ---
5
5
 
6
6
  # agentme-edr-014: Python project tooling and structure
@@ -13,9 +13,9 @@ What tooling and project structure should Python projects follow to ensure consi
13
13
 
14
14
  ## Decision Outcome
15
15
 
16
- **Use a uv-managed Python project with `pyproject.toml`, `ruff`, `pyright`, `pytest`, `pytest-cov`, `pip-audit`, and a Makefile as the only development entry point.**
16
+ **Use a Mise-managed Python and uv toolchain with `pyproject.toml`, `ruff`, `pyright`, `pytest`, `pytest-cov`, `pip-audit`, and a layout that follows [agentme-edr-016](../principles/016-cross-language-module-structure.md): a module root under `lib/`, runnable consumer examples in sibling `examples/`, and standardized `dist/` and `.cache/` locations.**
17
17
 
18
- A single dependency manager, one canonical config file, and standard targets keep Python projects predictable for contributors and CI.
18
+ A single dependency manager, isolated package internals under `lib/`, and a standard Makefile contract keep Python projects predictable for contributors and CI while keeping the repository root clean.
19
19
 
20
20
  ### Implementation Details
21
21
 
@@ -23,6 +23,7 @@ A single dependency manager, one canonical config file, and standard targets kee
23
23
 
24
24
  | Tool | Purpose |
25
25
  |------|---------|
26
+ | **Mise** | Mandatory tool version management and command runner for Python, uv, and project CLIs |
26
27
  | **uv** | Dependency management, lockfile management, virtualenv sync, build, publish |
27
28
  | **pyproject.toml** | Single source of truth for package metadata and tool configuration |
28
29
  | **ruff** | Formatting, import sorting, linting, and common code-quality checks |
@@ -33,42 +34,66 @@ A single dependency manager, one canonical config file, and standard targets kee
33
34
 
34
35
  All routine commands must run through the project `Makefile`, never by calling `uv`, `ruff`, `pytest`, or `pyright` directly in docs, CI, or daily development workflows.
35
36
 
36
- When the repository defines a root `.mise.toml`, Python and uv must be pinned there and commands should run through `mise exec --` or an activated Mise shell.
37
+ The repository root MUST define a `.mise.toml` that pins Python and uv. Contributors and CI MUST bootstrap with `make setup` or `mise install`, then invoke routine work with `make <target>`. Each Makefile recipe MUST execute the underlying tool through `mise exec -- <tool> ...`. Using host-installed `python`, `uv`, or other project CLIs directly for routine project work is not allowed.
38
+
39
+ The root `.venv/` is the canonical environment location for both the library and all examples. Subdirectory commands must set `UV_PROJECT_ENVIRONMENT` to the workspace root `.venv/` instead of creating nested virtual environments.
40
+
41
+ Persistent caches must live under `.cache/`, preferably the module `lib/.cache/` plus a shared root `.cache/uv/` when uv cache sharing is desired.
37
42
 
38
43
  #### Project structure
39
44
 
40
45
  ```text
41
46
  /
42
- ├── .mise.toml # optional but required when the repo uses Mise
43
- ├── Makefile # single entry point for build/lint/test/run tasks
44
- ├── pyproject.toml # package metadata + tool config
45
- ├── uv.lock # committed lockfile
46
- ├── README.md # Getting Started near the top
47
- ├── src/
48
- │ └── <package_name>/
49
- ├── __init__.py
50
- ├── __main__.py # when the project exposes a CLI
51
- └── ...
52
- ├── tests/
53
- │ ├── conftest.py # shared fixtures when needed
54
- └── test_*.py
55
- └── examples/ # required for libraries and shared utilities
56
- ├── Makefile
57
- └── basic-usage/
47
+ ├── .mise.toml # required; pins Python and uv
48
+ ├── .gitignore
49
+ ├── .cache/ # optional shared uv cache at repo level
50
+ ├── .venv/ # shared uv environment for lib/ and examples/
51
+ ├── Makefile # root entry point; delegates to lib/ and runs examples/
52
+ ├── README.md # workspace/repository overview
53
+ ├── lib/ # everything the published library needs
54
+ ├── Makefile # build, lint, test, publish targets for the library
55
+ ├── pyproject.toml # package metadata + tool config
56
+ ├── uv.lock # committed lockfile for the library
57
+ ├── README.md # package README used for publishing
58
+ │ ├── .cache/ # pytest, Ruff, coverage, Python bytecode cache
59
+ ├── src/
60
+ │ │ └── <package_name>/
61
+ │ │ ├── __init__.py
62
+ │ │ ├── __main__.py # when the project exposes a CLI
63
+ │ │ └── ...
64
+ │ ├── tests/
65
+ │ │ ├── conftest.py # shared fixtures when needed
66
+ │ │ └── test_*.py
67
+ │ ├── tests_integration/ # optional integration tests for this module
68
+ │ ├── tests_benchmark/ # optional benchmark harnesses and datasets
69
+ │ └── dist/ # wheels / sdists built from lib/
70
+ └── examples/ # independent consumer projects
71
+ ├── example1/
72
+ │ ├── pyproject.toml
73
+ │ └── main.py
74
+ └── example2/
75
+ ├── pyproject.toml
76
+ └── main.py
58
77
  ```
59
78
 
60
- Use the `src/` layout for import safety and packaging clarity. Keep tests under `tests/` and shared test setup in `tests/conftest.py`. Do not introduce `requirements.txt`, `setup.py`, `setup.cfg`, `tox.ini`, `ruff.toml`, or `pyrightconfig.json` by default; keep project metadata and tool configuration in `pyproject.toml`.
79
+ Keep the repository root clean: source code, tests, distribution artifacts, and package metadata live under `lib/`, while the root contains only orchestration and repository-level files.
80
+
81
+ Use the `lib/src/` layout for import safety and packaging clarity. Keep tests under `lib/tests/` and shared test setup in `lib/tests/conftest.py`. Do not introduce `requirements.txt`, `setup.py`, `setup.cfg`, `tox.ini`, `ruff.toml`, or `pyrightconfig.json` by default; keep project metadata and tool configuration in `lib/pyproject.toml`.
61
82
 
62
- Libraries and shared utilities must include an `examples/` folder and wire example execution into the root `test` flow, following [agentme-edr-007](../principles/007-project-quality-standards.md).
83
+ Libraries and shared utilities must include an `examples/` folder and wire example execution into the root `test` flow, following [agentme-edr-007](../principles/007-project-quality-standards.md). Each example directory is its own Python project with its own `pyproject.toml`, and examples must import the library as a consumer would rather than reaching back into `lib/src/` with relative imports. Local example verification must install the wheel built into `lib/dist/`; do not use editable or path-based dependencies back to `lib/`.
63
84
 
64
- #### `pyproject.toml`
85
+ Python keeps unit tests under `lib/tests/` by default because that remains the more common and maintainable convention for typed/package-based projects than co-locating tests beside every source file. Integration tests belong in `lib/tests_integration/`, and benchmark harnesses belong in `lib/tests_benchmark/` when they are more than a single micro-benchmark helper.
86
+
87
+ #### `lib/pyproject.toml`
65
88
 
66
89
  - Runtime dependencies belong in `[project.dependencies]`.
67
90
  - Development-only tooling belongs in `[dependency-groups].dev`.
68
- - Configure Ruff, Pyright, and Pytest in `pyproject.toml` under their `tool.*` sections.
69
- - Commit `uv.lock` and keep it in sync with `pyproject.toml`.
91
+ - Configure Ruff, Pyright, and Pytest in `lib/pyproject.toml` under their `tool.*` sections.
92
+ - Commit `lib/uv.lock` and keep it in sync with `lib/pyproject.toml`.
70
93
  - Expose CLI entry points with `[project.scripts]` when the project provides commands.
71
94
 
95
+ When Pyright runs from `lib/`, configure it to discover the shared root virtual environment, for example with `venvPath = ".."` and `venv = ".venv"`.
96
+
72
97
  Ruff is the default formatter and linter. Do not add Black, isort, or Flake8 unless another XDR for that repository explicitly requires them.
73
98
 
74
99
  Pyright must run on every lint pass. `typeCheckingMode = "standard"` is the minimum baseline; projects may raise this to `strict` when the codebase is ready.
@@ -77,23 +102,40 @@ Pytest coverage must fail below 80% line and branch coverage, following [agentme
77
102
 
78
103
  #### Makefile targets
79
104
 
80
- The commands below assume invocation through `mise exec -- make <target>` when the repository uses Mise, or plain `make <target>` inside an activated project environment.
105
+ Contributors and CI MUST invoke the commands below as `make <target>`. The Makefile recipes themselves MUST call the underlying tools through `mise exec -- <tool> ...`.
106
+
107
+ #### Root `Makefile`
108
+
109
+ The root `Makefile` is the only contract for CI and contributors. It delegates library work to `lib/` and runs each example project in `examples/` against the shared root `.venv/`.
81
110
 
82
111
  | Target | Description |
83
112
  |--------|-------------|
84
- | `install` | `uv sync --frozen --all-extras --dev` |
85
- | `build` | `uv sync --frozen --all-extras --dev && uv build` |
86
- | `lint` | `uv run ruff format --check . && uv run ruff check . && uv run pyright && uv run pip-audit` |
87
- | `lint-fix` | `uv run ruff format . && uv run ruff check . --fix && uv run pyright && uv run pip-audit` |
88
- | `test-unit` | `uv run pytest --cov=src/<package_name> --cov-branch --cov-report=term-missing --cov-fail-under=80` |
89
- | `test-examples` | Run `examples/` through its own `Makefile` when the project is a library/utility |
113
+ | `setup` | Run `mise install`, then `lib/install` to create or update the shared root `.venv/` |
114
+ | `install` | Run `lib/install` to create or update the shared root `.venv/` |
115
+ | `build` | Run `lib/build` |
116
+ | `lint` | Run `lib/lint` |
117
+ | `lint-fix` | Run `lib/lint-fix` |
118
+ | `test-unit` | Run `lib/test-unit` |
119
+ | `test-examples` | For each `examples/*/pyproject.toml`, sync and run the example serially against the shared root `.venv/` |
90
120
  | `test` | Run `test-unit`, then `test-examples` when applicable |
91
- | `clean` | Remove `.venv/`, `dist/`, `.pytest_cache/`, `.ruff_cache/`, `.coverage`, `htmlcov/` |
121
+ | `clean` | Remove the shared root `.venv/`, root `.cache/`, and delegate cleanup to `lib/` |
92
122
  | `all` | `build lint test` |
93
- | `update-lockfile` | `uv lock --upgrade` |
94
- | `run` | `uv run python -m <package_name>` or the project CLI entry point |
123
+
124
+ #### `lib/Makefile`
125
+
126
+ | Target | Description |
127
+ |--------|-------------|
128
+ | `install` | `mise exec -- uv sync --project . --frozen --all-extras --dev` using the shared root `.venv/` |
129
+ | `build` | `mise exec -- uv sync --project . --frozen --all-extras --dev && mise exec -- uv build --project . --out-dir dist` |
130
+ | `lint` | `mise exec -- uv run --project . ruff format --check . && mise exec -- uv run --project . ruff check . && mise exec -- uv run --project . pyright && mise exec -- uv run --project . pip-audit`, with caches redirected into `.cache/` |
131
+ | `lint-fix` | `mise exec -- uv run --project . ruff format . && mise exec -- uv run --project . ruff check . --fix && mise exec -- uv run --project . pyright && mise exec -- uv run --project . pip-audit`, with caches redirected into `.cache/` |
132
+ | `test-unit` | `mise exec -- uv run --project . pytest --cov=src/<package_name> --cov-branch --cov-report=term-missing --cov-fail-under=80`, with pytest and coverage outputs stored under `.cache/` |
133
+ | `clean` | Remove `dist/` and `.cache/` inside `lib/` |
134
+ | `all` | `build lint test-unit` |
135
+ | `update-lockfile` | `mise exec -- uv lock --project . --upgrade` |
136
+ | `run` | `mise exec -- uv run --project . python -m <package_name>` or the project CLI entry point |
95
137
  | `dev` | Same as `run`, optionally with repository-specific dev defaults |
96
- | `publish` | `uv publish` after versioning and packaging are complete |
138
+ | `publish` | `mise exec -- uv publish --project .` after versioning and packaging are complete |
97
139
 
98
140
  The root `Makefile` must remain the only contract for CI and contributors, in line with [agentme-edr-008](../devops/008-common-targets.md).
99
141
 
@@ -101,8 +143,8 @@ The root `Makefile` must remain the only contract for CI and contributors, in li
101
143
 
102
144
  * (REJECTED) **Mixed Python tooling** - Separate tools and config files such as `pip`, `requirements.txt`, `setup.cfg`, `flake8`, and `mypy`.
103
145
  * Reason: Increases cognitive load, duplicates configuration, and weakens the standard command surface across projects.
104
- * (CHOSEN) **uv + `pyproject.toml` + Ruff/Pyright/Pytest toolchain** - One dependency manager, one config file, and one Makefile entry point.
105
- * Reason: Keeps packaging, dependency locking, static analysis, security auditing, and test execution consistent.
146
+ * (CHOSEN) **uv + `lib/` package layout + Ruff/Pyright/Pytest toolchain** - One dependency manager, package internals isolated under `lib/`, consumer examples under `examples/`, and one root Makefile contract.
147
+ * Reason: Keeps packaging, dependency locking, static analysis, security auditing, and test execution consistent while aligning Python repositories with the established JavaScript layout.
106
148
 
107
149
  ## References
108
150