File size: 8,465 Bytes
383cb38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#!/usr/bin/env python3
"""
AST-based auto-fix script for indentation errors in Atom backend.

This script uses the tokenize module to precisely fix indentation issues
where `with get_db_session() as db:` is followed by an incorrectly indented `try:` block.
"""

import io
import os
from pathlib import Path
import sys
import tokenize
from typing import List, Tuple

# Backend directory
BACKEND_DIR = Path("/Users/rushiparikh/projects/atom/backend")


def fix_file_tokens(filepath: Path) -> Tuple[bool, str]:
    """
    Fix indentation issues using token-level processing.
    Returns (success, message)
    """
    try:
        with open(filepath, 'rb') as f:
            tokens = list(tokenize.tokenize(f.readline))

        # Convert tokens back to source with fixes
        result_tokens = []
        i = 0

        while i < len(tokens):
            token = tokens[i]

            # Look for pattern: WITH_KEYWORD ('with') followed by NAME ('get_db_session')
            # then incorrectly indented try block
            if token.type == tokenize.NAME and token.string == 'with':
                # Check if this is our pattern
                j = i
                found_get_db_session = False
                found_try_at_wrong_indent = False

                # Look ahead for get_db_session
                while j < len(tokens) and tokens[j].type != tokenize.NEWLINE:
                    if tokens[j].type == tokenize.NAME and tokens[j].string == 'get_db_session':
                        found_get_db_session = True
                    j += 1

                if found_get_db_session:
                    # Now look for the try statement
                    # Skip to next line
                    while j < len(tokens) and tokens[j].type in (tokenize.NEWLINE, tokenize.NL, tokenize.COMMENT):
                        j += 1

                    # Check if next line is 'try' with insufficient indentation
                    if j < len(tokens) and tokens[j].type == tokenize.NAME and tokens[j].string == 'try':
                        # Check indentation - should be more than 'with' statement
                        with_indent = tokens[i].start[1]
                        try_indent = tokens[j].start[1]

                        if try_indent <= with_indent + 1:
                            # Found the issue! We need to increase try indentation
                            # Create a new token with proper indentation
                            new_start = (tokens[j].start[0], with_indent + 4)
                            if tokens[j].end[1] == tokens[j].start[1]:  # Single token
                                new_end = (tokens[j].end[0], with_indent + 4 + len(tokens[j].string))
                            else:
                                new_end = tokens[j].end
                                new_end = (new_end[0], new_end[1] + (with_indent + 4 - try_indent))

                            fixed_token = tokenize.TokenInfo(
                                type=tokens[j].type,
                                string=tokens[j].string,
                                start=new_start,
                                end=new_end,
                                line=tokens[j].line
                            )
                            result_tokens.append(fixed_token)
                            i = j + 1
                            continue

            result_tokens.append(token)
            i += 1

        # Reconstruct source from tokens
        source_lines = []
        current_line = 1
        current_col = 0

        for token in result_tokens:
            if token.type == tokenize.ENCODING:
                continue

            # Handle line breaks
            while current_line < token.start[0]:
                source_lines.append('\n')
                current_line += 1
                current_col = 0

            # Handle column spacing
            while current_col < token.start[1]:
                source_lines.append(' ')
                current_col += 1

            # Add the token string
            if token.type != tokenize.NEWLINE and token.type != tokenize.NL:
                source_lines.append(token.string)
                current_col += len(token.string)
            else:
                source_lines.append('\n')
                current_line += 1
                current_col = 0

        # Join and write back
        fixed_content = ''.join(source_lines)

        with open(filepath, 'w') as f:
            f.write(fixed_content)

        return True, "Fixed indentation"

    except Exception as e:
        return False, f"Error: {str(e)}"


def fix_simple_pattern(filepath: Path) -> bool:
    """
    Simple line-based fix for the specific pattern.
    """
    try:
        with open(filepath, 'r') as f:
            lines = f.readlines()

        new_lines = []
        i = 0
        fixes = 0

        while i < len(lines):
            line = lines[i]

            # Check for pattern: "with get_db_session() as db:"
            if 'with get_db_session() as db:' in line:
                # Get indentation
                indent = len(line) - len(line.lstrip())
                new_lines.append(line)
                i += 1

                # Check next line for "try:" at wrong indentation
                if i < len(lines):
                    next_line = lines[i]
                    next_indent = len(next_line) - len(next_line.lstrip())

                    # If "try:" is at same or less indentation than "with"
                    if 'try:' in next_line and next_indent <= indent + 1:
                        # Fix indentation
                        fixed_try = ' ' * (indent + 4) + 'try:' + '\n'
                        new_lines.append(fixed_try)
                        fixes += 1
                        i += 1

                        # Continue with remaining lines
                        while i < len(lines):
                            new_lines.append(lines[i])
                            i += 1
                        break

            new_lines.append(line)
            i += 1

        if fixes > 0:
            with open(filepath, 'w') as f:
                f.writelines(new_lines)
            return True

        return False

    except Exception as e:
        print(f"  ✗ Error: {e}")
        return False


def scan_and_fix():
    """Scan all Python files and fix indentation errors."""
    print("=" * 70)
    print("Auto-fixing indentation errors in Atom backend")
    print("=" * 70)
    print()

    # List of known problematic files
    problematic_files = [
        "core/business_agents.py",
        "core/chat_session_manager.py",
        "core/change_order_agent.py",
        "core/communication_service.py",
        "core/workflow_engine.py",
        "core/resource_manager.py",
        "core/atom_meta_agent.py",
        "core/lifecycle_comm_generator.py",
        "core/background_agent_runner.py",
        "core/admin_bootstrap.py",
        "core/formula_memory.py",
        "core/uptime_tracker.py",
        "core/scheduler.py",
        "core/llm/byok_handler.py",
        "core/archive/database_v1.py",
        "integrations/chat_orchestrator.py",
        "integrations/universal_webhook_bridge.py",
        "integrations/zoho_workdrive_service.py",
    ]

    fixed_count = 0
    for rel_path in problematic_files:
        filepath = BACKEND_DIR / rel_path
        if not filepath.exists():
            continue

        print(f"🔧 {rel_path}")

        if fix_simple_pattern(filepath):
            print(f"  ✓ Fixed")
            fixed_count += 1
        else:
            print(f"  (no fix needed or failed)")
        print()

    print("=" * 70)
    print(f"Fixed {fixed_count} files")
    print("=" * 70)
    print()

    # Verify
    import ast
    print("Verifying fixes...")
    remaining = 0
    for rel_path in problematic_files:
        filepath = BACKEND_DIR / rel_path
        if not filepath.exists():
            continue

        try:
            with open(filepath, 'r') as f:
                content = f.read()
            ast.parse(content)
        except (SyntaxError, IndentationError) as e:
            print(f"  ✗ {rel_path}:{e.lineno} - {e.msg}")
            remaining += 1

    if remaining == 0:
        print("✅ All files fixed successfully!")
        return 0
    else:
        print(f"⚠️  {remaining} files still have errors")
        return 1


if __name__ == '__main__':
    sys.exit(scan_and_fix())