atdd 0.4.3__py3-none-any.whl → 0.4.5__py3-none-any.whl
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.
- atdd/coach/commands/sync.py +35 -8
- atdd/coach/templates/SESSION-TEMPLATE.md +1 -1
- atdd/coach/validators/test_release_versioning.py +13 -1
- {atdd-0.4.3.dist-info → atdd-0.4.5.dist-info}/METADATA +13 -5
- {atdd-0.4.3.dist-info → atdd-0.4.5.dist-info}/RECORD +9 -9
- {atdd-0.4.3.dist-info → atdd-0.4.5.dist-info}/WHEEL +0 -0
- {atdd-0.4.3.dist-info → atdd-0.4.5.dist-info}/entry_points.txt +0 -0
- {atdd-0.4.3.dist-info → atdd-0.4.5.dist-info}/licenses/LICENSE +0 -0
- {atdd-0.4.3.dist-info → atdd-0.4.5.dist-info}/top_level.txt +0 -0
atdd/coach/commands/sync.py
CHANGED
|
@@ -194,6 +194,11 @@ class AgentConfigSync:
|
|
|
194
194
|
"""
|
|
195
195
|
agents = self._get_enabled_agents()
|
|
196
196
|
|
|
197
|
+
# Get configured vs detected for display
|
|
198
|
+
config = self._load_config()
|
|
199
|
+
sync_config = config.get("sync", {})
|
|
200
|
+
configured_agents = set(sync_config.get("agents", []))
|
|
201
|
+
|
|
197
202
|
print("\n" + "=" * 60)
|
|
198
203
|
print("ATDD Agent Config Sync Status")
|
|
199
204
|
print("=" * 60)
|
|
@@ -202,8 +207,8 @@ class AgentConfigSync:
|
|
|
202
207
|
print(f"ATDD template: {self.atdd_template}")
|
|
203
208
|
print(f"Overlays dir: {self.overlays_dir}")
|
|
204
209
|
|
|
205
|
-
print(f"\n{'Agent':<10} {'File':<15} {'Status':<20}")
|
|
206
|
-
print("-" *
|
|
210
|
+
print(f"\n{'Agent':<10} {'File':<15} {'Status':<20} {'Source':<12}")
|
|
211
|
+
print("-" * 62)
|
|
207
212
|
|
|
208
213
|
for agent, target_file in sorted(self.AGENT_FILES.items()):
|
|
209
214
|
target_path = self.target_dir / target_file
|
|
@@ -211,18 +216,22 @@ class AgentConfigSync:
|
|
|
211
216
|
|
|
212
217
|
if not enabled:
|
|
213
218
|
status = "disabled"
|
|
219
|
+
source = ""
|
|
214
220
|
elif not target_path.exists():
|
|
215
221
|
status = "missing"
|
|
222
|
+
source = "config"
|
|
216
223
|
elif not self._has_managed_block(target_path.read_text()):
|
|
217
224
|
status = "no managed block"
|
|
225
|
+
source = "auto" if agent not in configured_agents else "config"
|
|
218
226
|
else:
|
|
219
227
|
status = "synced"
|
|
228
|
+
source = "auto" if agent not in configured_agents else "config"
|
|
220
229
|
|
|
221
230
|
enabled_marker = "*" if enabled else " "
|
|
222
|
-
print(f"{enabled_marker} {agent:<8} {target_file:<15} {status:<20}")
|
|
231
|
+
print(f"{enabled_marker} {agent:<8} {target_file:<15} {status:<20} {source:<12}")
|
|
223
232
|
|
|
224
|
-
print("-" *
|
|
225
|
-
print("* = enabled
|
|
233
|
+
print("-" * 62)
|
|
234
|
+
print("* = enabled for sync (config = explicit, auto = file exists)")
|
|
226
235
|
|
|
227
236
|
# Show overlay status
|
|
228
237
|
print("\nOverlays:")
|
|
@@ -250,14 +259,32 @@ class AgentConfigSync:
|
|
|
250
259
|
|
|
251
260
|
def _get_enabled_agents(self) -> List[str]:
|
|
252
261
|
"""
|
|
253
|
-
Return agents
|
|
262
|
+
Return agents to sync: configured agents + existing agent files.
|
|
263
|
+
|
|
264
|
+
Auto-includes any supported agent file that already exists in the
|
|
265
|
+
target directory, in addition to explicitly configured agents.
|
|
266
|
+
This ensures existing agent files stay in sync without requiring
|
|
267
|
+
explicit configuration.
|
|
254
268
|
|
|
255
269
|
Returns:
|
|
256
|
-
List of agent names enabled for sync.
|
|
270
|
+
List of unique agent names enabled for sync.
|
|
257
271
|
"""
|
|
272
|
+
# Get explicitly configured agents
|
|
258
273
|
config = self._load_config()
|
|
259
274
|
sync_config = config.get("sync", {})
|
|
260
|
-
|
|
275
|
+
configured_agents = set(sync_config.get("agents", []))
|
|
276
|
+
|
|
277
|
+
# Auto-detect existing agent files
|
|
278
|
+
detected_agents = set()
|
|
279
|
+
for agent, filename in self.AGENT_FILES.items():
|
|
280
|
+
agent_path = self.target_dir / filename
|
|
281
|
+
if agent_path.exists():
|
|
282
|
+
detected_agents.add(agent)
|
|
283
|
+
|
|
284
|
+
# Merge: configured + detected
|
|
285
|
+
all_agents = configured_agents | detected_agents
|
|
286
|
+
|
|
287
|
+
return sorted(all_agents)
|
|
261
288
|
|
|
262
289
|
def _load_base_content(self) -> Optional[str]:
|
|
263
290
|
"""
|
|
@@ -348,7 +348,7 @@ Rules:
|
|
|
348
348
|
-->
|
|
349
349
|
|
|
350
350
|
- [ ] Determine change class: PATCH / MINOR / MAJOR
|
|
351
|
-
- [ ] Bump version in version file (
|
|
351
|
+
- [ ] Bump version in version file (recommended: VERSION; sync any language manifests if used)
|
|
352
352
|
- [ ] Commit: "Bump version to {version}"
|
|
353
353
|
- [ ] Create tag: `git tag v{version}`
|
|
354
354
|
- [ ] Push with tags: `git push origin {branch} --tags`
|
|
@@ -62,6 +62,12 @@ def _read_version_from_file(path: Path) -> str:
|
|
|
62
62
|
version = _parse_package_json_version(path)
|
|
63
63
|
else:
|
|
64
64
|
version = _parse_plain_version(path)
|
|
65
|
+
if not version:
|
|
66
|
+
pytest.fail(
|
|
67
|
+
f"Could not read version from {path}. "
|
|
68
|
+
"Expected first non-comment line to contain a semver like "
|
|
69
|
+
"'1.2.3' or '1.2.3 - short summary'."
|
|
70
|
+
)
|
|
65
71
|
|
|
66
72
|
if not version:
|
|
67
73
|
pytest.fail(f"Could not read version from {path}")
|
|
@@ -127,11 +133,17 @@ def _parse_package_json_version(path: Path) -> Optional[str]:
|
|
|
127
133
|
|
|
128
134
|
|
|
129
135
|
def _parse_plain_version(path: Path) -> Optional[str]:
|
|
136
|
+
version_pattern = re.compile(
|
|
137
|
+
r"\bv?(?P<version>\d+\.\d+(?:\.\d+)?(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)\b"
|
|
138
|
+
)
|
|
130
139
|
for line in path.read_text().splitlines():
|
|
131
140
|
stripped = line.strip()
|
|
132
141
|
if not stripped or stripped.startswith("#"):
|
|
133
142
|
continue
|
|
134
|
-
|
|
143
|
+
match = version_pattern.search(stripped)
|
|
144
|
+
if match:
|
|
145
|
+
return match.group("version")
|
|
146
|
+
return None
|
|
135
147
|
return None
|
|
136
148
|
|
|
137
149
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atdd
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.5
|
|
4
4
|
Summary: ATDD Platform - Acceptance Test Driven Development toolkit
|
|
5
5
|
License: MIT
|
|
6
6
|
Requires-Python: >=3.10
|
|
@@ -58,14 +58,20 @@ atdd --help
|
|
|
58
58
|
```bash
|
|
59
59
|
atdd init # Initialize ATDD in your project
|
|
60
60
|
atdd gate # ⚠️ START EVERY SESSION WITH THIS
|
|
61
|
-
atdd session new <
|
|
61
|
+
atdd session new <task> # Create a planning session
|
|
62
62
|
atdd sync # Sync rules to agent config files
|
|
63
63
|
atdd validate # Run all validators
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
> **⚠️ `atdd gate` is required.**
|
|
67
67
|
> 🤖 Tell your agent: "Run `atdd gate` and follow ATDD rigorously."
|
|
68
|
-
> Agents skip instruction files but can't ignore tool
|
|
68
|
+
> Agents skip instruction files but can't ignore tool ou
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
tput. No gate = no ATDD guarantees.
|
|
69
75
|
|
|
70
76
|
## What It Does
|
|
71
77
|
|
|
@@ -232,14 +238,16 @@ atdd validate --html # With HTML report
|
|
|
232
238
|
|
|
233
239
|
### Release Versioning
|
|
234
240
|
|
|
235
|
-
ATDD enforces release versioning via coach validators. Configure the version file and tag prefix in `.atdd/config.yaml`:
|
|
241
|
+
ATDD enforces release versioning via coach validators. Recommended: keep a single root `VERSION` file as the canonical source (first line like `1.2.3 - short summary`; trailing summary is ignored). Configure the version file and tag prefix in `.atdd/config.yaml`:
|
|
236
242
|
|
|
237
243
|
```yaml
|
|
238
244
|
release:
|
|
239
|
-
version_file: "
|
|
245
|
+
version_file: "VERSION" # recommended single source of truth
|
|
240
246
|
tag_prefix: "v"
|
|
241
247
|
```
|
|
242
248
|
|
|
249
|
+
If you also publish with language-specific manifests (e.g., `pyproject.toml`, `package.json`), keep their version fields in sync with `VERSION`.
|
|
250
|
+
|
|
243
251
|
Validation (`atdd validate coach` or `atdd validate`) requires:
|
|
244
252
|
- Version file exists and contains a version
|
|
245
253
|
- Git tag on HEAD matches `{tag_prefix}{version}`
|
|
@@ -16,7 +16,7 @@ atdd/coach/commands/inventory.py,sha256=qU42MnkXt1JSBh5GU7pPSKmCO27Zfga7XwMT19Rq
|
|
|
16
16
|
atdd/coach/commands/migration.py,sha256=wRxU7emvvHqWt1MvXKkNTkPBjp0sU9g8F5Uy5yV2YfI,8177
|
|
17
17
|
atdd/coach/commands/registry.py,sha256=76-Pe3_cN483JR1pXUdDIE5WSZjWtVV0Jl8dRtRw_9Y,58349
|
|
18
18
|
atdd/coach/commands/session.py,sha256=MhuWXd5TR6bB3w0t8vANeZx3L476qwLT6EUQMwg-wQA,14268
|
|
19
|
-
atdd/coach/commands/sync.py,sha256=
|
|
19
|
+
atdd/coach/commands/sync.py,sha256=SLNzhcc6IuzMofMbkH9wM9rBSk5tPfcWPKXn9TaSZ-Y,13782
|
|
20
20
|
atdd/coach/commands/test_interface.py,sha256=a7ut2Hhk0PnQ5LfJZkoQwfkfkVuB5OHA4QBwOS0-jcg,16870
|
|
21
21
|
atdd/coach/commands/test_runner.py,sha256=_6JrDRq5fBHUOC4MtkgXcjkgJjG80otoGRTqnkEphIk,5832
|
|
22
22
|
atdd/coach/commands/traceability.py,sha256=8TmpZDeUVHJAz-p3oxXq55jCFiFpKIQR8h1wLZVYcgA,163612
|
|
@@ -28,7 +28,7 @@ atdd/coach/overlays/claude.md,sha256=33mhpqhmsRhCtdWlU7cMXAJDsaVra9uBBK8URV8OtQA
|
|
|
28
28
|
atdd/coach/schemas/config.schema.json,sha256=CpePppEAB6WiLeWVgWW3EKOxlLvMHHcWisRnJL9z_SE,1863
|
|
29
29
|
atdd/coach/schemas/manifest.schema.json,sha256=WO13-YF_FgH1awh96khCtk-112b6XSC24anlY3B7GjY,2885
|
|
30
30
|
atdd/coach/templates/ATDD.md,sha256=MLbrVbCETJre4c05d5FXGuf6W95Hz9E0jpE4RI9r4cg,13237
|
|
31
|
-
atdd/coach/templates/SESSION-TEMPLATE.md,sha256=
|
|
31
|
+
atdd/coach/templates/SESSION-TEMPLATE.md,sha256=cGT_0x5KLbPHOCiuM8evLGpWKIlR-aggqxiBtbjSJoo,9478
|
|
32
32
|
atdd/coach/utils/__init__.py,sha256=7Jbo-heJEKSAn6I0s35z_2S4R8qGZ48PL6a2IntcNYg,148
|
|
33
33
|
atdd/coach/utils/repo.py,sha256=0kiF5WpVTen0nO14u5T0RflznZhgGco2i9CwKobOh38,3757
|
|
34
34
|
atdd/coach/utils/graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -37,7 +37,7 @@ atdd/coach/validators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
|
37
37
|
atdd/coach/validators/shared_fixtures.py,sha256=tdqAb4675P-oOCL08mvSCG9XpmwMCjL9iSq1W5U7-wk,12558
|
|
38
38
|
atdd/coach/validators/test_enrich_wagon_registry.py,sha256=WeTwYJqoNY6mEYc-QAvQo7YVagSOjaNKxB6Q6dpWqIM,6561
|
|
39
39
|
atdd/coach/validators/test_registry.py,sha256=ffN70yA_1xxL3R8gdpGbY2M8dQXyuajIZhBZ-ylNiNs,17845
|
|
40
|
-
atdd/coach/validators/test_release_versioning.py,sha256
|
|
40
|
+
atdd/coach/validators/test_release_versioning.py,sha256=B40DfbtrSGguPc537zXmjT75hhySfocWLzJWqOKZQcU,5678
|
|
41
41
|
atdd/coach/validators/test_session_validation.py,sha256=0VszXtFwRTO04b5CxDPO3klk0VfiqlpdbNpshjMn-qU,39079
|
|
42
42
|
atdd/coach/validators/test_traceability.py,sha256=qTyobt41VBiCr6xRN2C7BPtGYvk_2poVQIe814Blt8E,15977
|
|
43
43
|
atdd/coach/validators/test_update_feature_paths.py,sha256=zOKVDgEIpncSJwDh_shyyou5Pu-Ai7Z_XgF8zAbQVTA,4528
|
|
@@ -182,9 +182,9 @@ atdd/tester/validators/test_red_supabase_layer_structure.py,sha256=zbUjsMWSJE1MP
|
|
|
182
182
|
atdd/tester/validators/test_telemetry_structure.py,sha256=uU5frZnxSlOn60iHyqhe7Pg9b0wrOV7N14D4S6Aw6TE,22626
|
|
183
183
|
atdd/tester/validators/test_typescript_test_naming.py,sha256=E-TyGv_GVlTfsbyuxrtv9sOWSZS_QcpH6rrJFbWoeeU,11280
|
|
184
184
|
atdd/tester/validators/test_typescript_test_structure.py,sha256=eV89SD1RaKtchBZupqhnJmaruoROosf3LwB4Fwe4UJI,2612
|
|
185
|
-
atdd-0.4.
|
|
186
|
-
atdd-0.4.
|
|
187
|
-
atdd-0.4.
|
|
188
|
-
atdd-0.4.
|
|
189
|
-
atdd-0.4.
|
|
190
|
-
atdd-0.4.
|
|
185
|
+
atdd-0.4.5.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
186
|
+
atdd-0.4.5.dist-info/METADATA,sha256=tMR-3urPv4DOZPD6Mx-9e94DMpuxX8DMhmNymzr9XQ0,8716
|
|
187
|
+
atdd-0.4.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
188
|
+
atdd-0.4.5.dist-info/entry_points.txt,sha256=-C3yrA1WQQfN3iuGmSzPapA5cKVBEYU5Q1HUffSJTbY,38
|
|
189
|
+
atdd-0.4.5.dist-info/top_level.txt,sha256=VKkf6Uiyrm4RS6ULCGM-v8AzYN8K2yg8SMqwJLoO-xs,5
|
|
190
|
+
atdd-0.4.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|