tech debt system
This commit is contained in:
parent
de816867ee
commit
f2ad833c6b
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Technical Debt Note 1
|
||||||
|
## Description
|
||||||
|
The tech debt note cleanup process needs an AI-driven strategy to:
|
||||||
|
1. Analyze note contents and determine priority/relevance
|
||||||
|
2. Consider note age and related code locations
|
||||||
|
3. Implement a scoring system for note importance
|
||||||
|
|
||||||
|
This should be implemented as a separate cleanup agent that can be triggered when needed.
|
||||||
|
|
||||||
|
## Location
|
||||||
|
ra_aid/tools/note_tech_debt.py
|
||||||
|
|
@ -33,7 +33,9 @@ def print_stage_header(stage: str) -> None:
|
||||||
|
|
||||||
# Create styled rule with icon
|
# Create styled rule with icon
|
||||||
rule_content = f"{icon} {stage_title} {icon}"
|
rule_content = f"{icon} {stage_title} {icon}"
|
||||||
|
console.print()
|
||||||
console.print(Rule(rule_content, style="green bold"))
|
console.print(Rule(rule_content, style="green bold"))
|
||||||
|
console.print()
|
||||||
|
|
||||||
def print_task_header(task: str) -> None:
|
def print_task_header(task: str) -> None:
|
||||||
"""Print a task header with yellow styling and wrench emoji. Content is rendered as Markdown.
|
"""Print a task header with yellow styling and wrench emoji. Content is rendered as Markdown.
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,26 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional, Any
|
||||||
import os
|
import os
|
||||||
import glob
|
import glob
|
||||||
from langchain_core.tools import tool
|
from langchain_core.tools import tool
|
||||||
from rich.console import Console
|
from rich.console import Console
|
||||||
from rich.panel import Panel
|
from rich.panel import Panel
|
||||||
|
|
||||||
|
MAX_NOTES = 10 # Maximum number of tech debt notes before cleanup warning
|
||||||
|
|
||||||
console = Console()
|
console = Console()
|
||||||
|
|
||||||
@tool
|
@tool
|
||||||
def note_tech_debt(
|
def note_tech_debt(
|
||||||
description: str,
|
description: str,
|
||||||
location: Optional[str] = None
|
location: Optional[str] = None
|
||||||
) -> Dict[str, any]:
|
) -> Dict[str, Any]:
|
||||||
"""Record a technical debt note for later review.
|
"""Record a technical debt note for later review.
|
||||||
|
|
||||||
Creates a markdown file in .ra-aid/tech-debt/ containing the technical debt note.
|
Creates a markdown file in .ra-aid/tech-debt/ containing the technical debt note.
|
||||||
|
The system maintains a limit of MAX_NOTES (10) tech debt notes before triggering
|
||||||
|
cleanup procedures. When this limit is reached, a cleanup agent is spawned to
|
||||||
|
analyze and suggest notes for removal.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
description: Description of the technical debt issue
|
description: Description of the technical debt issue
|
||||||
|
|
@ -26,17 +31,39 @@ def note_tech_debt(
|
||||||
- success: Boolean indicating if note was saved
|
- success: Boolean indicating if note was saved
|
||||||
- note_path: Path to the created note file
|
- note_path: Path to the created note file
|
||||||
- note_number: Sequential number of the note
|
- note_number: Sequential number of the note
|
||||||
|
- cleanup_needed: Boolean indicating if note limit was reached
|
||||||
"""
|
"""
|
||||||
# Ensure base directory exists
|
# Ensure base directory exists
|
||||||
base_dir = Path('.ra-aid/tech-debt')
|
base_dir = Path('.ra-aid/tech-debt')
|
||||||
base_dir.mkdir(parents=True, exist_ok=True)
|
base_dir.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
# Find next note number
|
# Find existing notes and determine next note number
|
||||||
existing_notes = glob.glob(str(base_dir / '*.md'))
|
existing_notes = glob.glob(str(base_dir / '*.md'))
|
||||||
next_num = 1
|
next_num = 1
|
||||||
|
cleanup_needed = False
|
||||||
|
|
||||||
if existing_notes:
|
if existing_notes:
|
||||||
|
# Extract note numbers from filenames and find highest number
|
||||||
numbers = [int(Path(note).stem) for note in existing_notes]
|
numbers = [int(Path(note).stem) for note in existing_notes]
|
||||||
next_num = max(numbers) + 1
|
next_num = max(numbers) + 1
|
||||||
|
|
||||||
|
# Check if we've hit the note limit that triggers cleanup
|
||||||
|
if len(existing_notes) >= MAX_NOTES:
|
||||||
|
cleanup_needed = True
|
||||||
|
console.print(
|
||||||
|
Panel(
|
||||||
|
f"""[bold]Tech Debt Threshold Reached[/bold]
|
||||||
|
|
||||||
|
• Current Count: {len(existing_notes)} notes
|
||||||
|
• Maximum Limit: {MAX_NOTES} notes
|
||||||
|
• Status: Spawning cleanup/triage agent
|
||||||
|
|
||||||
|
[dim italic]The cleanup agent will analyze note contents and suggest which ones to purge.[/dim italic]
|
||||||
|
""",
|
||||||
|
title="🧹 Tech Debt Cleanup",
|
||||||
|
border_style="bright_blue"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Create note path
|
# Create note path
|
||||||
note_path = base_dir / f'{next_num}.md'
|
note_path = base_dir / f'{next_num}.md'
|
||||||
|
|
@ -64,5 +91,6 @@ def note_tech_debt(
|
||||||
return {
|
return {
|
||||||
'success': True,
|
'success': True,
|
||||||
'note_path': str(note_path),
|
'note_path': str(note_path),
|
||||||
'note_number': next_num
|
'note_number': next_num,
|
||||||
|
'cleanup_needed': cleanup_needed
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ def run_shell_command(command: str) -> Dict[str, Union[str, int, bool]]:
|
||||||
|
|
||||||
if cowboy_mode:
|
if cowboy_mode:
|
||||||
console.print("")
|
console.print("")
|
||||||
console.print(get_cowboy_message())
|
console.print(" " + get_cowboy_message())
|
||||||
console.print("")
|
console.print("")
|
||||||
|
|
||||||
# Show just the command in a simple panel
|
# Show just the command in a simple panel
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ def test_shell_command_cowboy_mode(mock_console, mock_confirm, mock_run_interact
|
||||||
mock_confirm.ask.assert_not_called()
|
mock_confirm.ask.assert_not_called()
|
||||||
|
|
||||||
def test_shell_command_cowboy_message(mock_console, mock_confirm, mock_run_interactive):
|
def test_shell_command_cowboy_message(mock_console, mock_confirm, mock_run_interactive):
|
||||||
"""Test that cowboy mode displays a cowboy message"""
|
"""Test that cowboy mode displays a properly formatted cowboy message with correct spacing"""
|
||||||
_global_memory['config'] = {'cowboy_mode': True}
|
_global_memory['config'] = {'cowboy_mode': True}
|
||||||
|
|
||||||
with patch('ra_aid.tools.shell.get_cowboy_message') as mock_get_message:
|
with patch('ra_aid.tools.shell.get_cowboy_message') as mock_get_message:
|
||||||
|
|
@ -39,7 +39,9 @@ def test_shell_command_cowboy_message(mock_console, mock_confirm, mock_run_inter
|
||||||
result = run_shell_command("echo test")
|
result = run_shell_command("echo test")
|
||||||
|
|
||||||
assert result['success'] is True
|
assert result['success'] is True
|
||||||
mock_console.print.assert_any_call('🤠 Test cowboy message!')
|
mock_console.print.assert_any_call("")
|
||||||
|
mock_console.print.assert_any_call(" 🤠 Test cowboy message!")
|
||||||
|
mock_console.print.assert_any_call("")
|
||||||
mock_get_message.assert_called_once()
|
mock_get_message.assert_called_once()
|
||||||
|
|
||||||
def test_shell_command_interactive_approved(mock_console, mock_confirm, mock_run_interactive):
|
def test_shell_command_interactive_approved(mock_console, mock_confirm, mock_run_interactive):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue