unfuck edit workflow.
This commit is contained in:
+42
-38
@@ -1,16 +1,20 @@
|
||||
# Manual Slop Edit Tool Workflow
|
||||
|
||||
## The Problem
|
||||
|
||||
The `manual-slop_edit_file` tool requires **exact string matches** (character-for-character). Whitespace differences cause failures. The Python file uses **1-space indentation**.
|
||||
|
||||
## The Rules
|
||||
|
||||
### 1. ALWAYS Use Small, Incremental Edits
|
||||
|
||||
**WRONG:** Replace large blocks (50+ lines)
|
||||
**RIGHT:** Replace 3-10 lines at a time, verify, repeat
|
||||
|
||||
### 2. Verify Before Editing
|
||||
|
||||
Before ANY edit to a function you haven't touched recently:
|
||||
|
||||
```
|
||||
1. Run: git checkout -- src/gui_2.py
|
||||
2. Run: py_check_syntax on src/gui_2.py
|
||||
@@ -18,11 +22,13 @@ Before ANY edit to a function you haven't touched recently:
|
||||
```
|
||||
|
||||
### 3. Reading Before Editing (CRITICAL)
|
||||
|
||||
- Use `get_file_slice` to get the EXACT text including all whitespace
|
||||
- Copy text directly from the tool output - do NOT reformat
|
||||
- If using get_definition, verify the text matches before editing
|
||||
|
||||
### 4. The Edit Tool Parameters (snake_case)
|
||||
|
||||
```python
|
||||
{
|
||||
"path": "src/gui_2.py", # Required: file path
|
||||
@@ -33,6 +39,7 @@ Before ANY edit to a function you haven't touched recently:
|
||||
```
|
||||
|
||||
### 5. 1-Space Indentation in Python
|
||||
|
||||
- Class methods: ` def` (0 spaces, then 1)
|
||||
- Method body: ` ` (2 spaces total)
|
||||
- Nested blocks: ` ` (3 spaces total)
|
||||
@@ -41,14 +48,17 @@ Before ANY edit to a function you haven't touched recently:
|
||||
### 6. The Decorator-Orphan Pitfall (Added 2026-06-07)
|
||||
|
||||
When inserting new methods **before an existing `@property` def**:
|
||||
```
|
||||
|
||||
```python
|
||||
@property
|
||||
def perf_profiling_enabled(self) -> bool:
|
||||
...
|
||||
```
|
||||
|
||||
If you anchor on `def perf_profiling_enabled` and insert before it, the `@property` decorator on the line above is left orphaned on the line right before YOUR new method. Now `@property` decorates your method (which is no longer a property), and the original setter `@perf_profiling_enabled.setter` blows up at import with `'function' object has no attribute 'setter'`.
|
||||
|
||||
**Fix:** Anchor on a non-decorated landmark, or include the decorator in the replacement:
|
||||
|
||||
- `old_string` = ` self._init_actions()\n\n @property\n def perf_profiling_enabled`
|
||||
- `new_string` = ` self._init_actions()\n\n def your_new(...)\n ...\n\n @property\n def perf_profiling_enabled`
|
||||
|
||||
@@ -57,6 +67,7 @@ This keeps the `@property` attached to its original method.
|
||||
### 7. ast.parse() Is Not Enough (Added 2026-06-07)
|
||||
|
||||
`py_check_syntax` only confirms `ast.parse()` succeeds. Semantic errors (wrong decorator targets, wrong base class, wrong attribute, missing `self`) are NOT caught. After any multi-line edit, ALWAYS:
|
||||
|
||||
1. Import the module: `python -c "from src.app_controller import AppController"`
|
||||
2. Instantiate the class
|
||||
3. Call the new method in the way it's expected to be called (`ctrl.foo_ts` for a property, `ctrl.foo_ts()` for a method)
|
||||
@@ -67,39 +78,32 @@ This keeps the `@property` attached to its original method.
|
||||
|
||||
## Step-by-Step Workflow for gui_2.py
|
||||
|
||||
### Before ANY edit:
|
||||
```powershell
|
||||
git checkout -- src/gui_2.py
|
||||
```
|
||||
|
||||
### Check current state:
|
||||
|
||||
```powershell
|
||||
py_check_syntax path=src/gui_2.py
|
||||
get_file_slice path=src/gui_2.py start_line=X end_line=Y
|
||||
```
|
||||
|
||||
### For each edit:
|
||||
|
||||
1. Make the smallest possible change (3-10 lines)
|
||||
2. Run `py_check_syntax` to verify
|
||||
3. If syntax error, immediately `git checkout -- src/gui_2.py`
|
||||
3. If syntax error, immediately report to the user to address.
|
||||
4. Only proceed if syntax is OK
|
||||
|
||||
### If edit fails with "old_string not found":
|
||||
|
||||
- The text you're trying to replace doesn't EXACTLY match
|
||||
- Use `get_file_slice` to get the exact text
|
||||
- Copy it character-for-character including whitespace
|
||||
- Try again with exact match
|
||||
|
||||
### If syntax error after edit:
|
||||
```powershell
|
||||
git checkout -- src/gui_2.py
|
||||
```
|
||||
Then try again with smaller edit.
|
||||
|
||||
## Alternative: Update Definition Approach
|
||||
|
||||
For large function rewrites, use `py_update_definition`:
|
||||
```
|
||||
|
||||
```md
|
||||
name: function_name
|
||||
path: src/gui_2.py
|
||||
new_content: complete new function source
|
||||
@@ -110,48 +114,48 @@ This replaces the entire function at once using AST detection.
|
||||
## Context Composition Requirements
|
||||
|
||||
### Current Broken State
|
||||
|
||||
Files & Media works. Context Composition needs:
|
||||
|
||||
1. Add state tracking at start of function:
|
||||
```python
|
||||
if not hasattr(self, 'ctx_files_open'):
|
||||
self.ctx_files_open = True
|
||||
if not hasattr(self, 'ctx_shots_open'):
|
||||
self.ctx_shots_open = True
|
||||
```
|
||||
|
||||
```python
|
||||
if not hasattr(self, 'ctx_files_open'):
|
||||
self.ctx_files_open = True
|
||||
if not hasattr(self, 'ctx_shots_open'):
|
||||
self.ctx_shots_open = True
|
||||
```
|
||||
|
||||
2. Files section with collapsing header and child window:
|
||||
```python
|
||||
if imgui.collapsing_header("Files", self.ctx_files_open):
|
||||
imgui.begin_child("ctx_files_child", imgui.ImVec2(-1, 200), True)
|
||||
# table code here
|
||||
imgui.end_child()
|
||||
```
|
||||
|
||||
```python
|
||||
if imgui.collapsing_header("Files", self.ctx_files_open):
|
||||
imgui.begin_child("ctx_files_child", imgui.ImVec2(-1, 200), True)
|
||||
# table code here
|
||||
imgui.end_child()
|
||||
```
|
||||
|
||||
3. Screenshots section with collapsing header and child window:
|
||||
```python
|
||||
if imgui.collapsing_header("Screenshots", self.ctx_shots_open):
|
||||
imgui.begin_child("ctx_shots_child", imgui.ImVec2(-1, 100), True)
|
||||
# screenshot list here
|
||||
imgui.end_child()
|
||||
```
|
||||
|
||||
```python
|
||||
if imgui.collapsing_header("Screenshots", self.ctx_shots_open):
|
||||
imgui.begin_child("ctx_shots_child", imgui.ImVec2(-1, 100), True)
|
||||
# screenshot list here
|
||||
imgui.end_child()
|
||||
```
|
||||
|
||||
4. Fixed presets bar with push_item_width(150) on the combo
|
||||
|
||||
5. Remove the batch action bar entirely (Full/Agg/Sig/Def/None/Sel All/Del buttons)
|
||||
|
||||
## Key Files
|
||||
|
||||
- `src/gui_2.py` - Main GUI (1-space indentation, CRLF)
|
||||
- `src/models.py` - Data models including FileItem
|
||||
- Context Composition function: line ~2748
|
||||
|
||||
## Test Command
|
||||
|
||||
```powershell
|
||||
uv run sloppy.py
|
||||
```
|
||||
|
||||
## If Everything Goes Wrong
|
||||
```powershell
|
||||
git checkout -- src/gui_2.py
|
||||
git checkout -- src/models.py
|
||||
```
|
||||
Reference in New Issue
Block a user