diff --git a/.agents/skills/polylith/README.md b/.agents/skills/polylith/README.md new file mode 100644 index 00000000..bbe59a6c --- /dev/null +++ b/.agents/skills/polylith/README.md @@ -0,0 +1,36 @@ + +# Polylith Skills + +> **Note for contributors:** this README is a **human reference**. The agent loads each `*/SKILL.md` independently via the skill loader; this file is **not** auto-loaded with any skill. Anything an agent must know to act has to live in the relevant `SKILL.md` itself, not here. + +## Available Skills + +| Skill | Command | Purpose | +|---------------------------|--------------------|----------------------------------------------------------------------------------------------------------| +| [Workspace Setup](./workspace_setup/SKILL.md) | `poly create workspace` | Initialize a Polylith workspace (`workspace.toml`, top-level dirs). | +| [Component Creation](./component_creation/SKILL.md) | `poly create component` | Create a reusable brick (business logic, domain, capability). | +| [Base Creation](./base_creation/SKILL.md) | `poly create base` | Create an entry-point brick (HTTP API, CLI, Lambda handler). | +| [Project Management](./project_management/SKILL.md) | `poly create project` | Create a deployable project that references bricks. | +| [Brick Removal](./brick_removal/SKILL.md) | — | Safely delete a component or base (no `poly remove` exists). | +| [Sync](./sync/SKILL.md) | `poly sync` | Update each project's brick list to match actual imports. | +| [Workspace Inspection](./workspace_inspection/SKILL.md) | `poly info` | Show brick × project usage (which projects use which bricks). | +| [Dependency Visualization](./dependency_visualization/SKILL.md) | `poly deps` | Show brick × brick dependencies and interface compliance. | +| [Testing](./testing/SKILL.md) | `poly test diff` | List bricks/projects affected by **test-code** changes since a tag. | +| [Diff](./diff/SKILL.md) | `poly diff` | List bricks whose **implementation** changed since a tag. | +| [Check](./check/SKILL.md) | `poly check` | Validate the workspace (CI gate; exits 1 on failure). | +| [Libs](./libs/SKILL.md) | `poly libs` | Inspect third-party libraries per project. | +| [Concepts](./concepts/SKILL.md) | — | Provides foundational knowledge about Polylith architecture and terminology. | + +--- + +## For humans — getting started + +1. **Set up the workspace** — [Workspace Setup](./workspace_setup/SKILL.md). +2. **Understand the basics** — [Concepts](./concepts/SKILL.md). +3. **Create bricks** — [Component Creation](./component_creation/SKILL.md) and [Base Creation](./base_creation/SKILL.md). +4. **Create deployable projects** — [Project Management](./project_management/SKILL.md). +5. **Remove bricks safely** — [Brick Removal](./brick_removal/SKILL.md). +6. **Sync brick usage** — [Sync](./sync/SKILL.md). +7. **Inspect** — [Workspace Inspection](./workspace_inspection/SKILL.md) (brick × project) and [Dependency Visualization](./dependency_visualization/SKILL.md) (brick × brick). +8. **Validate** — [Check](./check/SKILL.md) (CI gate) and [Libs](./libs/SKILL.md) (library inspection). +9. **Diff between releases** — [Diff](./diff/SKILL.md) and [Testing](./testing/SKILL.md). diff --git a/.agents/skills/polylith/base_creation/SKILL.md b/.agents/skills/polylith/base_creation/SKILL.md new file mode 100644 index 00000000..c25c632b --- /dev/null +++ b/.agents/skills/polylith/base_creation/SKILL.md @@ -0,0 +1,56 @@ +--- +name: polylith-base-creation +description: Create a Polylith base with `poly create base` — the entry point of a deployable application (HTTP API, CLI, message-queue consumer, AWS Lambda handler, GCP Cloud Function, scheduled job). Use when the user wants to add a service, API, endpoint, handler, or any new entry point to a Polylith workspace. +--- + +# Base Creation Skill + +> 💡 **Terminology:** this skill uses Polylith terms like *brick*, *base*, *namespace*, and *theme*. If they're unfamiliar, load `polylith-concepts` first. + +## Quick command + +```bash +uv run poly create base --name api +``` + +**Command prefix:** If you do not know the package manager, list lock files with `ls uv.lock poetry.lock pdm.lock 2>/dev/null` (a `pyproject.toml` is always present, so it tells you nothing on its own). Use `uv run poly` (uv), `poetry poly` (poetry), `pdm run poly` (pdm), `hatch run poly` (hatch), or `poly` (activated venv). Examples below use `uv run`. + +> A **base** is the entry point of a deployable application. For non-entry-point reusable code (business logic, capabilities), use `polylith-component-creation` instead. + +## Command reference + +| Option | Required | Default | Description | +|-----------------|----------|---------|--------------------------------------------| +| `--name` | yes | — | Name of the base (also the package name). | +| `--description` | no | `""` | Optional human-readable description. | + +## What gets created (loose theme) + +``` +bases//api/ +├── __init__.py # Public interface — empty; add re-exports here +└── core.py # Implementation — empty; user fills it in +``` + +If `[tool.polylith.test].enabled = true` in `workspace.toml`, the CLI also creates `test/bases//api/test_core.py`. + +For the `tdd` theme layout (`bases/api/{src,test}//api/...`), load the `polylith-workspace-setup` skill. + +## Examples + +```bash +# Minimal +uv run poly create base --name api + +# With description +uv run poly create base --name consumer --description "Kafka order consumer" +``` + +## Notes for the agent +- `core.py` is **empty boilerplate** — there is no FastAPI/Typer/Lambda scaffolding. Fill it in manually after creation if asked. +- `__init__.py` is also empty. By Polylith convention it should re-export the brick's public symbols, so consumers import `from .api import …` rather than reaching into `core.py`. +- A new base is **not** wired into any project. To wire it: load `polylith-sync` and run `poly sync`, or run `poly create project` (the interactive prompt will offer to attach the base). +- The same command works for both `loose` and `tdd` themes — the CLI reads `[tool.polylith.structure].theme` from `workspace.toml`. + +## Verification +After creation, verify the base exists using your file tools (e.g., check `bases///__init__.py`). Then, you will likely need to populate `core.py` and `__init__.py` using your file writing tools since they are created empty. diff --git a/.agents/skills/polylith/brick_removal/SKILL.md b/.agents/skills/polylith/brick_removal/SKILL.md new file mode 100644 index 00000000..102f4d73 --- /dev/null +++ b/.agents/skills/polylith/brick_removal/SKILL.md @@ -0,0 +1,27 @@ +--- +name: polylith-brick-removal +description: Safely remove a Polylith brick (component or base) from the workspace. Use when the user wants to delete, remove, or tear down a component or base. +--- + +# Brick Removal Skill + +> 💡 **Terminology:** this skill uses Polylith terms like *brick*, *component*, *base*, and *development project*. If they're unfamiliar, load `polylith-concepts` first. + +There is no `poly remove` CLI command. Removing a brick is a manual process. + +## Steps to remove a brick + +1. **Delete the source code:** + Delete the brick's directory under `components//` or `bases//`. +2. **Delete the tests:** + Delete the brick's test directory under `test/components//` or `test/bases//`. +3. **Remove from projects:** + Search across all `projects/*/pyproject.toml` files and remove the brick from the `[tool.polylith.bricks]` section. +4. **Remove from the development project:** + Remove the brick from the `[tool.polylith.bricks]` section in the root `pyproject.toml` (the development project). +5. **Sync and Check:** + Run `poly sync` (load `polylith-sync`) and `poly check` (load `polylith-check`) to ensure the workspace is valid and no other bricks were importing the deleted brick. + +## Notes for the agent +- Always use your directory and file tools to verify the paths before deleting. +- If `poly check` fails after removal, it means another brick was depending on the removed brick. You must fix the importing brick. diff --git a/.agents/skills/polylith/check/SKILL.md b/.agents/skills/polylith/check/SKILL.md new file mode 100644 index 00000000..edf2472c --- /dev/null +++ b/.agents/skills/polylith/check/SKILL.md @@ -0,0 +1,61 @@ +--- +name: polylith-check +description: Validate a Polylith workspace with `poly check` — the canonical CI gate. Verifies brick imports against project `pyproject.toml`s, third-party library declarations vs. the lock file, and (under `--strict`) cross-project version consistency. Exits 1 on failure. Use when the user wants to lint, validate, verify, or CI-gate a Polylith workspace. +--- + +# Check Skill + +## Quick command + +```bash +uv run poly check +``` + +**Command prefix:** If you do not know the package manager, list lock files with `ls uv.lock poetry.lock pdm.lock 2>/dev/null` (a `pyproject.toml` is always present, so it tells you nothing on its own). Use `uv run poly` (uv), `poetry poly` (poetry), `pdm run poly` (pdm), `hatch run poly` (hatch), or `poly` (activated venv). Examples below use `uv run`. + +> ⚠ **Run `poly sync` first** if bricks have been added/removed since the last commit, otherwise sync-related findings will dominate the report. Load `polylith-sync` if needed. +> ⚠ **Exit code 1 = failure** — this is the right command to wrap in CI. + +## Typical CI usage + +```bash +uv run poly sync --quiet # Make sure brick lists are current (--quiet avoids the interactive prompt) +uv run poly check # Validate; build fails if non-zero + +# (Optional) scope test runs to bricks whose implementation changed. +# `poly diff --bricks --short` emits a comma-separated list, which becomes a +# pytest `-k` expression (`log,message` → `pytest -k "log or message"`). +changes="$(uv run poly diff --bricks --short)" +[ -n "$changes" ] && uv run pytest -k "${changes//,/ or }" +``` + +> Use `poly diff` (implementation diff) for "run tests for what changed". Use `poly test diff --short` if you specifically want to scope on **test-code** changes — load `polylith-testing` for that variant. Both feed the same `pytest -k` recipe. + +## What it verifies +- Every brick imported by another brick is listed in the consuming project's `[tool.polylith.bricks]`. +- Every third-party library imported by a project's bricks is declared in that project's `dependencies` and present in the lock file. + +## Command reference + +| Option | Default | Description | +|----------------|---------|---------------------------------------------------------------------------------------------------------| +| `--strict` | `false` | Stricter name/version matching across projects (catches version drift). | +| `--verbose` | `false` | Print extra context, including lock-file lookups. | +| `--quiet` | `false` | Suppress output. Exit code unchanged. | +| `--alias` | — | Comma-separated `import_name=package_name` aliases. | +| `--directory` | cwd | Limit the check to projects whose path matches this directory. | + +## Examples + +```bash +# Standard CI gate +uv run poly check + +# One project only +uv run poly check --directory projects/user_api +``` + +## Common failure modes & Auto-Fixes +1. **Missing Brick Error:** If the error says a brick imports another brick that isn't in `[tool.polylith.bricks]` → run `poly sync` (load `polylith-sync`). +2. **Missing Dependency Error:** If the error says a brick imports a third-party library not listed in the project's `dependencies` → load `polylith-dependency-management` and add the library to the project's `pyproject.toml`. +3. **Version Drift Error:** Under `--strict`, if versions of the same library diverge between projects → inspect `pyproject.toml` or load `polylith-libs` to find the drift, then align versions (or rely on a single root lock file). diff --git a/.agents/skills/polylith/component_creation/SKILL.md b/.agents/skills/polylith/component_creation/SKILL.md new file mode 100644 index 00000000..41e6c373 --- /dev/null +++ b/.agents/skills/polylith/component_creation/SKILL.md @@ -0,0 +1,59 @@ +--- +name: polylith-component-creation +description: Create a Polylith component with `poly create component` — a reusable, isolated brick implementing business logic, a feature, a domain module, or a capability. Use when adding non-entry-point code that bases or other components will import. +--- + +# Component Creation Skill + +> 💡 **Terminology:** this skill uses Polylith terms like *brick*, *component*, *namespace*, and *theme*. If they're unfamiliar, load `polylith-concepts` first. + +## Quick command + +```bash +uv run poly create component --name user_service +``` + +**Command prefix:** If you do not know the package manager, list lock files with `ls uv.lock poetry.lock pdm.lock 2>/dev/null` (a `pyproject.toml` is always present, so it tells you nothing on its own). Use `uv run poly` (uv), `poetry poly` (poetry), `pdm run poly` (pdm), `hatch run poly` (hatch), or `poly` (activated venv). Examples below use `uv run`. + +> A **component** is reusable, non-entry-point code (business logic, domain features, capabilities). For entry points (HTTP API, CLI, Lambda handler), use `polylith-base-creation` instead. + +## Command reference + +| Option | Required | Default | Description | +|-----------------|----------|---------|---------------------------------------------------| +| `--name` | yes | — | Name of the component (also the package name). | +| `--description` | no | `""` | Optional human-readable description. | + +## What gets created (loose theme) + +``` +components//user_service/ +├── __init__.py # Public interface — empty; add re-exports here +└── core.py # Implementation — empty; user fills it in +``` + +If `[tool.polylith.test].enabled = true` in `workspace.toml`, the CLI also creates `test/components//user_service/test_core.py`. + +For the `tdd` theme layout (`components/user_service/{src,test}//user_service/...`), load `polylith-workspace-setup`. + +## Examples + +```bash +# Minimal +uv run poly create component --name user_service + +# With description +uv run poly create component --name greeting --description "Greeting domain" +``` + +## Notes for the agent +- Both `core.py` and `__init__.py` are **empty boilerplate**. The component is not "ready" — the user fills in `core.py`, then re-exports its public API from `__init__.py`: + ```python + # components//user_service/__init__.py + from .user_service.core import create_user, get_user + ``` +- Consumers import via the public interface (`from .user_service import create_user`), never via `core.py` directly. `poly deps --interface` (load `polylith-dependency-visualization`) flags violations. +- A new component is **not** automatically used by any project. It is registered in a project once a base (or another component already in the project) imports it — then run `poly sync` (load `polylith-sync`). + +## Verification +After creation, verify the component exists using your file tools (e.g., check `components///__init__.py`). Then, you will likely need to populate `core.py` and `__init__.py` using your file writing tools since they are created empty. diff --git a/.agents/skills/polylith/concepts/SKILL.md b/.agents/skills/polylith/concepts/SKILL.md new file mode 100644 index 00000000..b713388d --- /dev/null +++ b/.agents/skills/polylith/concepts/SKILL.md @@ -0,0 +1,58 @@ +--- +name: polylith-concepts +description: Provides foundational knowledge about Polylith architecture, including the glossary (bases, components, projects, workspaces), theme layouts, and package manager mapping. Use this when you need to understand Polylith terminology or how the repository is structured conceptually before taking action. +--- + +# Polylith Concepts & Glossary + +## Glossary + +### Bricks +The fundamental units of code in Polylith — **components** and **bases**. Bricks are reusable, isolated, and organized under a single **namespace**. + +### Components +Reusable, isolated bricks that implement business logic or capabilities. Components are consumed by bases and by other components, never the other way around. + +### Bases +Bricks that serve as the **entry point** of a deployable application — for example HTTP APIs, CLIs, message-queue consumers, AWS Lambda handlers, GCP Cloud Functions, or scheduled jobs. A base wires together components and exposes the application to its runtime. + +### Namespace +The top-level Python package name under which all bricks live (e.g. `mycompany`). Defined once in `[tool.polylith].namespace` in `workspace.toml`; shared by every brick. + +### Workspace +The root directory of a Polylith repository. Contains `workspace.toml`, the root `pyproject.toml` (which **is** the development project), the `bases/`, `components/`, `projects/`, and `development/` directories, and a single shared lock file. + +### Projects +Lightweight `pyproject.toml` configurations under `projects//` that **reference bricks** to produce deployable artifacts (Docker images, wheels, Lambda packages). Projects contain no Python source code of their own. + +### Development Project +The root `pyproject.toml` itself — a single, unified Python environment that includes **every** brick and **every** dependency (production and dev). Used for local development, REPL sessions, and notebooks under `development/`. + +### Dependencies +- The **development project** (root `pyproject.toml`) holds **all** dependencies, including dev-only ones. +- Each **project** under `projects/` holds only its **production** dependencies. +- With **uv workspaces**, individual projects don't need to pin third-party versions — the root `pyproject.toml` and the shared lock file pin versions centrally. + +## Package & Dependency Management mapping + +The `poly` CLI is package-manager-agnostic — only the **command prefix** changes. Each SKILL.md repeats the prefix detection rule inline so the agent doesn't need this README to act. The full table: + +| Tool | Detection signal | Command prefix | +|-------------------------------|------------------------------------------------------------------------|-------------------| +| **uv** (recommended) | `uv.lock` present, or `[tool.uv]` in `pyproject.toml` | `uv run poly …` | +| **Poetry** | `[tool.poetry]` in `pyproject.toml`, `poetry.lock` | `poetry poly …` (via `poetry-polylith-plugin`) | +| **PDM** | `[tool.pdm]` in `pyproject.toml`, `pdm.lock` | `pdm run poly …` | +| **Hatch** | `[tool.hatch]` in `pyproject.toml` | `hatch run poly …`| +| **Rye** | `requirements.lock` + `[tool.rye]` | `rye run poly …` | +| **Activated virtualenv** | `$VIRTUAL_ENV` set, or none of the above | `poly …` | + +If multiple signals are present, prefer the lock file that exists, then `[tool.]` markers, then plain `poly`. + +## Themes + +`[tool.polylith.structure].theme` controls the on-disk brick layout: + +- **`loose`** (recommended) — flat `///` directories with tests in a top-level `test/` folder. Used by `python-polylith` itself and by most public examples. +- **`tdd`** — each brick is its own directory with `src/` and `test/` siblings. + +> The CLI default for `poly create workspace --theme` is **`tdd`**. Always pass `--theme loose` explicitly when loose is wanted. diff --git a/.agents/skills/polylith/dependency_management/SKILL.md b/.agents/skills/polylith/dependency_management/SKILL.md new file mode 100644 index 00000000..8fa6430d --- /dev/null +++ b/.agents/skills/polylith/dependency_management/SKILL.md @@ -0,0 +1,48 @@ +--- +name: polylith-dependency-management +description: Add or manage third-party dependencies in a Polylith workspace. Use when the user wants to install a new library (e.g., requests, fastapi) for a brick or project. +--- + +# Dependency Management Skill + +> 💡 **Terminology:** this skill uses Polylith terms like *brick*, *project*, and *development project*. If they're unfamiliar, load `polylith-concepts` first. + +Polylith manages third-party dependencies differently than standard Python projects. + +## Rules for adding dependencies + +1. **The Development Project (Root):** + **Every** third-party library used anywhere in the workspace must be added to the root `pyproject.toml` (the development project). This ensures local REPLs, tests, and the shared lockfile work correctly. Use your package manager (e.g., `uv add `, `poetry add `) at the workspace root. +2. **Deployable Projects (`projects/`):** + If a library is required for production by a specific deployable project, it must **also** be added to that project's `pyproject.toml` under `projects//`. Do this by manually editing the `dependencies` array in `projects//pyproject.toml`. + +> ⚠ **Never add dependencies to a brick's directory.** Bricks do not have their own `pyproject.toml` files. + +## Example Workflow: Adding `requests` to an `api` project + +1. Install it at the root so the lockfile updates and it's available for local development: + ```bash + uv add requests + ``` +2. Manually add it to the deployable project that needs it: + Edit `projects/api/pyproject.toml`. + + **Important Versioning Rule:** Before adding the dependency to the project, check the root `pyproject.toml`. If it contains a `[tool.uv.workspace]` section (e.g., `members = ["projects/*"]`), then `uv workspaces` is enabled. + + If `uv workspaces` is enabled, **do not specify the version** in the project's `pyproject.toml`. Just use the package name, because versions are centrally pinned in the root. If workspaces are not enabled, then you should specify the version. + + ```toml + # WITH uv/poetry workspaces enabled (Recommended): + dependencies = [ + "requests" + ] + + # WITHOUT workspaces enabled: + dependencies = [ + "requests>=2.31.0" + ] + ``` +3. Run `poly check` (load `polylith-check`) to verify the workspace is valid. `poly check` will catch if a project imports `requests` but forgot to declare it in its `pyproject.toml`. + +## Notes for the agent +- Use `poly libs` (load `polylith-libs`) to inspect current dependency usage across projects. diff --git a/.agents/skills/polylith/dependency_visualization/SKILL.md b/.agents/skills/polylith/dependency_visualization/SKILL.md new file mode 100644 index 00000000..9c56af02 --- /dev/null +++ b/.agents/skills/polylith/dependency_visualization/SKILL.md @@ -0,0 +1,82 @@ +--- +name: polylith-dependency-visualization +description: Visualize **brick × brick** dependencies with `poly deps` — find circular dependencies, inspect a brick's public interface, and detect interface-bypass violations. Use for "what depends on what", "circular deps", "interface violation". For brick × project usage, use `polylith-workspace-inspection`. +--- + +# Dependency Visualization Skill + +## Quick command + +```bash +uv run poly deps +``` + +**Command prefix:** If you do not know the package manager, list lock files with `ls uv.lock poetry.lock pdm.lock 2>/dev/null` (a `pyproject.toml` is always present, so it tells you nothing on its own). Use `uv run poly` (uv), `poetry poly` (poetry), `pdm run poly` (pdm), `hatch run poly` (hatch), or `poly` (activated venv). Examples below use `uv run`. + +> **`poly deps` vs `poly info`:** +> - `poly deps` → **brick × brick** (dependencies between bricks; interface compliance). +> - `poly info` → **brick × project** (which projects use which brick). Load `polylith-workspace-inspection`. +> ⚠ `poly deps` does **not** fail on warnings (circular deps, interface violations are informational). For pass/fail, use `poly check` (load `polylith-check`). + +## Command reference + +| Option | Default | Description | +|----------------|---------|----------------------------------------------------------------------------------------------| +| `--brick` | — | Restrict output to the named brick. | +| `--interface` | `false` | Show the brick's public interface and flag bricks that bypass it. | +| `--save` | `false` | Persist the report to a file under the workspace's output dir. | +| `--directory` | cwd | Restrict analysis to projects whose path matches this directory. | + +## Examples + +```bash +# Full matrix +uv run poly deps + +# One brick + interface compliance check +uv run poly deps --brick message --interface + +# Save report +uv run poly deps --save +``` + +### Output format + +``` + d g + a r m + t e e s + a e k s c + b t a s h + a i f l a e + s n k o g m + brick e g a g e a + ───────────────────────────────────────────── + greeting - - - - - - + kafka - - - ✔ - - + message ✔ - ✔ - - ✔ + greet_api - ✔ - ✔ - - +``` + +`✔` = row brick imports column brick. + +### Warning messages + +``` +ℹ brick_a is used by brick_b and also uses brick_a. # circular +ℹ Found in brick_a: helloworld is not part of the public interface of brick_b. # interface violation +``` + +## Fixing an interface violation + +When `--interface` reports a violation: +1. Identify the offending import in the violating brick (e.g. `from .brick_b.internal import helloworld`). +2. Add `helloworld` to `/brick_b/__init__.py`: + ```python + from .brick_b.internal import helloworld + ``` +3. Update the importer to `from .brick_b import helloworld`. +4. Re-run `poly deps --interface` to confirm. + +## Notes for the agent +- Circular deps usually mean two bricks share a concept that should be extracted into a third brick — flag this for the user; don't silently break the cycle by hiding imports. diff --git a/.agents/skills/polylith/diff/SKILL.md b/.agents/skills/polylith/diff/SKILL.md new file mode 100644 index 00000000..634f82e7 --- /dev/null +++ b/.agents/skills/polylith/diff/SKILL.md @@ -0,0 +1,68 @@ +--- +name: polylith-diff +description: List Polylith bricks whose **implementation** changed since a git tag using `poly diff`. Use for release notes, selective deploys ("which projects need rebuilding?"), and PR scope review. For TEST-code diffs, use `polylith-testing` instead. +--- + +# Diff Skill + +## Quick command + +```bash +# Human-readable (default) +uv run poly diff + +# Pipe-friendly: comma-separated list of changed bricks (use this in scripts) +uv run poly diff --bricks --short +``` + +> **Agent rule of thumb:** when the goal is to *do something* with the result (run pytest, drive a deploy script, render a list), reach for `--bricks --short` first. The default output is for human readers. + +**Command prefix:** If you do not know the package manager, list lock files with `ls uv.lock poetry.lock pdm.lock 2>/dev/null` (a `pyproject.toml` is always present, so it tells you nothing on its own). Use `uv run poly` (uv), `poetry poly` (poetry), `pdm run poly` (pdm), `hatch run poly` (hatch), or `poly` (activated venv). Examples below use `uv run`. + +> **`poly diff` vs `poly test diff`:** +> - `poly diff` → brick **implementation** changes since a tag (drives releases/deploys). +> - `poly test diff` → **test-code** changes since a tag (drives selective test runs). Load `polylith-testing`. + +## Tag selection +- Default: latest git tag matching `[tool.polylith.tag.patterns].stable` from `workspace.toml` (e.g. `stable-*`). +- `--since ` — pin a specific tag, branch, or commit-ish. The CLI tries to resolve `` as a configured pattern key first, then falls through to using it literally with `git diff `. + +## Command reference + +| Option | Default | Description | +|--------------|---------------------|------------------------------------------------------------------------------------------------------------| +| `--since` | latest matching tag | Reference tag (or branch/commit) to diff against. | +| `--short` | `false` | Compact output. Combined with `--bricks`, emits a comma-separated list of brick names — pipe-friendly. | +| `--bricks` | `false` | Print the list of bricks that changed (human-readable on its own; CSV when paired with `--short`). | +| `--deps` | `false` | With `--bricks`, also print bricks that **depend on** the changed bricks (transitive impact). | + +## Examples + +```bash +# Default: against latest stable-* tag +uv run poly diff + +# Selective deploy: every brick changed (incl. transitive consumers) since a release tag +uv run poly diff --since stable-4 --bricks --deps + +# Pipe-friendly: comma-separated names of bricks changed vs. main +uv run poly diff --since main --bricks --short +``` + +## Running tests for changed bricks + +The established Polylith pattern is to feed `--bricks --short` straight into `pytest -k`: brick names become an `or`-expression that pytest matches against test IDs, so the agent doesn't need to resolve namespace / theme / base-vs-component. + +```bash +changes="$(uv run poly diff --bricks --short)" +[ -n "$changes" ] && uv run pytest -k "${changes//,/ or }" +``` + +Example: `--bricks --short` outputs `log,message` → pytest runs as `pytest -k "log or message"`, collecting every test whose ID contains `log` or `message` (matches `test/components//log/...` and `test/bases//log/...` alike). + +> ⚠ `pytest -k` does **substring** matching, so a brick named `log` will also match tests whose name contains `log` (e.g. an unrelated `logger` brick or a `test_login` function). For short/generic brick names, fall back to passing explicit test directories. + +## Notes for the agent +- Operates on git's view of the working tree — uncommitted changes since the tag count as changed. +- If no matching tag exists and `--since` isn't passed, the command prints `No matching tags or commits found in repository.` and exits 0. Guard scripts so they don't run `pytest -k ""` (which would collect nothing or, worse, every test depending on the version). +- Map changed bricks → projects with `poly info` (load `polylith-workspace-inspection`) to drive selective deploys. diff --git a/.agents/skills/polylith/libs/SKILL.md b/.agents/skills/polylith/libs/SKILL.md new file mode 100644 index 00000000..a69c3293 --- /dev/null +++ b/.agents/skills/polylith/libs/SKILL.md @@ -0,0 +1,51 @@ +--- +name: polylith-libs +description: Inspect third-party libraries used per Polylith project with `poly libs`. Use when the user wants to see dependency usage, audit version drift across projects, find which projects use a given library, or compare library declarations vs. the lock file. Read-only — for a CI gate use `polylith-check` instead. +--- + +# Libs Skill + +## Quick command + +```bash +uv run poly libs +``` + +**Command prefix:** If you do not know the package manager, list lock files with `ls uv.lock poetry.lock pdm.lock 2>/dev/null` (a `pyproject.toml` is always present, so it tells you nothing on its own). Use `uv run poly` (uv), `poetry poly` (poetry), `pdm run poly` (pdm), `hatch run poly` (hatch), or `poly` (activated venv). Examples below use `uv run`. + +> `poly libs` **reports**; `poly check` **fails the build**. Use `libs` for inspection, `check` for CI (load `polylith-check`). + +## Prerequisites +- A Polylith workspace with at least one project. +- A lock file at the root (`uv.lock`, `poetry.lock`, or `pdm.lock`). + +## Command reference + +| Option | Default | Description | +|----------------|---------|--------------------------------------------------------------------------------------------------------| +| `--strict` | `false` | Stricter matching of names and versions across projects. | +| `--directory` | cwd | Limit output to projects whose path matches this directory. | +| `--alias` | — | Comma-separated `import_name=package_name` aliases. | +| `--short` | `false` | Compact view — useful for wide workspaces. | +| `--save` | `false` | Persist the report to a file under the workspace's output dir. | + +## Examples + +```bash +# Full library × project matrix +uv run poly libs + +# Strict version-drift detection +uv run poly libs --strict + +# Compact view for many projects +uv run poly libs --short +``` + +## How to read it +- Rows are third-party libraries; columns are projects. +- `✔` = the library is used by that project. +- A library used by multiple projects with **different versions** = version drift. Fix by aligning versions in the relevant project `pyproject.toml`s, or by relying on a central lock file (uv workspaces). + +## Notes for the agent +- `poly libs` is **read-only** — it never modifies `pyproject.toml` or the lock file. diff --git a/.agents/skills/polylith/project_management/SKILL.md b/.agents/skills/polylith/project_management/SKILL.md new file mode 100644 index 00000000..8a8787af --- /dev/null +++ b/.agents/skills/polylith/project_management/SKILL.md @@ -0,0 +1,101 @@ +--- +name: polylith-project-management +description: Create a deployable Polylith project with `poly create project` — a lightweight `pyproject.toml` under `projects//` that references bricks for deployment as a Docker image, wheel, AWS Lambda, GCP Cloud Function, or other artifact. Use when the user wants a new deployable, service, microservice, or release target. +--- + +# Project Management Skill + +> 💡 **Terminology:** this skill uses Polylith terms like *brick*, *base*, *namespace*, and *development project*. If they're unfamiliar, load `polylith-concepts` first. + +## Quick command + +```bash +uv run poly create project --name user_api --quiet +``` + +**Command prefix:** If you do not know the package manager, list lock files with `ls uv.lock poetry.lock pdm.lock 2>/dev/null` (a `pyproject.toml` is always present, so it tells you nothing on its own). Use `uv run poly` (uv), `poetry poly` (poetry), `pdm run poly` (pdm), `hatch run poly` (hatch), or `poly` (activated venv). Examples below use `uv run`. + +> ⚠ **Do NOT invent flags** for selecting components/bases/deployment targets — they don't exist. The CLI accepts only `--name`, `--description`, and `--quiet`. Bricks are attached manually and via later `poly sync` runs. +> ⚠ **There is no `poly build project` command.** Building the artifact (Docker, wheel, Lambda zip) is the **package manager's** job (`uv build`, `poetry build`, `hatch build`, `pdm build`). + +## What `poly create project` actually does +1. Detects the build backend in the **root** `pyproject.toml` (Hatchling, PDM, or Poetry) and picks the matching `pyproject.toml` template. +2. Writes `projects//pyproject.toml`, inheriting authors and `requires-python` from the root. +3. If `--quiet` is not used, it runs an interactive prompt to add bricks. Agents must always use `--quiet` and manage bricks manually. + +## Prerequisites +- A Polylith workspace already exists (load `polylith-workspace-setup` if not). +- The root `pyproject.toml` exists and uses Hatchling, uv, Poetry, pixi, Maturin or PDM. Without it, the command exits non-zero with `Failed to guess the used Package & Dependency Management`. + +## Command reference + +| Option | Required | Default | Description | +|-----------------|----------|---------|----------------------------------------------| +| `--name` | yes | — | Name of the project. | +| `--description` | no | `""` | Optional human-readable description. | +| `--quiet` | no | `false` | Suppress the interactive prompt. | + +## Examples + +```bash +# Minimal — bypass interactive prompt +uv run poly create project --name user_api --quiet + +# With description +uv run poly create project --name consumer --description "Kafka order consumer" --quiet +``` + +## What gets written + +``` +projects/user_api/pyproject.toml +``` + +For the **Hatchling** backend (most common with Polylith): + +```toml +[build-system] +requires = ["hatchling", "hatch-polylith-bricks"] +build-backend = "hatchling.build" + +[project] +name = "user_api" +version = "0.1.0" +description = "User-facing HTTP API" +authors = [{ name = "Jane Doe", email = "jane@example.com" }] +requires-python = ">=3.12" +dependencies = [] + +[tool.hatch.build.targets.wheel] +packages = ["mycompany"] + +[tool.hatch.build.hooks.polylith-bricks] + +[tool.polylith.bricks] +# Populated by `poly sync` (e.g. "../../bases/mycompany/api" = "mycompany/api") +``` + +`name`, `description`, `authors`, `requires-python`, and `packages` come from the root `pyproject.toml` and the `--name` / `--description` flags. `[tool.polylith.bricks]` is populated manually or by `poly sync`. + +### Backend differences + +| Build backend | Build hook in project | Notes | +|---------------|------------------------------|-------------------------------------------| +| Hatchling | `hatch-polylith-bricks` | Most common. | +| PDM | `pdm-polylith-bricks` | | +| Poetry | (no build hook) | Uses `poetry-polylith-plugin` at runtime. | + +## After creation +- Whenever imports change, run `poly sync` (load `polylith-sync`). +- Before a release / in CI, run `poly check` (load `polylith-check`). + +## Notes for the agent +- **Always use `--quiet`.** AI agents cannot interact with `stdin` prompts and the process will hang indefinitely if `--quiet` is omitted. +- After creating the project with `--quiet`, you *can* link a base manually, but **it is not strictly required right away**. Empty projects are perfectly valid. If the user wants to add a base later, or if the base doesn't exist yet, simply leave the `[tool.polylith.bricks]` section empty for now. +- **Manual Base Linking Syntax:** When it's time to link a base manually, edit the `[tool.polylith.bricks]` section in `projects//pyproject.toml`. Check `workspace.toml` first to determine the `theme` and `namespace`. + - For the **`loose`** theme (recommended): `"../../bases//" = "/"` (e.g., `"../../bases/mycompany/api" = "mycompany/api"`). + - For the **`tdd`** theme: `"../../bases//src//" = "/"` (e.g., `"../../bases/api/src/mycompany/api" = "mycompany/api"`). +- Components are never selected directly; they are pulled in transitively by the imports of the chosen base when you run `poly sync`. + +## Verification +After creation, verify the project exists by checking `projects//pyproject.toml`. If the base already exists and the user wants it linked now, edit the `[tool.polylith.bricks]` section in that file to include the base, and then run `poly sync` to populate its transitive dependencies. Otherwise, the empty project is ready for development to proceed. diff --git a/.agents/skills/polylith/sync/SKILL.md b/.agents/skills/polylith/sync/SKILL.md new file mode 100644 index 00000000..a8db33c9 --- /dev/null +++ b/.agents/skills/polylith/sync/SKILL.md @@ -0,0 +1,79 @@ +--- +name: polylith-sync +description: Run `poly sync` to update each project's `[tool.polylith.bricks]` table with the bricks actually imported. Use this whenever a brick is added, removed, or its imports change — and before `poly check` or a release. +--- + +# Sync Skill + +> 💡 **Terminology:** this skill uses Polylith terms like *brick*, *project*, and *development project*. If they're unfamiliar, load `polylith-concepts` first. + +## Quick command + +```bash +uv run poly sync --quiet +``` + +> ⚠ **Agents must pass `--quiet`.** `poly sync` has an interactive mode that will prompt on stdin and **hang the process** if no human is attached. `--quiet` suppresses output *and* disables the interactive prompts. **Never use `--verbose`** in an agent run — it is the opposite of `--quiet` and can trigger interactive mode. Save `--verbose` for humans who are debugging at a terminal. + +**Command prefix:** If you do not know the package manager, list lock files with `ls uv.lock poetry.lock pdm.lock 2>/dev/null` (a `pyproject.toml` is always present, so it tells you nothing on its own). Use `uv run poly` (uv), `poetry poly` (poetry), `pdm run poly` (pdm), `hatch run poly` (hatch), or `poly` (activated venv). Examples below use `uv run`. + +## When to run +- After `poly create base` / `poly create component` — registers the new brick in the development project. +- After `poly create project` — only if the interactive prompt was skipped. +- After adding a new `import` between bricks — picks up the transitively pulled-in brick. +- Before `poly check` and before any release/CI run. + +> ⚠ `poly sync` **adds** missing bricks but does **not** remove unused ones. Stale entries in `[tool.polylith.bricks]` must be deleted by hand. It also does not sync third-party libraries — use `poly libs` / `poly check` for those. + +## What it does +- **Per project under `projects/`:** resolves the project's base(s), walks the import graph, and adds any imported brick missing from `[tool.polylith.bricks]`. +- **For the development project (root `pyproject.toml`):** always lists every base and every component in the workspace. + +## Command reference + +| Option | Default | Description | +|----------------|---------|----------------------------------------------------------------------------------------------------------------------------| +| `--directory` | cwd | Sync only projects whose path matches this directory. | +| `--quiet` | `false` | Suppress all output **and** disable interactive prompts. Exit code unchanged. **Required for agent runs.** | +| `--verbose` | `false` | Print detailed information about each sync operation. **Can trigger interactive mode** — for human/terminal use only. | + +## Examples + +```bash +# Agent / CI default — non-interactive, no output +uv run poly sync --quiet + +# Agent: only one project, still non-interactive +uv run poly sync --quiet --directory projects/user_api + +# Human, at a terminal: verbose for debugging missing bricks (may prompt!) +uv run poly sync --verbose +``` + +### Output + +Nothing changed: +``` +✔ project-a +✔ project-b +✔ development +``` + +A brick was added: +``` +👉 the-cli +adding greeting component to the-cli +``` + +## Notes for the agent +- **Always run with `--quiet`.** Without it, `poly sync` may drop into an interactive prompt and hang the process — agents cannot answer stdin prompts. Never combine with `--verbose`, which leans the other way and can trigger interactive mode. +- The exit code is always 0 — `poly sync` is informational, not a gate. For a CI gate, follow it with `poly check` (load `polylith-check`). +- If a brick is showing up in unexpected projects after sync, it's because *something the project's base imports* (transitively) imports that brick. Trace it with `poly deps --brick ` (load `polylith-dependency-visualization`). +- **Git reminder:** If `poly sync` adds missing bricks to any `pyproject.toml` files, use your git tools to review the diff and ensure those changes are committed. Because `--quiet` suppresses output, the agent should rely on `git diff` (or re-run `poly info`) to confirm what changed. + +## Background — the development project + +The root `pyproject.toml` doubles as a "development project": a single virtual environment that includes every brick and every dependency (production *and* dev-only). The `development/` directory holds REPL scripts and notebooks that import bricks freely. `poly sync` keeps the development project complete by listing every brick in the workspace there. Per-project `pyproject.toml`s under `projects/` only list the bricks each project actually uses. + +## Verification +After running `poly sync`, verify the changes by inspecting the `[tool.polylith.bricks]` section in the relevant `projects//pyproject.toml` or the root `pyproject.toml` to ensure the new bricks were added. Alternatively, run `poly info` (load `polylith-workspace-inspection`) to see the updated matrix. diff --git a/.agents/skills/polylith/testing/SKILL.md b/.agents/skills/polylith/testing/SKILL.md new file mode 100644 index 00000000..38e1c6cb --- /dev/null +++ b/.agents/skills/polylith/testing/SKILL.md @@ -0,0 +1,129 @@ +--- +name: polylith-testing +description: List Polylith bricks and projects affected by **test-code** changes since a git tag using `poly test diff`. Use for selective test runs in CI ("which tests do I need to run?"). For implementation-code diffs, use `polylith-diff` instead. +--- + +# Testing Skill + +## Quick command + +```bash +# Human-readable (default) +uv run poly test diff + +# Pipe-friendly: comma-separated list of affected bricks (use this in scripts) +uv run poly test diff --short +``` + +> **Agent rule of thumb:** when the goal is to *do something* with the result (run pytest, drive CI), reach for `--short` first. The default output is for human readers. + +**Command prefix:** If you do not know the package manager, list lock files with `ls uv.lock poetry.lock pdm.lock 2>/dev/null` (a `pyproject.toml` is always present, so it tells you nothing on its own). Use `uv run poly` (uv), `poetry poly` (poetry), `pdm run poly` (pdm), `hatch run poly` (hatch), or `poly` (activated venv). Examples below use `uv run`. + +> ⚠ `poly test diff` **reports only** — it does not execute tests. Pipe its output into `pytest` / `unittest`. +> **`poly test diff` vs `poly diff`:** +> - `poly test diff` → which **test files** changed (drives test runs). +> - `poly diff` → which **brick implementations** changed (drives releases). Load `polylith-diff`. + +## Tag selection +- Default: latest git tag matching `[tool.polylith.tag.patterns].stable` from `workspace.toml` (e.g. `stable-*`). +- `--since ` — pin a tag/branch/commit. The output line `Test diff based on stable-4` shows the tag the CLI selected. + +## Command reference + +| Option | Default | Description | +|--------------|---------------------|----------------------------------------------------------------------------------------------| +| `--since` | latest matching tag | Reference tag (or branch/commit) to diff against. | +| `--short` | `false` | Pipe-friendly output: a comma-separated list of affected brick names — nothing else. | +| `--bricks` | `false` | Print the affected bricks as a human-readable report (`⚙ Changes affecting ` lines). | +| `--projects` | `false` | Print the affected projects as a human-readable report. | + +> 💡 **For piping into `pytest` use `--short`.** It emits just the brick names separated by commas, with no headers, prefixes, or decoration — exactly what a script needs. `--bricks` is meant for humans reading the output. + +## Examples + +```bash +# Default: against latest stable-* tag +uv run poly test diff + +# Pipe-friendly bricks list (best for scripts / agents) +uv run poly test diff --short + +# Pin a tag, then pipe affected bricks into pytest +uv run poly test diff --since stable-4 --short + +# Human-readable list of affected bricks +uv run poly test diff --bricks +``` + +### Sample output (default, no flags) + +``` +Projects and bricks affected by changes in tests +Test diff based on stable-4 + +Affected projects: 5 +Affected components: 1 +Affected bases: 0 + + brick consumer_project message-api aws lambda my_fastapi_project gcp function + ──────────────────────────────────────────────────────────────────────────────────────── + log ✔ ✔ ✔ ✔ ✔ +``` + +`✔` = the column project is affected by the row brick's test changes. + +### Sample output (`--short`) + +``` +log,message +``` + +Just the brick names, comma-separated. No header, no prefix, no namespace. Empty result = no affected bricks. + +### Sample output (`--bricks`) + +`--bricks` is a human-readable variant; one line per affected brick: + +``` +⚙ Changes affecting log +⚙ Changes affecting message +``` + +Use `--short` instead when piping into another tool. + +## Executing tests for affected bricks + +> 💡 **Most common case — "I changed code, run the tests for it":** that's driven by `poly diff` (implementation diff), not `poly test diff`. Load `polylith-diff` for the canonical recipe; the same `pytest -k` pattern shown below works there. + +`poly test diff` only reports — you drive the test runner yourself. The established Polylith pattern is to feed `--short` straight into `pytest -k`: brick names become an `or`-expression that pytest matches against test IDs, so you don't need to know the namespace, the theme, or whether each brick is a base or a component. + +### Recommended flow + +1. Capture `poly test diff --short`. +2. Replace the commas with ` or ` to form a pytest `-k` expression. +3. Pass it to `pytest -k`. Skip the call when the result is empty (no affected bricks). + +### Shell one-liner (uv) + +```bash +changes="$(uv run poly test diff --short)" +[ -n "$changes" ] && uv run pytest -k "${changes//,/ or }" +``` + +Example: `--short` outputs `log,message` → pytest is invoked as `pytest -k "log or message"`, which collects every test whose ID contains `log` or `message` (the brick directory name appears in the test path, so this matches both `test/components//log/...` and `test/bases//log/...` automatically). + +### Caveat — substring matching + +`pytest -k` matches **substrings** of test IDs, so a brick named `log` will also pull in tests whose name happens to contain `log` (e.g. tests for an unrelated brick called `logger` or a function `test_login`). If a brick name is short or generic and produces unwanted matches, fall back to passing explicit test directories instead. + +## Running targeted tests for a single brick + +If you are iteratively debugging or just created a single brick, you do not need to use `poly test diff`. You can run the test runner directly against the brick's test folder. + +Check `workspace.toml` to determine the `theme` and `namespace`: +- For the **`loose`** theme (recommended): `pytest test/components//` or `pytest test/bases//`. +- For the **`tdd`** theme: `pytest components//test` or `pytest bases//test`. + +## Notes for the agent +- Always exits 0 — informational, never a CI gate. +- If no matching tag exists and `--since` isn't passed, prints `No matching tags or commits found in repository.` and exits 0. Handle this in scripts. diff --git a/.agents/skills/polylith/workspace_inspection/SKILL.md b/.agents/skills/polylith/workspace_inspection/SKILL.md new file mode 100644 index 00000000..ef7141ab --- /dev/null +++ b/.agents/skills/polylith/workspace_inspection/SKILL.md @@ -0,0 +1,64 @@ +--- +name: polylith-workspace-inspection +description: Show **brick × project usage** with `poly info` — which projects use which bricks, plus workspace counts. Use for "workspace overview", "which projects use X", "find orphaned bricks". For brick-to-brick dependencies, use `polylith-dependency-visualization`. +--- + +# Workspace Inspection Skill + +## Quick command + +```bash +uv run poly info +``` + +**Command prefix:** If you do not know the package manager, list lock files with `ls uv.lock poetry.lock pdm.lock 2>/dev/null` (a `pyproject.toml` is always present, so it tells you nothing on its own). Use `uv run poly` (uv), `poetry poly` (poetry), `pdm run poly` (pdm), `hatch run poly` (hatch), or `poly` (activated venv). Examples below use `uv run`. + +> **`poly info` vs `poly deps`:** +> - `poly info` → **brick × project** (which project uses which brick). +> - `poly deps` → **brick × brick** (which brick uses which brick). Load `polylith-dependency-visualization`. +> 💡 A brick that is `-` in every project except `development` is **orphaned in production** — flag it for the user. + +## Command reference + +| Option | Default | Description | +|---------------|---------|-----------------------------------------------------------------------------------------------------------------| +| `--short` | `false` | Compact view — for workspaces where the full matrix doesn't fit. | +| `--save` | `false` | Persist the report to a file under the workspace's output dir. | +| `--group` | — | Show only projects in the named group(s) (comma-separated), defined in `[tool.polylith.projects.groups]`. | + +## Examples + +```bash +# Full matrix +uv run poly info + +# Compact summary +uv run poly info --short + +# Filter to a project group +uv run poly info --group hooks +``` + +### Sample output + +``` +Workspace summary +projects: 6 components: 7 bases: 5 development: 1 + + brick consumer message-api aws lambda fastapi gcp fn development + ────────────────────────────────────────────────────────────────────────────────────── + greeting - - ✔ ✔ ✔ ✔ + kafka ✔ ✔ - - - ✔ + log ✔ ✔ ✔ ✔ ✔ ✔ + greet_api - - - ✔ - ✔ + message_api - ✔ - - - ✔ +``` + +- Rows are bricks; columns are projects (rightmost = development). +- `✔` = the brick is used by that project; `-` = not used. +- The `development` column should be `✔` for every brick (enforced by `poly sync`); a `-` there means a brick was created but isn't yet known to the development project. + +## Notes for the agent +- `poly info` exits 0 — it's a report, not a gate. +- For wide workspaces, prefer `--short` or `--group `. +- To turn this report into action: cross-reference orphans (only `development = ✔`) with `poly deps --brick ` to confirm nothing imports them, then propose deletion to the user. diff --git a/.agents/skills/polylith/workspace_setup/SKILL.md b/.agents/skills/polylith/workspace_setup/SKILL.md new file mode 100644 index 00000000..5d163026 --- /dev/null +++ b/.agents/skills/polylith/workspace_setup/SKILL.md @@ -0,0 +1,104 @@ +--- +name: polylith-workspace-setup +description: Scaffold a new Polylith workspace with `poly create workspace`. Use when the user wants to initialize / set up / start / bootstrap Polylith from scratch in a directory (creates `workspace.toml` and the `bases/`, `components/`, `projects/`, `development/` directories). +--- + +# Workspace Setup Skill + +> 💡 **Terminology:** this skill uses Polylith terms like *namespace*, *brick*, *theme*, and *development project*. If they're unfamiliar, load `polylith-concepts` first. + +## Quick command + +```bash +uv run poly create workspace --name mycompany --theme loose +``` + +**Command prefix:** If you do not know the package manager, list lock files with `ls uv.lock poetry.lock pdm.lock 2>/dev/null` (a `pyproject.toml` is always present, so it tells you nothing on its own). Use `uv run poly` (uv), `poetry poly` (poetry), `pdm run poly` (pdm), `hatch run poly` (hatch), or `poly` (activated venv). Examples below use `uv run`. + +> ⚠ **Always pass `--theme loose`.** The CLI default is `tdd`; loose is the recommended layout used by `python-polylith` itself and almost every public example. +> ⚠ **`--name` sets the namespace**, not just a workspace label — it becomes the top-level Python package for every brick. +> ⚠ **`pyproject.toml` is NOT created.** Polylith layers on top of an existing Python project. The user must create the root `pyproject.toml` separately (`uv init`, `poetry init`, etc.). + +## Command reference + +| Option | Required | Default | Description | +|------------|----------|---------|------------------------------------------------------------| +| `--name` | yes | — | The **namespace** for all bricks (e.g. `mycompany`). | +| `--theme` | no | `tdd` | Brick directory layout: `loose` (recommended) or `tdd`. | + +## What gets created + +``` +/ +├── workspace.toml # Polylith config (generated, see below) +├── README.md # Workspace README (generated) +├── bases/ # Empty; populate with `poly create base` +├── components/ # Empty; populate with `poly create component` +├── projects/ # Empty; populate with `poly create project` +└── development/ # Scratch space for REPL/notebooks + └── __init__.py +``` + +The CLI does **not** create: `pyproject.toml`, lock files, or any brick subdirectories. + +### Generated `workspace.toml` + +```toml +[tool.polylith] +namespace = "mycompany" +git_tag_pattern = "stable-*" + +[tool.polylith.structure] +theme = "loose" + +[tool.polylith.tag.patterns] +stable = "stable-*" +release = "v[0-9]*" + +[tool.polylith.resources] +brick_docs_enabled = false + +[tool.polylith.test] +enabled = true +``` + +### Optional advanced config (added by hand) + +```toml +# Short aliases for verbose project names — used in `poly info` / `poly deps` tables. +[tool.polylith.projects.alias] +my-very-long-project-name = "api" + +# Group projects for filtered views: `poly info --group hooks`. +[tool.polylith.projects.groups] +hooks = ["project-a", "project-c"] + +# Library aliases when import name ≠ package name (NOTE: `libs.alias`, not `projects.alias`). +[tool.polylith.libs.alias] +cv2 = "opencv-python" +``` + +> Polylith has **two `alias` tables**: `projects.alias` (display names for projects) and `libs.alias` (third-party library import-name → package-name). + +## Themes + +`[tool.polylith.structure].theme` controls only the on-disk layout of bricks. + +### `loose` (recommended) +Flat directories: `///{__init__.py,core.py}`. Tests live at `test////test_.py`. + +``` +components/mycompany/greeting/{__init__.py,core.py} +test/components/mycompany/greeting/test_core.py +``` + +### `tdd` +Each brick is its own distributable with sibling `src/` and `test/`: `//src///...` and `//test///...`. Useful when bricks ship as standalone packages. + +## After setup +1. Create the root `pyproject.toml` if it doesn't exist (with the user's chosen package manager). +2. Add `polylith-cli` and the matching build hook (`hatch-polylith-bricks`, `pdm-polylith-bricks`) as dev dependencies. +3. Load `polylith-base-creation` / `polylith-component-creation` to start adding bricks. + +## Verification +After setup, check that `workspace.toml` and the top-level directories (`bases/`, `components/`, `projects/`, `development/`) were created. Since `poly create workspace` does not create a `pyproject.toml`, verify if the root `pyproject.toml` exists and create/initialize it if missing. diff --git a/projects/polylith_cli/pyproject.toml b/projects/polylith_cli/pyproject.toml index 4bd4c972..5a1d0f99 100644 --- a/projects/polylith_cli/pyproject.toml +++ b/projects/polylith_cli/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "polylith-cli" -version = "1.46.0" +version = "1.47.0" description = "Python tooling support for the Polylith Architecture" authors = ['David Vujic'] homepage = "https://davidvujic.github.io/python-polylith-docs/" @@ -39,6 +39,7 @@ packages = [ { include = "polylith/toml", from = "../../components" }, { include = "polylith/workspace", from = "../../components" }, { include = "polylith/yaml", from = "../../components" }, + { include = ".agents", from = "../../"} ] [tool.poetry.dependencies]