tapps-agents 3.5.39__py3-none-any.whl → 3.5.40__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.
- tapps_agents/__init__.py +2 -2
- tapps_agents/agents/enhancer/agent.py +2728 -2728
- tapps_agents/agents/implementer/agent.py +35 -13
- tapps_agents/agents/reviewer/agent.py +43 -10
- tapps_agents/agents/reviewer/scoring.py +59 -68
- tapps_agents/agents/reviewer/tools/__init__.py +24 -0
- tapps_agents/agents/reviewer/tools/ruff_grouping.py +250 -0
- tapps_agents/agents/reviewer/tools/scoped_mypy.py +284 -0
- tapps_agents/beads/__init__.py +11 -0
- tapps_agents/beads/hydration.py +213 -0
- tapps_agents/beads/specs.py +206 -0
- tapps_agents/cli/commands/health.py +19 -3
- tapps_agents/cli/commands/simple_mode.py +842 -676
- tapps_agents/cli/commands/task.py +219 -0
- tapps_agents/cli/commands/top_level.py +13 -0
- tapps_agents/cli/main.py +658 -651
- tapps_agents/cli/parsers/top_level.py +1978 -1881
- tapps_agents/core/config.py +1622 -1622
- tapps_agents/core/init_project.py +3012 -2897
- tapps_agents/epic/markdown_sync.py +105 -0
- tapps_agents/epic/orchestrator.py +1 -2
- tapps_agents/epic/parser.py +427 -423
- tapps_agents/experts/adaptive_domain_detector.py +0 -2
- tapps_agents/experts/knowledge/api-design-integration/api-security-patterns.md +15 -15
- tapps_agents/experts/knowledge/api-design-integration/external-api-integration.md +19 -44
- tapps_agents/health/checks/outcomes.backup_20260204_064058.py +324 -0
- tapps_agents/health/checks/outcomes.backup_20260204_064256.py +324 -0
- tapps_agents/health/checks/outcomes.backup_20260204_064600.py +324 -0
- tapps_agents/health/checks/outcomes.py +134 -46
- tapps_agents/health/orchestrator.py +12 -4
- tapps_agents/hooks/__init__.py +33 -0
- tapps_agents/hooks/config.py +140 -0
- tapps_agents/hooks/events.py +135 -0
- tapps_agents/hooks/executor.py +128 -0
- tapps_agents/hooks/manager.py +143 -0
- tapps_agents/session/__init__.py +19 -0
- tapps_agents/session/manager.py +256 -0
- tapps_agents/simple_mode/code_snippet_handler.py +382 -0
- tapps_agents/simple_mode/intent_parser.py +29 -4
- tapps_agents/simple_mode/orchestrators/base.py +185 -59
- tapps_agents/simple_mode/orchestrators/build_orchestrator.py +2667 -2642
- tapps_agents/simple_mode/orchestrators/fix_orchestrator.py +2 -2
- tapps_agents/simple_mode/workflow_suggester.py +37 -3
- tapps_agents/workflow/agent_handlers/implementer_handler.py +18 -3
- tapps_agents/workflow/cursor_executor.py +2196 -2118
- tapps_agents/workflow/direct_execution_fallback.py +16 -3
- tapps_agents/workflow/message_formatter.py +2 -1
- tapps_agents/workflow/parallel_executor.py +43 -4
- tapps_agents/workflow/parser.py +375 -357
- tapps_agents/workflow/rules_generator.py +337 -337
- tapps_agents/workflow/skill_invoker.py +9 -3
- {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.40.dist-info}/METADATA +5 -1
- {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.40.dist-info}/RECORD +57 -53
- tapps_agents/agents/analyst/SKILL.md +0 -85
- tapps_agents/agents/architect/SKILL.md +0 -80
- tapps_agents/agents/debugger/SKILL.md +0 -66
- tapps_agents/agents/designer/SKILL.md +0 -78
- tapps_agents/agents/documenter/SKILL.md +0 -95
- tapps_agents/agents/enhancer/SKILL.md +0 -189
- tapps_agents/agents/implementer/SKILL.md +0 -117
- tapps_agents/agents/improver/SKILL.md +0 -55
- tapps_agents/agents/ops/SKILL.md +0 -64
- tapps_agents/agents/orchestrator/SKILL.md +0 -238
- tapps_agents/agents/planner/story_template.md +0 -37
- tapps_agents/agents/reviewer/templates/quality-dashboard.html.j2 +0 -150
- tapps_agents/agents/tester/SKILL.md +0 -71
- {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.40.dist-info}/WHEEL +0 -0
- {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.40.dist-info}/entry_points.txt +0 -0
- {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.40.dist-info}/licenses/LICENSE +0 -0
- {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.40.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sync epic execution status from report JSON back into the epic markdown file.
|
|
3
|
+
|
|
4
|
+
Updates each story block with **Execution status:** done | failed so the .md
|
|
5
|
+
reflects the last run. Run after epic execution or when you have a report file.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import re
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def update_epic_markdown_from_report(
|
|
14
|
+
epic_path: Path | str,
|
|
15
|
+
report_path: Path | None = None,
|
|
16
|
+
project_root: Path | None = None,
|
|
17
|
+
) -> None:
|
|
18
|
+
"""
|
|
19
|
+
Update the epic markdown file with execution status from the report JSON.
|
|
20
|
+
|
|
21
|
+
For each story in the report, adds or replaces a line
|
|
22
|
+
"**Execution status:** done" or "**Execution status:** failed"
|
|
23
|
+
in the corresponding story block.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
epic_path: Path to the epic .md file.
|
|
27
|
+
report_path: Path to epic-N-report.json. If None, uses same directory
|
|
28
|
+
as epic_path and filename epic-{N}-report.json (N from epic content).
|
|
29
|
+
project_root: Project root for resolving relative epic_path. Defaults to cwd.
|
|
30
|
+
|
|
31
|
+
Raises:
|
|
32
|
+
FileNotFoundError: If epic or report file is missing.
|
|
33
|
+
ValueError: If report format is invalid or epic number cannot be determined.
|
|
34
|
+
"""
|
|
35
|
+
root = Path(project_root or Path.cwd())
|
|
36
|
+
epic_path = Path(epic_path)
|
|
37
|
+
if not epic_path.is_absolute():
|
|
38
|
+
for base in [root, root / "stories", root / "docs" / "prd"]:
|
|
39
|
+
candidate = base / epic_path.name if epic_path.parent.name else base / epic_path
|
|
40
|
+
if candidate.exists():
|
|
41
|
+
epic_path = candidate
|
|
42
|
+
break
|
|
43
|
+
else:
|
|
44
|
+
epic_path = root / epic_path
|
|
45
|
+
|
|
46
|
+
if not epic_path.exists():
|
|
47
|
+
raise FileNotFoundError(f"Epic file not found: {epic_path}")
|
|
48
|
+
|
|
49
|
+
content = epic_path.read_text(encoding="utf-8")
|
|
50
|
+
|
|
51
|
+
# Determine epic number from content
|
|
52
|
+
epic_num_match = re.search(r"^#\s+Epic\s+(\d+):", content, re.MULTILINE)
|
|
53
|
+
if not epic_num_match:
|
|
54
|
+
epic_num_match = re.search(r"epic-(\d+)", epic_path.name, re.IGNORECASE)
|
|
55
|
+
if not epic_num_match:
|
|
56
|
+
raise ValueError(f"Could not determine epic number from {epic_path}")
|
|
57
|
+
epic_number = int(epic_num_match.group(1))
|
|
58
|
+
|
|
59
|
+
if report_path is None:
|
|
60
|
+
report_path = epic_path.parent / f"epic-{epic_number}-report.json"
|
|
61
|
+
else:
|
|
62
|
+
report_path = Path(report_path)
|
|
63
|
+
if not report_path.is_absolute():
|
|
64
|
+
report_path = root / report_path
|
|
65
|
+
|
|
66
|
+
if not report_path.exists():
|
|
67
|
+
raise FileNotFoundError(f"Report file not found: {report_path}")
|
|
68
|
+
|
|
69
|
+
report = json.loads(report_path.read_text(encoding="utf-8"))
|
|
70
|
+
stories = report.get("stories") or []
|
|
71
|
+
if not stories:
|
|
72
|
+
return
|
|
73
|
+
|
|
74
|
+
# Build map story_id -> status (done | failed | in_progress)
|
|
75
|
+
status_by_id: dict[str, str] = {}
|
|
76
|
+
for s in stories:
|
|
77
|
+
sid = s.get("story_id")
|
|
78
|
+
if sid:
|
|
79
|
+
status_by_id[sid] = (s.get("status") or "unknown").lower()
|
|
80
|
+
|
|
81
|
+
# For each story id, find the story block and add/replace **Execution status:**
|
|
82
|
+
def replace_or_add_status(match: re.Match[str]) -> str:
|
|
83
|
+
story_id = match.group(2) # e.g. "2.1"
|
|
84
|
+
title_line = match.group(1)
|
|
85
|
+
rest = match.group(3)
|
|
86
|
+
status = status_by_id.get(story_id, "not run")
|
|
87
|
+
status_line = f" **Execution status:** {status}\n"
|
|
88
|
+
existing = re.search(r"^(\s*\*\*Execution status:\*\*\s*)[^\n]*\n", rest, re.MULTILINE)
|
|
89
|
+
if existing:
|
|
90
|
+
rest = rest[: existing.start()] + status_line.strip() + "\n" + rest[existing.end() :]
|
|
91
|
+
else:
|
|
92
|
+
rest = status_line + rest
|
|
93
|
+
return title_line + rest
|
|
94
|
+
|
|
95
|
+
pattern = re.compile(
|
|
96
|
+
r"^(\d+\.\s*\*\*Story\s+(\d+\.\d+):[^*]*\*\*[^\n]*\n)(.*?)(?=^\d+\.\s*\*\*Story\s|\Z)",
|
|
97
|
+
re.MULTILINE | re.DOTALL,
|
|
98
|
+
)
|
|
99
|
+
new_content = pattern.sub(
|
|
100
|
+
lambda m: replace_or_add_status(m) if m.group(2) in status_by_id else m.group(0),
|
|
101
|
+
content,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
if new_content != content:
|
|
105
|
+
epic_path.write_text(new_content, encoding="utf-8")
|
|
@@ -202,8 +202,7 @@ class EpicOrchestrator:
|
|
|
202
202
|
workflow_yaml = self._create_story_workflow(story)
|
|
203
203
|
|
|
204
204
|
# Parse and execute workflow
|
|
205
|
-
|
|
206
|
-
workflow = parser.parse_workflow(workflow_yaml)
|
|
205
|
+
workflow = WorkflowParser.parse_yaml(workflow_yaml)
|
|
207
206
|
|
|
208
207
|
# Execute with quality gate loopback
|
|
209
208
|
iteration = 0
|