tapps-agents 3.5.39__py3-none-any.whl → 3.5.41__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.
Files changed (71) hide show
  1. tapps_agents/__init__.py +2 -2
  2. tapps_agents/agents/enhancer/agent.py +2728 -2728
  3. tapps_agents/agents/implementer/agent.py +35 -13
  4. tapps_agents/agents/reviewer/agent.py +43 -10
  5. tapps_agents/agents/reviewer/scoring.py +59 -68
  6. tapps_agents/agents/reviewer/tools/__init__.py +24 -0
  7. tapps_agents/agents/reviewer/tools/ruff_grouping.py +250 -0
  8. tapps_agents/agents/reviewer/tools/scoped_mypy.py +284 -0
  9. tapps_agents/beads/__init__.py +11 -0
  10. tapps_agents/beads/hydration.py +213 -0
  11. tapps_agents/beads/specs.py +206 -0
  12. tapps_agents/cli/commands/health.py +19 -3
  13. tapps_agents/cli/commands/simple_mode.py +842 -676
  14. tapps_agents/cli/commands/task.py +227 -0
  15. tapps_agents/cli/commands/top_level.py +13 -0
  16. tapps_agents/cli/main.py +658 -651
  17. tapps_agents/cli/parsers/top_level.py +1978 -1881
  18. tapps_agents/core/config.py +1622 -1622
  19. tapps_agents/core/init_project.py +3012 -2897
  20. tapps_agents/epic/markdown_sync.py +105 -0
  21. tapps_agents/epic/orchestrator.py +1 -2
  22. tapps_agents/epic/parser.py +427 -423
  23. tapps_agents/experts/adaptive_domain_detector.py +0 -2
  24. tapps_agents/experts/knowledge/api-design-integration/api-security-patterns.md +15 -15
  25. tapps_agents/experts/knowledge/api-design-integration/external-api-integration.md +19 -44
  26. tapps_agents/health/checks/outcomes.backup_20260204_064058.py +324 -0
  27. tapps_agents/health/checks/outcomes.backup_20260204_064256.py +324 -0
  28. tapps_agents/health/checks/outcomes.backup_20260204_064600.py +324 -0
  29. tapps_agents/health/checks/outcomes.py +134 -46
  30. tapps_agents/health/orchestrator.py +12 -4
  31. tapps_agents/hooks/__init__.py +33 -0
  32. tapps_agents/hooks/config.py +140 -0
  33. tapps_agents/hooks/events.py +135 -0
  34. tapps_agents/hooks/executor.py +128 -0
  35. tapps_agents/hooks/manager.py +143 -0
  36. tapps_agents/session/__init__.py +19 -0
  37. tapps_agents/session/manager.py +256 -0
  38. tapps_agents/simple_mode/code_snippet_handler.py +382 -0
  39. tapps_agents/simple_mode/intent_parser.py +29 -4
  40. tapps_agents/simple_mode/orchestrators/base.py +185 -59
  41. tapps_agents/simple_mode/orchestrators/build_orchestrator.py +2667 -2642
  42. tapps_agents/simple_mode/orchestrators/fix_orchestrator.py +2 -2
  43. tapps_agents/simple_mode/workflow_suggester.py +37 -3
  44. tapps_agents/workflow/agent_handlers/implementer_handler.py +18 -3
  45. tapps_agents/workflow/cursor_executor.py +2337 -2118
  46. tapps_agents/workflow/direct_execution_fallback.py +16 -3
  47. tapps_agents/workflow/message_formatter.py +2 -1
  48. tapps_agents/workflow/models.py +38 -1
  49. tapps_agents/workflow/parallel_executor.py +43 -4
  50. tapps_agents/workflow/parser.py +375 -357
  51. tapps_agents/workflow/rules_generator.py +337 -337
  52. tapps_agents/workflow/skill_invoker.py +9 -3
  53. {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.41.dist-info}/METADATA +5 -1
  54. {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.41.dist-info}/RECORD +58 -54
  55. tapps_agents/agents/analyst/SKILL.md +0 -85
  56. tapps_agents/agents/architect/SKILL.md +0 -80
  57. tapps_agents/agents/debugger/SKILL.md +0 -66
  58. tapps_agents/agents/designer/SKILL.md +0 -78
  59. tapps_agents/agents/documenter/SKILL.md +0 -95
  60. tapps_agents/agents/enhancer/SKILL.md +0 -189
  61. tapps_agents/agents/implementer/SKILL.md +0 -117
  62. tapps_agents/agents/improver/SKILL.md +0 -55
  63. tapps_agents/agents/ops/SKILL.md +0 -64
  64. tapps_agents/agents/orchestrator/SKILL.md +0 -238
  65. tapps_agents/agents/planner/story_template.md +0 -37
  66. tapps_agents/agents/reviewer/templates/quality-dashboard.html.j2 +0 -150
  67. tapps_agents/agents/tester/SKILL.md +0 -71
  68. {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.41.dist-info}/WHEEL +0 -0
  69. {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.41.dist-info}/entry_points.txt +0 -0
  70. {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.41.dist-info}/licenses/LICENSE +0 -0
  71. {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.41.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
- parser = WorkflowParser()
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