agentme 0.9.0 → 0.11.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.
- package/.filedist-package.yml +2 -1
- package/.xdrs/agentme/edrs/application/003-javascript-project-tooling.md +41 -5
- package/.xdrs/agentme/edrs/application/010-golang-project-tooling.md +39 -15
- package/.xdrs/agentme/edrs/application/014-python-project-tooling.md +63 -5
- package/.xdrs/agentme/edrs/application/015-cli-tool-standards.md +25 -24
- package/.xdrs/agentme/edrs/application/018-ai-agent-development-standards.md +57 -64
- package/.xdrs/agentme/edrs/application/019-ml-dataset-structure.md +12 -12
- package/.xdrs/agentme/edrs/application/020-ai-agent-xdrs-knowledge-layer.md +99 -0
- package/.xdrs/agentme/edrs/application/021-pragmatic-hexagonal-architecture.md +112 -0
- package/.xdrs/agentme/edrs/application/skills/001-create-javascript-project/SKILL.md +26 -11
- package/.xdrs/agentme/edrs/application/skills/003-create-golang-project/SKILL.md +31 -14
- package/.xdrs/agentme/edrs/application/skills/005-create-python-project/SKILL.md +56 -23
- package/.xdrs/agentme/edrs/devops/005-monorepo-structure.md +1 -1
- package/.xdrs/agentme/edrs/devops/006-github-pipelines.md +1 -1
- package/.xdrs/agentme/edrs/devops/008-common-targets.md +2 -1
- package/.xdrs/agentme/edrs/devops/017-tool-execution-and-scripting.md +1 -1
- package/.xdrs/agentme/edrs/governance/013-contributing-guide-requirements.md +1 -1
- package/.xdrs/agentme/edrs/index.md +3 -1
- package/.xdrs/agentme/edrs/observability/011-service-health-check-endpoint.md +1 -1
- package/.xdrs/agentme/edrs/principles/002-coding-best-practices.md +1 -1
- package/.xdrs/agentme/edrs/principles/004-unit-test-requirements.md +23 -3
- package/.xdrs/agentme/edrs/principles/007-project-quality-standards.md +31 -3
- package/.xdrs/agentme/edrs/principles/009-error-handling.md +1 -1
- package/.xdrs/agentme/edrs/principles/012-continuous-xdr-enrichment.md +2 -2
- package/.xdrs/agentme/edrs/principles/016-cross-language-module-structure.md +1 -1
- package/.xdrs/agentme/edrs/principles/articles/001-continuous-xdr-improvement.md +5 -5
- package/package.json +2 -2
|
@@ -17,13 +17,13 @@ How should ML datasets be organized on disk so they are self-describing, easy to
|
|
|
17
17
|
|
|
18
18
|
**A standard root layout with mandatory README.md and dataset.schema.json, plus type-specific conventions for data files**
|
|
19
19
|
|
|
20
|
-
Every dataset
|
|
20
|
+
Every dataset MUST live in its own named folder and include a README and a JSON Schema file. Data files are organized according to three dataset types, each with its own placement rule.
|
|
21
21
|
|
|
22
22
|
### Details
|
|
23
23
|
|
|
24
24
|
#### 01-root-structure-is-mandatory
|
|
25
25
|
|
|
26
|
-
Every dataset
|
|
26
|
+
Every dataset MUST follow this root layout:
|
|
27
27
|
|
|
28
28
|
```
|
|
29
29
|
/[name-of-dataset]/
|
|
@@ -33,13 +33,13 @@ Every dataset must follow this root layout:
|
|
|
33
33
|
... (additional files depending on dataset type)
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
- `README.md`
|
|
37
|
-
- `dataset.schema.json`
|
|
38
|
-
- The dataset folder name
|
|
36
|
+
- `README.md` MUST explain what the dataset is about, the procedures used to create it, remarks on data quality, and instructions on how to consume it with examples.
|
|
37
|
+
- `dataset.schema.json` MUST be a valid [JSON Schema](https://json-schema.org/) document describing the structure of the dataset's primary data.
|
|
38
|
+
- The dataset folder name MUST be lowercase, using underscores as separators (e.g. `my_dataset`).
|
|
39
39
|
|
|
40
40
|
#### 02-file-annotation-pairs-must-use-data-folder
|
|
41
41
|
|
|
42
|
-
Datasets where each item is a file paired with structured JSON output (e.g. image labeling, document data extraction, medical records with known features)
|
|
42
|
+
Datasets where each item is a file paired with structured JSON output (e.g. image labeling, document data extraction, medical records with known features) MUST store all files inside the `data/` subfolder. Each data file MUST have a sibling JSON annotation file named with the same filename suffixed with `.json`.
|
|
43
43
|
|
|
44
44
|
```
|
|
45
45
|
/[name-of-dataset]/
|
|
@@ -56,11 +56,11 @@ Datasets where each item is a file paired with structured JSON output (e.g. imag
|
|
|
56
56
|
|
|
57
57
|
Placing the annotation file next to its source file (same name + `.json`) keeps them adjacent even in large directories, making it easy to iterate pairs programmatically.
|
|
58
58
|
|
|
59
|
-
Subdirectories inside `data/` are allowed when the number of files warrants grouping, but the `.json` sibling convention
|
|
59
|
+
Subdirectories inside `data/` are allowed when the number of files warrants grouping, but the `.json` sibling convention MUST be preserved at each level.
|
|
60
60
|
|
|
61
61
|
#### 03-tabular-datasets-must-use-csv-files-at-root
|
|
62
62
|
|
|
63
|
-
Datasets composed of column-oriented tabular data
|
|
63
|
+
Datasets composed of column-oriented tabular data MUST place CSV files at the root of the dataset folder. All tabular files MUST conform to the schema defined in `dataset.schema.json`, which MUST describe columns as named attributes with their types.
|
|
64
64
|
|
|
65
65
|
```
|
|
66
66
|
/[name-of-dataset]/
|
|
@@ -70,11 +70,11 @@ Datasets composed of column-oriented tabular data must place CSV files at the ro
|
|
|
70
70
|
README.md
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
Multiple CSV files are allowed when they represent different slices or splits of the same schema (e.g. train/test splits, subsets by source). All files in the same dataset
|
|
73
|
+
Multiple CSV files are allowed when they represent different slices or splits of the same schema (e.g. train/test splits, subsets by source). All files in the same dataset MUST share the same column schema.
|
|
74
74
|
|
|
75
75
|
#### 04-complex-structured-datasets-must-use-jsonl
|
|
76
76
|
|
|
77
|
-
Datasets with complex or heterogeneous per-record structures (e.g. LLM workflow evaluation sets, Q&A pairs, input → expected_output pairs)
|
|
77
|
+
Datasets with complex or heterogeneous per-record structures (e.g. LLM workflow evaluation sets, Q&A pairs, input → expected_output pairs) MUST use JSONL files (one JSON object per line) placed at the root of the dataset folder. Each line MUST conform to the schema defined in `dataset.schema.json`.
|
|
78
78
|
|
|
79
79
|
```
|
|
80
80
|
/[name-of-dataset]/
|
|
@@ -84,11 +84,11 @@ Datasets with complex or heterogeneous per-record structures (e.g. LLM workflow
|
|
|
84
84
|
README.md
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
-
Multiple JSONL files are allowed when they represent different splits or categories (e.g. easy vs. edge cases). All files in the same dataset
|
|
87
|
+
Multiple JSONL files are allowed when they represent different splits or categories (e.g. easy vs. edge cases). All files in the same dataset MUST conform to the same line schema.
|
|
88
88
|
|
|
89
89
|
#### 05-referenced-files-must-live-in-data-folder
|
|
90
90
|
|
|
91
|
-
When any dataset type (tabular, JSONL, or annotation-pair) contains references to external files as part of the data (e.g. a JSONL record that includes a file path), those referenced files
|
|
91
|
+
When any dataset type (tabular, JSONL, or annotation-pair) contains references to external files as part of the data (e.g. a JSONL record that includes a file path), those referenced files MUST be stored inside the `data/` subfolder of the dataset. Paths inside data records MUST be relative to the dataset root.
|
|
92
92
|
|
|
93
93
|
## References
|
|
94
94
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentme-edr-policy-020-ai-agent-xdrs-knowledge-layer
|
|
3
|
+
description: Defines how to integrate XDRS as the runtime knowledge source of truth for AI agents — covering document placement, AGENTS.md setup, file tools, and local sandbox configuration. Apply only when the project explicitly uses XDRS to govern agent behavior.
|
|
4
|
+
apply-to: AI agent projects that use XDRS as the source of truth for policies and skills
|
|
5
|
+
valid-from: 2026-05-27
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# agentme-edr-policy-020: AI agent XDRS knowledge layer
|
|
9
|
+
|
|
10
|
+
## Context and Problem Statement
|
|
11
|
+
|
|
12
|
+
AI agents need access to project-specific policies and skills at runtime to produce consistent, governed outputs. XDRS provides a file-system-based structure for capturing these decisions, but there is no standard pattern for embedding XDRS documents in agent libraries, wiring the agent to consult them, or sandboxing file access securely.
|
|
13
|
+
|
|
14
|
+
How should an AI agent project integrate XDRS as its runtime source of truth for policies and skills?
|
|
15
|
+
|
|
16
|
+
## Decision Outcome
|
|
17
|
+
|
|
18
|
+
**Embed XDRS documents in `lib/data/.xdrs/`, instruct the agent to consult them via `AGENTS.md`, equip the agent with sandboxed file tools, and use the deepagents framework when a local sandbox is required.**
|
|
19
|
+
|
|
20
|
+
This policy MUST only be applied when the project explicitly chooses XDRS as its knowledge governance layer. It is not required by [agentme-edr-018](018-ai-agent-development-standards.md) in general.
|
|
21
|
+
|
|
22
|
+
### Details
|
|
23
|
+
|
|
24
|
+
#### 01-xdrs-knowledge-layer
|
|
25
|
+
|
|
26
|
+
XDRS documents are the source of truth for all policies and skills that the agent must follow during its tasks. The agent MUST consult XDRS before acting, not rely on general knowledge alone.
|
|
27
|
+
|
|
28
|
+
**Placing XDRS documents in the library**
|
|
29
|
+
|
|
30
|
+
- XDRS Policy and Skill documents MUST be placed at `lib/data/.xdrs/`, using the standard XDRS scope/type/subject folder structure (following `_core-adr-policy-001`).
|
|
31
|
+
- They MUST be embedded in the package data manifest (e.g. `pyproject.toml` `[tool.hatch.build] include` or equivalent) so they are available at runtime.
|
|
32
|
+
- When exposed through a deepagents sandbox, they MUST be mounted at `/.xdrs/` inside the sandbox (see rule `03-local-sandbox`).
|
|
33
|
+
|
|
34
|
+
**AGENTS.md — mandatory XDRS consultation**
|
|
35
|
+
|
|
36
|
+
Place an `AGENTS.md` file at the root of the deepagents sandbox (i.e. alongside `/.xdrs/`). This file instructs the agent to always consult XDRS before acting. Its content MUST follow the xdrs-core AGENTS.md template:
|
|
37
|
+
|
|
38
|
+
```markdown
|
|
39
|
+
# AGENTS.md
|
|
40
|
+
|
|
41
|
+
**Purpose:** This file is intentionally brief. All decisions and working instructions are captured as Policies or Skills in the XDRS structure.
|
|
42
|
+
|
|
43
|
+
## Policy Consultation in XDRS Is Mandatory For Every Request
|
|
44
|
+
|
|
45
|
+
Before answering **any** request you MUST:
|
|
46
|
+
|
|
47
|
+
1. Read the XDRS root index at `/.xdrs/index.md` to identify relevant Policies and Skills.
|
|
48
|
+
2. Read the relevant Policy and Skill files.
|
|
49
|
+
3. Base your actions on those Policies and Skills.
|
|
50
|
+
|
|
51
|
+
This rule has NO exceptions. Do not answer from general knowledge alone when a Policy may exist on the topic.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
The agent system prompt MUST reference `AGENTS.md` so the agent loads it at startup. Example:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
Read /AGENTS.md and follow all instructions in it before proceeding.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
#### 02-agent-file-tools
|
|
61
|
+
|
|
62
|
+
Every agent that uses the XDRS knowledge layer MUST use the file tools provided by the deepagents framework. Do not implement hand-rolled alternatives — see [agentme-edr-policy-018-ai-agent-development-standards.[09-local-sandbox]](018-ai-agent-development-standards.md) for the full sandbox and tool requirements.
|
|
63
|
+
|
|
64
|
+
These tools operate over two sandboxed roots (configured in rule `03-local-sandbox`):
|
|
65
|
+
|
|
66
|
+
| Root | Content | Source |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `data_root` | Static files shipped with the library (`lib/data/`) | Resolved via `importlib.resources` at workflow startup |
|
|
69
|
+
| `temp_root` | Dynamic files generated for the current workflow run | Temporary directory created by `tempfile.mkdtemp()` at workflow startup |
|
|
70
|
+
|
|
71
|
+
`temp_root` MUST be created at workflow startup and cleaned up in the same `try/finally` block. Pass it explicitly into the workflow; do not read it from a global variable.
|
|
72
|
+
|
|
73
|
+
#### 03-local-sandbox
|
|
74
|
+
|
|
75
|
+
Follow [agentme-edr-policy-018-ai-agent-development-standards.[09-local-sandbox]](018-ai-agent-development-standards.md) for the general deepagents sandbox setup. When XDRS is in use, add the following mounts to the sandbox configuration:
|
|
76
|
+
|
|
77
|
+
| Source | Content | Deepagents sandbox path |
|
|
78
|
+
|---|---|---|
|
|
79
|
+
| `lib/data/.xdrs/` | XDRS Policy and Skill documents | `/.xdrs/` (read-only) |
|
|
80
|
+
| Generated at startup | `AGENTS.md` instructing the agent to consult XDRS | `/AGENTS.md` (read-only) |
|
|
81
|
+
|
|
82
|
+
XDRS documents MUST always be mounted at `/.xdrs/`. `AGENTS.md` MUST always be placed at the sandbox root (`/AGENTS.md`).
|
|
83
|
+
|
|
84
|
+
Example XDRS mount additions:
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from importlib.resources import files
|
|
88
|
+
from pathlib import Path
|
|
89
|
+
|
|
90
|
+
data_root = str(files("myagent").joinpath("data"))
|
|
91
|
+
agents_md = Path(temp_root) / "AGENTS.md"
|
|
92
|
+
agents_md.write_text(_AGENTS_MD) # content from xdrs-core AGENTS.md template; see rule 01-xdrs-knowledge-layer
|
|
93
|
+
|
|
94
|
+
# Add these mounts alongside the base mounts from agentme-edr-018 rule 09-local-sandbox:
|
|
95
|
+
xdrs_mounts = [
|
|
96
|
+
{"src": f"{data_root}/.xdrs", "dst": "/.xdrs", "readonly": True},
|
|
97
|
+
{"src": str(agents_md), "dst": "/AGENTS.md", "readonly": True},
|
|
98
|
+
]
|
|
99
|
+
```
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentme-edr-policy-021-pragmatic-hexagonal-architecture
|
|
3
|
+
description: Defines a pragmatic variant of Hexagonal Architecture for organizing application source code into Adapters (inbound/outbound I/O boundaries) and Application (business logic) layers, with explicit naming conventions and folder structure. Use when designing or reviewing the internal layout of application modules.
|
|
4
|
+
apply-to: All application projects
|
|
5
|
+
valid-from: 2026-05-28
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# agentme-edr-policy-021: Pragmatic hexagonal architecture
|
|
9
|
+
|
|
10
|
+
## Context and Problem Statement
|
|
11
|
+
|
|
12
|
+
Applications often mix business logic with infrastructure concerns (database access, HTTP handling, environment variable reading), making code hard to test, refactor, and reuse.
|
|
13
|
+
|
|
14
|
+
How should application source code be organized to separate business logic from infrastructure while avoiding unnecessary abstraction layers?
|
|
15
|
+
|
|
16
|
+
## Decision Outcome
|
|
17
|
+
|
|
18
|
+
**Organize application source code into three conceptual layers — External (not in codebase), Adapters (inbound/outbound I/O boundaries), and Application (business logic exposed as typed library interfaces) — following a pragmatic variant of Hexagonal Architecture that avoids unnecessary abstractions.**
|
|
19
|
+
|
|
20
|
+
### Details
|
|
21
|
+
|
|
22
|
+
#### 01-three-layer-separation
|
|
23
|
+
|
|
24
|
+
Every application is conceptually divided into three layers:
|
|
25
|
+
|
|
26
|
+
| Layer | Description |
|
|
27
|
+
|-------|-------------|
|
|
28
|
+
| **External** | Systems outside the codebase boundary (databases, third-party APIs, message brokers, filesystems, users) |
|
|
29
|
+
| **Adapters** | Bridge between External and Application — translate external protocols into application calls and vice versa |
|
|
30
|
+
| **Application** | Business logic that delegates I/O to adapters |
|
|
31
|
+
|
|
32
|
+
#### 02-adapter-naming-conventions
|
|
33
|
+
|
|
34
|
+
**Inbound adapters** receive external requests or events and trigger application logic. Each gets a flat folder under `adapters/`:
|
|
35
|
+
|
|
36
|
+
- `cli/` — command-line interface entry point
|
|
37
|
+
- `http/` — HTTP/REST server
|
|
38
|
+
- `grpc/` — gRPC server
|
|
39
|
+
- `ws/` — WebSocket server
|
|
40
|
+
- `kafka/` — Kafka consumer
|
|
41
|
+
- `mqtt/` — MQTT subscriber
|
|
42
|
+
- Additional inbound adapters are allowed with descriptive names
|
|
43
|
+
|
|
44
|
+
**Outbound adapters** are called by the application to reach external systems. They live under `adapters/connectors/` with one subfolder per external resource, named descriptively:
|
|
45
|
+
|
|
46
|
+
- e.g.: `stripe-api/`, `config-file/`, `s3-datalake/`, `whatsapp/`, `postgres/`, `redis-cache/`
|
|
47
|
+
|
|
48
|
+
**Clarification:** "inbound" means the adapter triggers application logic in response to an external stimulus. "Outbound" means the application calls the adapter to interact with an external system.
|
|
49
|
+
|
|
50
|
+
#### 03-application-layer-rules
|
|
51
|
+
|
|
52
|
+
- Expose functionality as typed library interfaces
|
|
53
|
+
- All inputs must be explicitly passed as typed parameters
|
|
54
|
+
- No global variables, no direct environment variable access in `app/` or `shared/`
|
|
55
|
+
- Business logic with well-defined input/output behavior
|
|
56
|
+
- Group related logic into subfolders (aggregation roots)
|
|
57
|
+
- Environment variables must be read only in the bootstrap/entry-point layer of inbound adapters, converted into typed configuration objects, and passed explicitly to all other components
|
|
58
|
+
|
|
59
|
+
#### 04-mandatory-folder-structure
|
|
60
|
+
|
|
61
|
+
```text
|
|
62
|
+
mysystem/
|
|
63
|
+
Makefile # targets to run different inbound interfaces (e.g. run-http, run-cli)
|
|
64
|
+
src/
|
|
65
|
+
adapters/ # mandatory
|
|
66
|
+
cli/ # if CLI exists — bootstrap/entry point for CLI
|
|
67
|
+
http/ # if HTTP server exists — bootstrap/entry point for HTTP
|
|
68
|
+
grpc/ # if gRPC exists
|
|
69
|
+
connectors/ # if external resource access exists
|
|
70
|
+
postgres/ # one folder per external resource
|
|
71
|
+
stripe-api/
|
|
72
|
+
app/ # mandatory — core business logic
|
|
73
|
+
feature1.ts
|
|
74
|
+
feature-group/ # optional subfolders for grouping
|
|
75
|
+
shared/ # utilities and functions shared among adapters and app
|
|
76
|
+
logging.ts
|
|
77
|
+
errors.ts
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
`shared/` must contain only infrastructure-agnostic utilities — not business rules or domain logic.
|
|
81
|
+
|
|
82
|
+
#### 05-pragmatic-coupling
|
|
83
|
+
|
|
84
|
+
- Application MAY import from Adapters when it simplifies the design
|
|
85
|
+
- Avoid excessive abstractions, interface types, and indirection layers
|
|
86
|
+
- Only introduce interfaces or abstract types when building a framework where the extra complexity demonstrably pays off
|
|
87
|
+
- Prefer concrete implementations over abstract ports — skip the purism of classic Hexagonal Architecture in favor of practicality
|
|
88
|
+
- Some coupling between Application and Adapters is acceptable and expected
|
|
89
|
+
|
|
90
|
+
#### 06-bootstrap-and-entry-points
|
|
91
|
+
|
|
92
|
+
- Each inbound adapter folder (`cli/`, `http/`, `grpc/`, etc.) contains the bootstrap and entry point for that interface
|
|
93
|
+
- The project root Makefile must have targets to run the different inbound interfaces following [agentme-edr-008](../devops/008-common-targets.md) extension conventions (e.g. `run-http`, `run-grpc`)
|
|
94
|
+
- Bootstrap code lives in the adapter that receives inbound requests, not in a separate wiring layer
|
|
95
|
+
|
|
96
|
+
#### 07-minimum-complexity-threshold
|
|
97
|
+
|
|
98
|
+
- Trivial scripts and single-purpose tools (fewer than ~300 lines with a single I/O boundary) MAY skip this layering
|
|
99
|
+
- All other projects MUST use this structure from the start
|
|
100
|
+
|
|
101
|
+
#### 08-examples-of-data-flow
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
HTTP request → adapters/http/ → app/create-user → adapters/connectors/postgres/
|
|
105
|
+
CLI command → adapters/cli/ → app/create-dir → adapters/connectors/local-fs/
|
|
106
|
+
Kafka message → adapters/kafka/ → app/process-event → adapters/connectors/stripe-api/
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## References
|
|
110
|
+
|
|
111
|
+
- [agentme-edr-016](../principles/016-cross-language-module-structure.md) — Defines the module-root structure (Makefile, dist/, .cache/) that wraps this internal layout
|
|
112
|
+
- [agentme-edr-002](../principles/002-coding-best-practices.md) — File size limits and code organization practices that complement this architecture
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agentme-edr-skill-001-create-javascript-project
|
|
3
3
|
description: >
|
|
4
|
-
Scaffolds the initial boilerplate structure for a JavaScript/TypeScript
|
|
4
|
+
Scaffolds the initial boilerplate structure for a JavaScript/TypeScript project following
|
|
5
5
|
the standard tooling and layout defined in agentme-edr-003. Activate this skill when the user
|
|
6
|
-
asks to create, scaffold, or initialize a new JavaScript or TypeScript
|
|
6
|
+
asks to create, scaffold, or initialize a new JavaScript or TypeScript project, npm
|
|
7
7
|
package, or similar project structure.
|
|
8
8
|
metadata:
|
|
9
9
|
author: flaviostutz
|
|
@@ -13,13 +13,14 @@ compatibility: JavaScript/TypeScript, Node.js 18+
|
|
|
13
13
|
|
|
14
14
|
## Overview
|
|
15
15
|
|
|
16
|
-
Creates a complete JavaScript/TypeScript
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
Creates a complete JavaScript/TypeScript project from scratch. The layout keeps the
|
|
17
|
+
package self-contained in its module root (`lib/`), organizes internal code following
|
|
18
|
+
[agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md) (`adapters/`, `app/`, `shared/`),
|
|
19
|
+
places runnable consumer examples in the sibling `examples/` folder, redirects persistent caches
|
|
20
|
+
into `.cache/`, and uses Makefiles as the only entry points. Boilerplate is derived from the
|
|
21
|
+
[filedist](https://github.com/flaviostutz/filedist) project.
|
|
21
22
|
|
|
22
|
-
Related EDRs: [agentme-edr-003](../../003-javascript-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md)
|
|
23
|
+
Related EDRs: [agentme-edr-003](../../003-javascript-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md), [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md)
|
|
23
24
|
|
|
24
25
|
## Instructions
|
|
25
26
|
|
|
@@ -82,7 +83,7 @@ dist/
|
|
|
82
83
|
|
|
83
84
|
### Phase 3: Create `lib/`
|
|
84
85
|
|
|
85
|
-
**`lib/src/
|
|
86
|
+
**`lib/src/app/hello.ts`** — business logic:
|
|
86
87
|
|
|
87
88
|
```typescript
|
|
88
89
|
export const hello = (name: string): string => {
|
|
@@ -90,10 +91,10 @@ export const hello = (name: string): string => {
|
|
|
90
91
|
};
|
|
91
92
|
```
|
|
92
93
|
|
|
93
|
-
**`lib/src/
|
|
94
|
+
**`lib/src/app/hello.test.ts`** — co-located unit test:
|
|
94
95
|
|
|
95
96
|
```typescript
|
|
96
|
-
import { hello } from './
|
|
97
|
+
import { hello } from './hello';
|
|
97
98
|
|
|
98
99
|
describe('hello', () => {
|
|
99
100
|
it('should return a greeting', () => {
|
|
@@ -102,6 +103,20 @@ describe('hello', () => {
|
|
|
102
103
|
});
|
|
103
104
|
```
|
|
104
105
|
|
|
106
|
+
**`lib/src/index.ts`** — public API re-export from `app/`:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
export { hello } from './app/hello';
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**`lib/src/adapters/`** — create empty directories for the hexagonal structure:
|
|
113
|
+
|
|
114
|
+
- `lib/src/adapters/` — inbound adapters (add `cli/`, `http/`, etc. as needed)
|
|
115
|
+
- `lib/src/adapters/connectors/` — outbound adapters (one folder per external resource)
|
|
116
|
+
- `lib/src/shared/` — infrastructure-agnostic utilities
|
|
117
|
+
|
|
118
|
+
Create a placeholder `.gitkeep` in `lib/src/adapters/` and `lib/src/shared/` so the directories are tracked.
|
|
119
|
+
|
|
105
120
|
**`lib/Makefile`**:
|
|
106
121
|
|
|
107
122
|
```makefile
|
|
@@ -12,9 +12,9 @@ compatibility: Go 1.21+
|
|
|
12
12
|
|
|
13
13
|
## Overview
|
|
14
14
|
|
|
15
|
-
Creates a complete Go
|
|
15
|
+
Creates a complete Go project from scratch, following the layout from [agentme-edr-010](../../010-golang-project-tooling.md) and [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md). Business logic lives in `app/<feature>/` packages; CLI wiring lives in `adapters/cli/`; outbound integrations live in `adapters/connectors/`; `main.go` is a thin dispatcher. The module root owns its `Makefile`, `README.md`, `dist/`, and `.cache/` folders.
|
|
16
16
|
|
|
17
|
-
Related EDRs: [agentme-edr-010](../../010-golang-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md)
|
|
17
|
+
Related EDRs: [agentme-edr-010](../../010-golang-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md), [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md)
|
|
18
18
|
|
|
19
19
|
## Instructions
|
|
20
20
|
|
|
@@ -67,7 +67,7 @@ import (
|
|
|
67
67
|
"fmt"
|
|
68
68
|
"os"
|
|
69
69
|
|
|
70
|
-
cli
|
|
70
|
+
cli "[module]/adapters/cli"
|
|
71
71
|
)
|
|
72
72
|
|
|
73
73
|
func main() {
|
|
@@ -78,7 +78,7 @@ func main() {
|
|
|
78
78
|
|
|
79
79
|
switch os.Args[1] {
|
|
80
80
|
case "[subcommand]":
|
|
81
|
-
cli[Feature]
|
|
81
|
+
cli.Run[Feature](os.Args)
|
|
82
82
|
default:
|
|
83
83
|
fmt.Printf("Unknown command: %s\n", os.Args[1])
|
|
84
84
|
fmt.Println("Usage: [binary] [[feature]]")
|
|
@@ -216,7 +216,7 @@ coverage.out
|
|
|
216
216
|
|
|
217
217
|
### Phase 3: Create the feature package
|
|
218
218
|
|
|
219
|
-
**`[feature]/[feature].go`** (replace `[feature]`, `[Feature]`):
|
|
219
|
+
**`app/[feature]/[feature].go`** (replace `[feature]`, `[Feature]`):
|
|
220
220
|
|
|
221
221
|
```go
|
|
222
222
|
package [feature]
|
|
@@ -246,7 +246,7 @@ func Run(opts Options) (Result, error) {
|
|
|
246
246
|
}
|
|
247
247
|
```
|
|
248
248
|
|
|
249
|
-
**`[feature]/[feature]_test.go`** (replace `[feature]`, `[Feature]`):
|
|
249
|
+
**`app/[feature]/[feature]_test.go`** (replace `[feature]`, `[Feature]`):
|
|
250
250
|
|
|
251
251
|
```go
|
|
252
252
|
package [feature]
|
|
@@ -267,12 +267,12 @@ func Test[Feature]Run(t *testing.T) {
|
|
|
267
267
|
|
|
268
268
|
---
|
|
269
269
|
|
|
270
|
-
### Phase 4: Create the CLI
|
|
270
|
+
### Phase 4: Create the CLI adapter
|
|
271
271
|
|
|
272
|
-
**`cli/[feature]
|
|
272
|
+
**`adapters/cli/[feature].go`** (replace `[module]`, `[feature]`, `[Feature]`, `[subcommand]`):
|
|
273
273
|
|
|
274
274
|
```go
|
|
275
|
-
package cli
|
|
275
|
+
package cli
|
|
276
276
|
|
|
277
277
|
import (
|
|
278
278
|
"flag"
|
|
@@ -280,11 +280,11 @@ import (
|
|
|
280
280
|
"os"
|
|
281
281
|
|
|
282
282
|
"github.com/sirupsen/logrus"
|
|
283
|
-
"[module]/[feature]"
|
|
283
|
+
"[module]/app/[feature]"
|
|
284
284
|
)
|
|
285
285
|
|
|
286
|
-
// Run parses CLI flags for the [subcommand] command and calls the domain package.
|
|
287
|
-
func Run(args []string) {
|
|
286
|
+
// Run[Feature] parses CLI flags for the [subcommand] command and calls the domain package.
|
|
287
|
+
func Run[Feature](args []string) {
|
|
288
288
|
fs := flag.NewFlagSet("[subcommand]", flag.ExitOnError)
|
|
289
289
|
verbose := fs.Bool("verbose", false, "Show verbose logs during processing")
|
|
290
290
|
|
|
@@ -309,6 +309,21 @@ func Run(args []string) {
|
|
|
309
309
|
}
|
|
310
310
|
```
|
|
311
311
|
|
|
312
|
+
**`shared/logging.go`** (optional, scaffold if needed):
|
|
313
|
+
|
|
314
|
+
```go
|
|
315
|
+
package shared
|
|
316
|
+
|
|
317
|
+
import "github.com/sirupsen/logrus"
|
|
318
|
+
|
|
319
|
+
// SetupLogging configures the global log level.
|
|
320
|
+
func SetupLogging(verbose bool) {
|
|
321
|
+
if verbose {
|
|
322
|
+
logrus.SetLevel(logrus.DebugLevel)
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
312
327
|
---
|
|
313
328
|
|
|
314
329
|
### Phase 5: Verify and run
|
|
@@ -327,8 +342,10 @@ Fix any compile or lint errors before finishing.
|
|
|
327
342
|
## Conventions and reminders
|
|
328
343
|
|
|
329
344
|
- `main.go` dispatches only — no logic.
|
|
330
|
-
- Business logic only in `
|
|
331
|
-
- `cli
|
|
345
|
+
- Business logic only in `app/<feature>/` packages — no flag parsing, no `fmt.Println` for diagnostics.
|
|
346
|
+
- `adapters/cli/` owns flag parsing, output formatting, and the wiring between flags and `app/` functions. No business logic lives in adapter packages.
|
|
347
|
+
- Outbound adapters live under `adapters/connectors/` with one subfolder per external resource (e.g., `postgres/`, `stripe-api/`, `redis-cache/`).
|
|
348
|
+
- `shared/` must contain only infrastructure-agnostic utilities — not business rules or domain logic.
|
|
332
349
|
- All tests co-located (`*_test.go` next to the file under test).
|
|
333
350
|
- Use `tests_integration/` for integration flows and `tests_benchmark/` when benchmarks need dedicated harnesses or datasets.
|
|
334
351
|
- Log with `logrus`; never use `fmt.Println` for diagnostic/debug output.
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agentme-edr-skill-005-create-python-project
|
|
3
3
|
description: >
|
|
4
|
-
Scaffolds the initial boilerplate structure for a Python
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
structure.
|
|
4
|
+
Scaffolds the initial boilerplate structure for a Python project following the standard tooling
|
|
5
|
+
and layout defined in agentme-edr-014. Activate this skill when the user asks to create,
|
|
6
|
+
scaffold, or initialize a new Python package, CLI, or similar project structure.
|
|
8
7
|
metadata:
|
|
9
8
|
author: flaviostutz
|
|
10
9
|
version: "1.0"
|
|
@@ -14,11 +13,12 @@ compatibility: Python 3.12+
|
|
|
14
13
|
## Overview
|
|
15
14
|
|
|
16
15
|
Creates a complete Python project from scratch using Mise, `uv`, `pyproject.toml`, Ruff,
|
|
17
|
-
Pyright, Pytest, and Makefiles. The
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
Pyright, Pytest, and Makefiles. The layout keeps the package self-contained under `lib/`,
|
|
17
|
+
organizes internal code following [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md)
|
|
18
|
+
(`adapters/`, `app/`, `shared/`), uses a shared root `.venv/`, redirects persistent caches into
|
|
19
|
+
`.cache/`, and places runnable consumer projects under the sibling `examples/` folder.
|
|
20
20
|
|
|
21
|
-
Related EDRs: [agentme-edr-014](../../014-python-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md)
|
|
21
|
+
Related EDRs: [agentme-edr-014](../../014-python-project-tooling.md), [agentme-edr-016](../../../principles/016-cross-language-module-structure.md), [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md)
|
|
22
22
|
|
|
23
23
|
## Instructions
|
|
24
24
|
|
|
@@ -30,7 +30,6 @@ Ask for or infer from context:
|
|
|
30
30
|
- **Short description** - one sentence
|
|
31
31
|
- **Author** name or GitHub username
|
|
32
32
|
- **Python version** - default `3.13`
|
|
33
|
-
- **Project kind** - `library` or `cli`
|
|
34
33
|
- **Primary entry point** - first module or command name to scaffold
|
|
35
34
|
- **GitHub repo URL** - optional, for project metadata
|
|
36
35
|
- **Confirm target directory** - default: current workspace root
|
|
@@ -105,6 +104,7 @@ The root `Makefile` keeps the repository clean by delegating package work to `li
|
|
|
105
104
|
.venv/
|
|
106
105
|
dist/
|
|
107
106
|
.cache/
|
|
107
|
+
__pycache__/
|
|
108
108
|
```
|
|
109
109
|
|
|
110
110
|
**`./README.md`**
|
|
@@ -214,11 +214,28 @@ requires = ["hatchling>=1.27.0"]
|
|
|
214
214
|
build-backend = "hatchling.build"
|
|
215
215
|
|
|
216
216
|
[tool.ruff]
|
|
217
|
-
|
|
217
|
+
cache-dir = ".cache/ruff"
|
|
218
|
+
output-format = "grouped"
|
|
219
|
+
line-length = 120
|
|
218
220
|
target-version = "py313"
|
|
221
|
+
src = ["src", "tests", "tests_integration"]
|
|
222
|
+
|
|
223
|
+
[tool.ruff.format]
|
|
224
|
+
docstring-code-format = true
|
|
225
|
+
line-ending = "lf"
|
|
219
226
|
|
|
220
227
|
[tool.ruff.lint]
|
|
221
|
-
|
|
228
|
+
task-tags = ["TODO"]
|
|
229
|
+
select = ["ERA", "FAST", "ANN", "ASYNC", "S", "BLE", "FBT", "B", "A", "COM",
|
|
230
|
+
"C4", "DTZ", "T10", "DJ", "EM", "EXE", "FIX", "INT", "ISC", "ICN", "LOG", "G",
|
|
231
|
+
"INP", "PIE", "T20", "PYI", "PT", "Q", "RSE", "RET", "SLF", "SIM", "SLOT", "TID",
|
|
232
|
+
"TC", "ARG", "PTH", "FLY", "I", "C90", "NPY", "PD", "N", "PERF", "E", "W",
|
|
233
|
+
"D", "F", "PGH", "PL", "UP", "FURB", "RUF", "TRY"]
|
|
234
|
+
ignore = ["ANN002", "ANN003", "ANN401", "D100", "D101", "D102", "D103", "D104",
|
|
235
|
+
"D105", "D106", "D107", "COM812", "D203", "D213", "D400", "D401", "D404", "D415", "FIX002"]
|
|
236
|
+
|
|
237
|
+
[tool.ruff.lint.pycodestyle]
|
|
238
|
+
ignore-overlong-task-comments = true
|
|
222
239
|
|
|
223
240
|
[tool.pyright]
|
|
224
241
|
include = ["src", "tests"]
|
|
@@ -267,29 +284,37 @@ make test
|
|
|
267
284
|
|
|
268
285
|
### Phase 4: Create the package and tests inside `lib/`
|
|
269
286
|
|
|
270
|
-
Create this baseline structure.
|
|
287
|
+
Create this baseline structure following [agentme-edr-021](../../021-pragmatic-hexagonal-architecture.md).
|
|
271
288
|
|
|
272
289
|
**`lib/src/[package_name]/__init__.py`**
|
|
273
290
|
|
|
274
291
|
```python
|
|
275
|
-
from .
|
|
292
|
+
from .app.hello import hello
|
|
276
293
|
|
|
277
294
|
__all__ = ["hello"]
|
|
278
295
|
```
|
|
279
296
|
|
|
280
|
-
**`lib/src/[package_name]/
|
|
297
|
+
**`lib/src/[package_name]/app/__init__.py`**
|
|
298
|
+
|
|
299
|
+
```python
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**`lib/src/[package_name]/app/hello.py`**
|
|
281
303
|
|
|
282
304
|
```python
|
|
283
305
|
def hello(name: str) -> str:
|
|
284
306
|
return f"Hello, {name}!"
|
|
285
307
|
```
|
|
286
308
|
|
|
287
|
-
**`lib/src/[package_name]/
|
|
309
|
+
**`lib/src/[package_name]/adapters/__init__.py`**
|
|
288
310
|
|
|
289
|
-
|
|
311
|
+
```python
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**`lib/src/[package_name]/adapters/cli/__init__.py`**
|
|
290
315
|
|
|
291
316
|
```python
|
|
292
|
-
from .
|
|
317
|
+
from [package_name].app.hello import hello
|
|
293
318
|
|
|
294
319
|
|
|
295
320
|
def main() -> None:
|
|
@@ -300,10 +325,17 @@ if __name__ == "__main__":
|
|
|
300
325
|
main()
|
|
301
326
|
```
|
|
302
327
|
|
|
303
|
-
**`lib/
|
|
328
|
+
**`lib/src/[package_name]/shared/__init__.py`**
|
|
329
|
+
|
|
330
|
+
```python
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Create empty `adapters/connectors/` directory with a `.gitkeep` for outbound adapters.
|
|
334
|
+
|
|
335
|
+
**`lib/tests/test_hello.py`**
|
|
304
336
|
|
|
305
337
|
```python
|
|
306
|
-
from [package_name].
|
|
338
|
+
from [package_name].app.hello import hello
|
|
307
339
|
|
|
308
340
|
|
|
309
341
|
def test_hello() -> None:
|
|
@@ -314,9 +346,9 @@ If two or more test files need shared fixtures, create `lib/tests/conftest.py` a
|
|
|
314
346
|
|
|
315
347
|
If the module needs slower end-to-end coverage, place those tests in `lib/tests_integration/`. Put dedicated benchmark harnesses in `lib/tests_benchmark/`.
|
|
316
348
|
|
|
317
|
-
### Phase 5: Create examples
|
|
349
|
+
### Phase 5: Create examples
|
|
318
350
|
|
|
319
|
-
|
|
351
|
+
Add an `examples/` directory with one subdirectory per runnable consumer example. Each example must be its own Python project.
|
|
320
352
|
|
|
321
353
|
**`examples/basic-usage/pyproject.toml`**
|
|
322
354
|
|
|
@@ -355,14 +387,15 @@ After creating the files:
|
|
|
355
387
|
|
|
356
388
|
## Examples
|
|
357
389
|
|
|
358
|
-
**Input:** "Create a Python
|
|
390
|
+
**Input:** "Create a Python project called `event_tools`"
|
|
359
391
|
- Create `Makefile`, `README.md`, `lib/pyproject.toml`, `lib/Makefile`, `lib/src/event_tools/`, `lib/tests/`, and `examples/`
|
|
392
|
+
- Scaffold `adapters/`, `app/`, `shared/` directories inside `lib/src/event_tools/`
|
|
360
393
|
- Add `lib/README.md`, `.cache/` handling, and install examples from the built wheel in `lib/dist/`
|
|
361
394
|
- Configure `uv`, Ruff, Pyright, Pytest, `pytest-cov`, and `pip-audit`
|
|
362
395
|
- Verify with `make lint-fix`, `make test`, and `make build`
|
|
363
396
|
|
|
364
397
|
**Input:** "Scaffold a Python CLI package"
|
|
365
|
-
- Add `lib/src/<package_name>/
|
|
398
|
+
- Add CLI entry point in `lib/src/<package_name>/adapters/cli/__init__.py`
|
|
366
399
|
- Add `[project.scripts]` in `lib/pyproject.toml` when the command name must differ from the module name
|
|
367
400
|
- Keep the same Makefile and quality checks
|
|
368
401
|
|
|
@@ -20,7 +20,7 @@ What monorepo structure, naming conventions, tooling, and build standards should
|
|
|
20
20
|
For step-by-step scaffolding instructions see [skill 002-monorepo-setup](skills/002-monorepo-setup/SKILL.md).
|
|
21
21
|
Module folder responsibilities, artifact locations, and test-folder conventions follow [agentme-edr-016](../principles/016-cross-language-module-structure.md).
|
|
22
22
|
|
|
23
|
-
###
|
|
23
|
+
### Details
|
|
24
24
|
|
|
25
25
|
#### 01-top-level-directory-layout
|
|
26
26
|
|