etch-loop 0.4.3__tar.gz → 0.4.5__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.5}/PKG-INFO +1 -1
- {etch_loop-0.4.3 → etch_loop-0.4.5}/pyproject.toml +1 -1
- etch_loop-0.4.5/src/etch/__init__.py +1 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/analyze.py +25 -13
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/signals.py +26 -44
- etch_loop-0.4.5/src/etch/templates/RUN.md +32 -0
- etch_loop-0.4.3/src/etch/__init__.py +0 -1
- etch_loop-0.4.3/src/etch/templates/RUN.md +0 -20
- {etch_loop-0.4.3 → etch_loop-0.4.5}/.github/workflows/workflow.yml +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/README.md +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/agent.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/cli.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/display.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/git.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/loop.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/prompt.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/report.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/templates/BREAK.md +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/templates/ETCH.md +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/src/etch/templates/SCAN.md +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/tests/__init__.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/tests/test_git.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/tests/test_loop.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/tests/test_prompt.py +0 -0
- {etch_loop-0.4.3 → etch_loop-0.4.5}/tests/test_signals.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.4.5"
|
|
@@ -270,26 +270,38 @@ def build_run_md(info: dict) -> str:
|
|
|
270
270
|
else:
|
|
271
271
|
cmd_list = "- (detect and run the appropriate build/test command for this project)"
|
|
272
272
|
|
|
273
|
-
return f"""# RUN —
|
|
273
|
+
return f"""# RUN — test writer and build validator
|
|
274
274
|
|
|
275
|
-
You are a
|
|
275
|
+
You are a test engineer. The fixer has just made changes. Your job is to write tests for what was changed, then run the full suite to confirm everything works.
|
|
276
276
|
|
|
277
|
-
##
|
|
277
|
+
## Your mission
|
|
278
|
+
|
|
279
|
+
1. **Write or update tests** — look at what the fixer changed and write targeted tests covering:
|
|
280
|
+
- The specific edge cases that were fixed
|
|
281
|
+
- Boundary conditions around the changed code
|
|
282
|
+
- Any regression paths that could break silently
|
|
283
|
+
Write tests in the project's existing test style and location.
|
|
284
|
+
|
|
285
|
+
2. **Run the test suite** — run the full build and test commands to confirm everything passes.
|
|
286
|
+
|
|
287
|
+
## Build and test commands
|
|
278
288
|
|
|
279
289
|
{cmd_list}
|
|
280
290
|
|
|
281
291
|
## Rules
|
|
282
292
|
|
|
283
|
-
1.
|
|
284
|
-
2.
|
|
285
|
-
|
|
286
|
-
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
+
1. You MAY edit test files — that is your job
|
|
294
|
+
2. Do NOT touch production code — only tests
|
|
295
|
+
3. After running, report clearly:
|
|
296
|
+
- If ALL tests pass:
|
|
297
|
+
- `ETCH_SUMMARY: <e.g. "wrote 4 tests, all 51 passed">`
|
|
298
|
+
- `ETCH_ALL_CLEAR`
|
|
299
|
+
- If ANY test fails due to a bug in the production code:
|
|
300
|
+
- `ETCH_SUMMARY: <what failed and why>`
|
|
301
|
+
- Include the relevant error output
|
|
302
|
+
- `ETCH_ISSUES_FOUND`
|
|
303
|
+
- If tests fail because the tests themselves are wrong (flawed test logic):
|
|
304
|
+
- Fix the test and re-run before reporting
|
|
293
305
|
"""
|
|
294
306
|
|
|
295
307
|
|
|
@@ -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("#"):
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# RUN — test writer and build validator
|
|
2
|
+
|
|
3
|
+
You are a test engineer. The fixer has just made changes. Your job is to write tests for what was changed, then run the full suite to confirm everything works.
|
|
4
|
+
|
|
5
|
+
## Your mission
|
|
6
|
+
|
|
7
|
+
1. **Write or update tests** — look at what the fixer changed and write targeted tests covering:
|
|
8
|
+
- The specific edge cases that were fixed
|
|
9
|
+
- Boundary conditions around the changed code
|
|
10
|
+
- Any regression paths that could break silently
|
|
11
|
+
Write tests in the project's existing test style and location.
|
|
12
|
+
|
|
13
|
+
2. **Run the test suite** — run the full build and test commands to confirm everything passes.
|
|
14
|
+
|
|
15
|
+
## Build and test commands
|
|
16
|
+
|
|
17
|
+
[configured by etch init]
|
|
18
|
+
|
|
19
|
+
## Rules
|
|
20
|
+
|
|
21
|
+
1. You MAY edit test files — that is your job
|
|
22
|
+
2. Do NOT touch production code — only tests
|
|
23
|
+
3. After running, report clearly:
|
|
24
|
+
- If ALL tests pass:
|
|
25
|
+
- `ETCH_SUMMARY: <e.g. "wrote 4 tests, all 51 passed">`
|
|
26
|
+
- `ETCH_ALL_CLEAR`
|
|
27
|
+
- If ANY test fails due to a bug in the production code:
|
|
28
|
+
- `ETCH_SUMMARY: <what failed and why>`
|
|
29
|
+
- Include the relevant error output
|
|
30
|
+
- `ETCH_ISSUES_FOUND`
|
|
31
|
+
- If tests fail because the tests themselves are wrong (flawed test logic):
|
|
32
|
+
- Fix the test and re-run before reporting
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.4.3"
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
# RUN — build and test validation
|
|
2
|
-
|
|
3
|
-
You are a build validator. The fixer has made changes. Your job is to run the project's build and test suite to confirm everything still works.
|
|
4
|
-
|
|
5
|
-
## Commands to run
|
|
6
|
-
|
|
7
|
-
[configured by etch init]
|
|
8
|
-
|
|
9
|
-
## Rules
|
|
10
|
-
|
|
11
|
-
1. Run each command and observe the output
|
|
12
|
-
2. If ALL commands pass:
|
|
13
|
-
- Write `ETCH_SUMMARY: <e.g. "all 47 tests passed">`
|
|
14
|
-
- Write `ETCH_ALL_CLEAR`
|
|
15
|
-
3. If ANY command fails:
|
|
16
|
-
- Write `ETCH_SUMMARY: <what failed, e.g. "3 tests failed in test_auth.py — TypeError on line 42">`
|
|
17
|
-
- Include the relevant error output so the fixer can diagnose it
|
|
18
|
-
- Write `ETCH_ISSUES_FOUND`
|
|
19
|
-
|
|
20
|
-
Do not fix anything — only run and report.
|
|
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
|