Skip to content

Commit b1dddad

Browse files
committed
fix: handle corrupted markers in remove, CRLF-safe end-marker consumption
1. Handle corrupted markers in remove_context_section() — mirror upsert's behavior: start-only removes start→EOF, end-only removes BOF→end. Previously bailed out leaving partial markers behind. 2. CRLF-safe end-marker consumption — both upsert and remove now handle \r\n after the end marker, not just \n. Prevents extra blank lines at replacement boundaries in CRLF files. 3. Clarify path rule in plan template — distinguish filesystem operations (absolute paths) from documentation/agent context references (project-relative paths).
1 parent 03af8ec commit b1dddad

2 files changed

Lines changed: 27 additions & 9 deletions

File tree

src/specify_cli/integrations/base.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,9 @@ def upsert_context_section(
492492
if start_idx != -1 and end_idx != -1 and end_idx > start_idx:
493493
# Replace existing section (include the end marker + newline)
494494
end_of_marker = end_idx + len(self.CONTEXT_MARKER_END)
495+
# Consume trailing line ending (CRLF or LF)
496+
if end_of_marker < len(content) and content[end_of_marker] == "\r":
497+
end_of_marker += 1
495498
if end_of_marker < len(content) and content[end_of_marker] == "\n":
496499
end_of_marker += 1
497500
new_content = content[:start_idx] + section + content[end_of_marker:]
@@ -501,6 +504,8 @@ def upsert_context_section(
501504
elif end_idx != -1:
502505
# Corrupted: end marker without start — replace BOF through end marker
503506
end_of_marker = end_idx + len(self.CONTEXT_MARKER_END)
507+
if end_of_marker < len(content) and content[end_of_marker] == "\r":
508+
end_of_marker += 1
504509
if end_of_marker < len(content) and content[end_of_marker] == "\n":
505510
end_of_marker += 1
506511
new_content = section + content[end_of_marker:]
@@ -549,19 +554,32 @@ def remove_context_section(self, project_root: Path) -> bool:
549554
start_idx if start_idx != -1 else 0,
550555
)
551556

552-
if start_idx == -1 or end_idx == -1 or end_idx <= start_idx:
557+
if start_idx != -1 and end_idx != -1 and end_idx > start_idx:
558+
removal_start = start_idx
559+
removal_end = end_idx + len(self.CONTEXT_MARKER_END)
560+
elif start_idx != -1:
561+
# Corrupted: start marker without end — remove from start through EOF
562+
removal_start = start_idx
563+
removal_end = len(content)
564+
elif end_idx != -1:
565+
# Corrupted: end marker without start — remove BOF through end marker
566+
removal_start = 0
567+
removal_end = end_idx + len(self.CONTEXT_MARKER_END)
568+
else:
553569
return False
554570

555-
end_of_marker = end_idx + len(self.CONTEXT_MARKER_END)
556-
if end_of_marker < len(content) and content[end_of_marker] == "\n":
557-
end_of_marker += 1
571+
# Consume trailing line ending (CRLF or LF)
572+
if removal_end < len(content) and content[removal_end] == "\r":
573+
removal_end += 1
574+
if removal_end < len(content) and content[removal_end] == "\n":
575+
removal_end += 1
558576

559577
# Also strip a blank line before the section if present
560-
if start_idx > 0 and content[start_idx - 1] == "\n":
561-
if start_idx > 1 and content[start_idx - 2] == "\n":
562-
start_idx -= 1
578+
if removal_start > 0 and content[removal_start - 1] == "\n":
579+
if removal_start > 1 and content[removal_start - 2] == "\n":
580+
removal_start -= 1
563581

564-
new_content = content[:start_idx] + content[end_of_marker:]
582+
new_content = content[:removal_start] + content[removal_end:]
565583

566584
# Normalize line endings before comparisons
567585
normalized = new_content.replace("\r\n", "\n").replace("\r", "\n")

templates/commands/plan.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,5 +148,5 @@ You **MUST** consider the user input before proceeding (if not empty).
148148

149149
## Key rules
150150

151-
- Use absolute paths
151+
- Use absolute paths for filesystem operations; use project-relative paths for references in documentation and agent context files
152152
- ERROR on gate failures or unresolved clarifications

0 commit comments

Comments
 (0)