etch-loop 0.5.1__tar.gz → 0.5.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: etch-loop
3
- Version: 0.5.1
3
+ Version: 0.5.2
4
4
  Summary: Run Claude Code in a fix-break loop until your codebase is clean
5
5
  License: MIT
6
6
  Requires-Python: >=3.11
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "etch-loop"
3
- version = "0.5.1"
3
+ version = "0.5.2"
4
4
  requires-python = ">=3.11"
5
5
  description = "Run Claude Code in a fix-break loop until your codebase is clean"
6
6
  readme = "README.md"
@@ -0,0 +1 @@
1
+ __version__ = "0.5.2"
@@ -67,9 +67,11 @@ def run(
67
67
  stdin_writer.join(timeout=30)
68
68
  if stdin_writer.is_alive():
69
69
  process.kill()
70
+ process.wait()
70
71
  raise AgentError("Timed out writing prompt to claude stdin")
71
72
  if stdin_exc:
72
73
  process.kill()
74
+ process.wait()
73
75
  raise AgentError(f"Failed to write prompt to claude stdin: {stdin_exc[0]}") from stdin_exc[0]
74
76
 
75
77
  output_lines: list[str] = []
@@ -96,6 +98,7 @@ def run(
96
98
  reader.join(timeout=timeout)
97
99
  if reader.is_alive():
98
100
  process.kill()
101
+ process.wait()
99
102
  raise AgentError("claude subprocess timed out (output reader still running)")
100
103
 
101
104
  stderr_reader.join(timeout=10)
@@ -104,6 +107,7 @@ def run(
104
107
  process.wait(timeout=10)
105
108
  except subprocess.TimeoutExpired:
106
109
  process.kill()
110
+ process.wait()
107
111
  raise AgentError("claude subprocess timed out waiting for exit")
108
112
 
109
113
  stderr_output = "".join(stderr_lines).strip()
@@ -69,7 +69,7 @@ def commit(message: str, paths: list[str] | None = None) -> None:
69
69
  raise GitError("Commit message must not be empty.")
70
70
 
71
71
  # Stage all changes (or specific paths)
72
- add_cmd = ["git", "add"] + (paths if paths else ["-u"])
72
+ add_cmd = ["git", "add"] + (paths if paths is not None else ["--all"])
73
73
  try:
74
74
  add_result = subprocess.run(
75
75
  add_cmd,
@@ -84,8 +84,18 @@ def run(
84
84
  # ── Scanner phase ─────────────────────────────────────────────────
85
85
  disp.start_phase("scanner")
86
86
  scanner_start = time.monotonic()
87
+ # Give the scanner any unresolved breaker findings as extra hints,
88
+ # so it can verify whether those areas are still broken.
89
+ effective_scan_text = scan_text
90
+ if last_breaker_output:
91
+ effective_scan_text += (
92
+ f"\n\n## Unresolved areas from previous adversarial review\n\n"
93
+ f"{last_breaker_output.strip()}\n\n"
94
+ f"Pay special attention to these spots — confirm whether each is "
95
+ f"still a genuine bug or has already been fixed.\n"
96
+ )
87
97
  try:
88
- scanner_output = agent.run(scan_text, verbose=verbose)
98
+ scanner_output = agent.run(effective_scan_text, verbose=verbose)
89
99
  except AgentError as exc:
90
100
  disp.finish_phase("scanner", status="error", detail=str(exc),
91
101
  duration=time.monotonic() - scanner_start, success=False)
@@ -124,17 +134,13 @@ def run(
124
134
  iter_entry["scanner"] = {"status": "issues found", "detail": scanner_detail}
125
135
 
126
136
  # ── Build fixer prompt ────────────────────────────────────────────
137
+ # Only the scanner's confirmed findings go to the fixer — the scanner
138
+ # already re-checked any breaker issues and reported only real ones.
127
139
  fixer_prompt = prompt_text
128
140
  fixer_prompt += (
129
141
  f"\n\n## Scanner findings\n\n{scanner_output.strip()}\n\n"
130
142
  f"Fix these specific issues.\n"
131
143
  )
132
- if last_breaker_output:
133
- fixer_prompt += (
134
- f"\n\n## Breaker findings from previous iteration\n\n"
135
- f"{last_breaker_output.strip()}\n\n"
136
- f"Also address these if not already covered above.\n"
137
- )
138
144
 
139
145
  # ── Fixer phase ───────────────────────────────────────────────────
140
146
  disp.start_phase("fixer")
@@ -1 +0,0 @@
1
- __version__ = "0.5.1"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes