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.
- 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 +227 -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 +2337 -2118
- tapps_agents/workflow/direct_execution_fallback.py +16 -3
- tapps_agents/workflow/message_formatter.py +2 -1
- tapps_agents/workflow/models.py +38 -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.41.dist-info}/METADATA +5 -1
- {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.41.dist-info}/RECORD +58 -54
- 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.41.dist-info}/WHEEL +0 -0
- {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.41.dist-info}/entry_points.txt +0 -0
- {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.41.dist-info}/licenses/LICENSE +0 -0
- {tapps_agents-3.5.39.dist-info → tapps_agents-3.5.41.dist-info}/top_level.txt +0 -0
|
@@ -257,8 +257,15 @@ class DirectExecutionFallback:
|
|
|
257
257
|
if skill_command.startswith("@"):
|
|
258
258
|
skill_command = skill_command[1:]
|
|
259
259
|
|
|
260
|
-
# Split into parts
|
|
261
|
-
|
|
260
|
+
# Split into parts, preserving quoted strings
|
|
261
|
+
# Use shlex.split() to handle complex quotes properly
|
|
262
|
+
# Use posix=True to properly handle quote removal (even on Windows)
|
|
263
|
+
try:
|
|
264
|
+
parts = shlex.split(skill_command, posix=True)
|
|
265
|
+
except ValueError as e:
|
|
266
|
+
# Provide helpful error message with truncated command
|
|
267
|
+
cmd_preview = skill_command[:200] + "..." if len(skill_command) > 200 else skill_command
|
|
268
|
+
raise ValueError(f"Invalid skill command (malformed quotes): {cmd_preview}") from e
|
|
262
269
|
|
|
263
270
|
if not parts:
|
|
264
271
|
raise ValueError(f"Invalid skill command: {skill_command}")
|
|
@@ -282,7 +289,13 @@ class DirectExecutionFallback:
|
|
|
282
289
|
if command_name:
|
|
283
290
|
cli_parts.append(command_name)
|
|
284
291
|
|
|
285
|
-
|
|
292
|
+
# Safely quote arguments that may contain spaces or special characters
|
|
293
|
+
for arg in remaining_args:
|
|
294
|
+
# Check if arg needs quoting (contains spaces, quotes, or special chars)
|
|
295
|
+
if ' ' in arg or '"' in arg or "'" in arg:
|
|
296
|
+
cli_parts.append(shlex.quote(arg))
|
|
297
|
+
else:
|
|
298
|
+
cli_parts.append(arg)
|
|
286
299
|
|
|
287
300
|
return " ".join(cli_parts)
|
|
288
301
|
|
|
@@ -103,9 +103,10 @@ class MessageFormatter:
|
|
|
103
103
|
"""
|
|
104
104
|
emoji = self._get_emoji("block") if self.config.use_emoji else ""
|
|
105
105
|
intent_display = user_intent or "Implement feature"
|
|
106
|
+
path_display = Path(file_path).as_posix()
|
|
106
107
|
|
|
107
108
|
lines = [
|
|
108
|
-
f"{emoji}Direct file edit blocked: {
|
|
109
|
+
f"{emoji}Direct file edit blocked: {path_display}".strip(),
|
|
109
110
|
"",
|
|
110
111
|
f"Detected intent: {workflow.value} (confidence: {confidence:.0f}%)",
|
|
111
112
|
"",
|
tapps_agents/workflow/models.py
CHANGED
|
@@ -5,7 +5,7 @@ Workflow models - Data structures for workflow definitions.
|
|
|
5
5
|
from dataclasses import dataclass, field
|
|
6
6
|
from datetime import datetime
|
|
7
7
|
from enum import Enum
|
|
8
|
-
from typing import Any
|
|
8
|
+
from typing import Any, Literal
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class WorkflowType(Enum):
|
|
@@ -95,6 +95,43 @@ class StepExecution:
|
|
|
95
95
|
error: str | None = None
|
|
96
96
|
|
|
97
97
|
|
|
98
|
+
@dataclass
|
|
99
|
+
class StepResult:
|
|
100
|
+
"""Result of step execution with proper error handling.
|
|
101
|
+
|
|
102
|
+
This class represents the outcome of executing a workflow step,
|
|
103
|
+
including success/failure status, error details, and artifacts created.
|
|
104
|
+
Used by CursorExecutor to properly track step outcomes and halt
|
|
105
|
+
workflows when required steps fail.
|
|
106
|
+
"""
|
|
107
|
+
|
|
108
|
+
step_id: str
|
|
109
|
+
status: Literal["completed", "failed", "skipped"]
|
|
110
|
+
success: bool
|
|
111
|
+
duration: float
|
|
112
|
+
started_at: datetime
|
|
113
|
+
completed_at: datetime
|
|
114
|
+
error: str | None = None
|
|
115
|
+
error_traceback: str | None = None
|
|
116
|
+
artifacts: list[str] = field(default_factory=list)
|
|
117
|
+
skip_reason: str | None = None
|
|
118
|
+
|
|
119
|
+
def to_dict(self) -> dict[str, Any]:
|
|
120
|
+
"""Convert to dictionary for serialization."""
|
|
121
|
+
return {
|
|
122
|
+
"step_id": self.step_id,
|
|
123
|
+
"status": self.status,
|
|
124
|
+
"success": self.success,
|
|
125
|
+
"duration": self.duration,
|
|
126
|
+
"started_at": self.started_at.isoformat(),
|
|
127
|
+
"completed_at": self.completed_at.isoformat(),
|
|
128
|
+
"error": self.error,
|
|
129
|
+
"error_traceback": self.error_traceback,
|
|
130
|
+
"artifacts": self.artifacts,
|
|
131
|
+
"skip_reason": self.skip_reason,
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
98
135
|
@dataclass
|
|
99
136
|
class WorkflowState:
|
|
100
137
|
"""Workflow execution state."""
|
|
@@ -127,21 +127,60 @@ class ParallelStepExecutor:
|
|
|
127
127
|
"""
|
|
128
128
|
Find steps that are ready to execute (dependencies met).
|
|
129
129
|
|
|
130
|
+
This method respects the workflow's sequential 'next:' chain to prevent
|
|
131
|
+
premature step execution. A step is only ready if:
|
|
132
|
+
1. It's the 'next:' step from a completed step, OR it's the first step
|
|
133
|
+
2. All its artifact dependencies are met
|
|
134
|
+
|
|
135
|
+
This ensures workflows follow the intended sequence (enhance→planning→
|
|
136
|
+
implementation→review→testing→complete) instead of jumping to the final
|
|
137
|
+
step prematurely.
|
|
138
|
+
|
|
139
|
+
Fix for: Workflow Auto-Continuation Issue (BUG - Workflow stops after 1 step)
|
|
140
|
+
Root cause: Previous logic only checked artifact dependencies, allowing
|
|
141
|
+
'complete' step to execute immediately after 'enhance' because it had
|
|
142
|
+
no 'requires' dependencies.
|
|
143
|
+
|
|
130
144
|
Args:
|
|
131
145
|
workflow_steps: All workflow steps
|
|
132
146
|
completed_step_ids: Set of completed step IDs
|
|
133
147
|
running_step_ids: Set of currently running step IDs
|
|
134
148
|
available_artifacts: Set of available artifact names (from state.artifacts)
|
|
135
|
-
|
|
136
|
-
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
List of steps ready to execute
|
|
137
152
|
"""
|
|
138
153
|
ready: list[WorkflowStep] = []
|
|
139
154
|
artifacts = available_artifacts or set()
|
|
140
155
|
|
|
156
|
+
# Build set of next steps from completed steps' next: fields
|
|
157
|
+
next_step_ids: set[str] = set()
|
|
158
|
+
for step in workflow_steps:
|
|
159
|
+
if step.id in completed_step_ids and step.next:
|
|
160
|
+
next_step_ids.add(step.next)
|
|
161
|
+
|
|
162
|
+
# If no completed steps yet, first step is ready
|
|
163
|
+
if not completed_step_ids:
|
|
164
|
+
first_step = workflow_steps[0] if workflow_steps else None
|
|
165
|
+
if first_step and first_step.id not in running_step_ids:
|
|
166
|
+
# Still check artifact dependencies for first step
|
|
167
|
+
if first_step.requires:
|
|
168
|
+
all_met = all(req in artifacts for req in first_step.requires)
|
|
169
|
+
if all_met:
|
|
170
|
+
return [first_step]
|
|
171
|
+
else:
|
|
172
|
+
return [first_step]
|
|
173
|
+
return []
|
|
174
|
+
|
|
175
|
+
# Find steps that are in the next_step_ids set (sequential progression)
|
|
141
176
|
for step in workflow_steps:
|
|
142
177
|
if step.id in completed_step_ids or step.id in running_step_ids:
|
|
143
178
|
continue
|
|
144
179
|
|
|
180
|
+
# Must be in the next_step_ids set (respects sequential workflow chain)
|
|
181
|
+
if step.id not in next_step_ids:
|
|
182
|
+
continue
|
|
183
|
+
|
|
145
184
|
# Check if all required artifacts exist and are available
|
|
146
185
|
if step.requires:
|
|
147
186
|
all_met = all(req in artifacts for req in step.requires)
|
|
@@ -342,7 +381,7 @@ class ParallelStepExecutor:
|
|
|
342
381
|
tasks_map[task] = step
|
|
343
382
|
|
|
344
383
|
# All tasks completed successfully - collect results
|
|
345
|
-
for task
|
|
384
|
+
for task in tasks_map:
|
|
346
385
|
result = await task
|
|
347
386
|
results.append(result)
|
|
348
387
|
|
|
@@ -416,7 +455,7 @@ class ParallelStepExecutor:
|
|
|
416
455
|
|
|
417
456
|
# Re-raise the first exception for upstream handling
|
|
418
457
|
if eg.exceptions:
|
|
419
|
-
raise eg.exceptions[0]
|
|
458
|
+
raise eg.exceptions[0] from None
|
|
420
459
|
|
|
421
460
|
# Sort by step.id for deterministic ordering
|
|
422
461
|
results.sort(key=lambda r: r.step.id)
|