etch-loop 0.4.3__tar.gz → 0.4.4__tar.gz
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.
- {etch_loop-0.4.3 → etch_loop-0.4.4}/PKG-INFO +1 -1
- {etch_loop-0.4.3 → etch_loop-0.4.4}/pyproject.toml +1 -1
- etch_loop-0.4.4/src/etch/__init__.py +1 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/signals.py +26 -44
- etch_loop-0.4.3/src/etch/__init__.py +0 -1
- {etch_loop-0.4.3 → etch_loop-0.4.4}/.github/workflows/workflow.yml +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/README.md +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/agent.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/analyze.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/cli.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/display.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/git.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/loop.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/prompt.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/report.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/templates/BREAK.md +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/templates/ETCH.md +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/templates/RUN.md +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/src/etch/templates/SCAN.md +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/tests/__init__.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/tests/test_git.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/tests/test_loop.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/tests/test_prompt.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.4}/tests/test_signals.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.4.4"
|
|
@@ -6,36 +6,30 @@ _PUNCTUATION_ONLY = set("-=*_`~><|")
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def parse(output: str) -> str:
|
|
9
|
-
"""Parse
|
|
9
|
+
"""Parse agent output for control tokens.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
Tokens must appear alone on their own line (after stripping whitespace
|
|
12
|
+
and backtick wrappers). This prevents false matches when agents quote the
|
|
13
|
+
token strings in explanations like `ETCH_ALL_CLEAR`.
|
|
14
|
+
|
|
15
|
+
The first matching line wins. If neither token is found, returns "issues"
|
|
16
|
+
as a fail-safe.
|
|
14
17
|
|
|
15
18
|
Returns:
|
|
16
|
-
"clear" — ETCH_ALL_CLEAR found
|
|
17
|
-
"issues" — ETCH_ISSUES_FOUND found
|
|
19
|
+
"clear" — ETCH_ALL_CLEAR found on its own line first
|
|
20
|
+
"issues" — ETCH_ISSUES_FOUND found on its own line first, or no token found
|
|
18
21
|
"""
|
|
19
22
|
if not isinstance(output, str):
|
|
20
23
|
return "issues"
|
|
21
24
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if clear_pos == -1:
|
|
30
|
-
return "issues"
|
|
31
|
-
|
|
32
|
-
if issues_pos == -1:
|
|
33
|
-
return "clear"
|
|
25
|
+
for line in output.splitlines():
|
|
26
|
+
stripped = line.strip().strip("`").strip()
|
|
27
|
+
if stripped == _TOKEN_CLEAR:
|
|
28
|
+
return "clear"
|
|
29
|
+
if stripped == _TOKEN_ISSUES:
|
|
30
|
+
return "issues"
|
|
34
31
|
|
|
35
|
-
#
|
|
36
|
-
if clear_pos < issues_pos:
|
|
37
|
-
return "clear"
|
|
38
|
-
return "issues"
|
|
32
|
+
return "issues" # fail-safe: no token found
|
|
39
33
|
|
|
40
34
|
|
|
41
35
|
def extract_commit_message(output: str, fallback: str) -> str:
|
|
@@ -93,35 +87,23 @@ def extract_summary(output: str) -> str:
|
|
|
93
87
|
|
|
94
88
|
|
|
95
89
|
def extract_finding(output: str) -> str:
|
|
96
|
-
"""Extract
|
|
90
|
+
"""Extract the last meaningful line before the signal token line.
|
|
97
91
|
|
|
98
|
-
|
|
99
|
-
the
|
|
92
|
+
Scans line by line, stops at the first line that IS a token (exact match).
|
|
93
|
+
Returns the last non-empty, non-header line before that point.
|
|
100
94
|
"""
|
|
101
95
|
if not isinstance(output, str) or not output.strip():
|
|
102
96
|
return ""
|
|
103
97
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if clear_pos >= 0 and issues_pos >= 0:
|
|
111
|
-
cutoff = min(clear_pos, issues_pos)
|
|
112
|
-
elif clear_pos >= 0:
|
|
113
|
-
cutoff = clear_pos
|
|
114
|
-
elif issues_pos >= 0:
|
|
115
|
-
cutoff = issues_pos
|
|
116
|
-
|
|
117
|
-
text_before = output[:cutoff].strip()
|
|
118
|
-
if not text_before:
|
|
119
|
-
return ""
|
|
98
|
+
lines_before: list[str] = []
|
|
99
|
+
for line in output.splitlines():
|
|
100
|
+
stripped = line.strip().strip("`").strip()
|
|
101
|
+
if stripped in (_TOKEN_CLEAR, _TOKEN_ISSUES):
|
|
102
|
+
break
|
|
103
|
+
lines_before.append(line)
|
|
120
104
|
|
|
121
|
-
|
|
122
|
-
for line in reversed(lines):
|
|
105
|
+
for line in reversed(lines_before):
|
|
123
106
|
stripped = line.strip().strip("`").strip()
|
|
124
|
-
# Skip empty lines, markdown headers, separator lines, and bare punctuation
|
|
125
107
|
if not stripped:
|
|
126
108
|
continue
|
|
127
109
|
if stripped.startswith("#"):
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.4.3"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|