@@ -68,114 +68,6 @@ data class PlanItem(
6868 }
6969}
7070
71- /* *
72- * Parses Plan format markdown into structured plan items
73- * Supports nested structure: ordered list for items, unordered list for steps
74- */
75- object PlanParser {
76- private val CODE_BLOCK_PATTERN = Regex (" ```plan\\ s*\\ n([\\ s\\ S]*?)\\ n```" , RegexOption .IGNORE_CASE )
77- private val ORDERED_ITEM_PATTERN = Regex (" ^(\\ d+)\\ .\\ s*(.+?)(?:\\ s*-\\ s*(.+))?$" )
78- private val UNORDERED_ITEM_PATTERN = Regex (" ^\\ s*-\\ s*\\ [([\\ s✓!*]?)\\ ]\\ s*(.+)$" )
79- private val FILE_LINK_PATTERN = Regex (" \\ [([^\\ ]]+)\\ ]\\ (([^)]+)\\ )" )
80-
81- fun parse (planOutput : String ): List <PlanItem > {
82- val items = mutableListOf<PlanItem >()
83-
84- // Extract plan code block if present
85- val planContent = CODE_BLOCK_PATTERN .find(planOutput)?.groupValues?.get(1 )
86- ? : planOutput
87-
88- val lines = planContent.lines()
89- var currentItem: PlanItem ? = null
90- var currentSteps = mutableListOf<PlanStep >()
91- var currentNumber = 0
92-
93- for (line in lines) {
94- val trimmed = line.trim()
95- if (trimmed.isEmpty()) continue
96-
97- // Check for ordered list item (main plan item)
98- val orderedMatch = ORDERED_ITEM_PATTERN .find(trimmed)
99- if (orderedMatch != null ) {
100- // Save previous item
101- currentItem?.let {
102- items.add(it.copy(steps = currentSteps.toList()))
103- }
104-
105- // Start new item
106- currentNumber = orderedMatch.groupValues[1 ].toIntOrNull() ? : 0
107- val titleWithPriority = orderedMatch.groupValues[2 ].trim()
108-
109- // Extract priority from title (format: "Title - PRIORITY")
110- val titleParts = titleWithPriority.split(" - " , limit = 2 )
111- val title = titleParts[0 ].trim()
112- val priority = titleParts.getOrNull(1 )?.trim() ? : " MEDIUM"
113-
114- currentItem = PlanItem (
115- number = currentNumber,
116- title = title,
117- priority = priority
118- )
119- currentSteps = mutableListOf ()
120- continue
121- }
122-
123- // Check for unordered list item (plan step)
124- val unorderedMatch = UNORDERED_ITEM_PATTERN .find(trimmed)
125- if (unorderedMatch != null ) {
126- val statusMarker = unorderedMatch.groupValues[1 ].trim()
127- val stepText = unorderedMatch.groupValues[2 ].trim()
128-
129- val status = when (statusMarker) {
130- " ✓" , " x" , " X" -> StepStatus .COMPLETED
131- " !" -> StepStatus .FAILED
132- " *" -> StepStatus .IN_PROGRESS
133- else -> StepStatus .TODO
134- }
135-
136- // Extract file links from step text
137- val fileLinks = extractFileLinks(stepText)
138-
139- currentSteps.add(
140- PlanStep (
141- text = stepText,
142- status = status,
143- fileLinks = fileLinks
144- )
145- )
146- continue
147- }
148-
149- // If we're inside an item but not a step, append to last step
150- if (currentItem != null && currentSteps.isNotEmpty() && trimmed.startsWith(" -" )) {
151- val lastStep = currentSteps.last()
152- currentSteps[currentSteps.size - 1 ] = lastStep.copy(
153- text = " ${lastStep.text} ${trimmed.removePrefix(" -" ).trim()} "
154- )
155- }
156- }
157-
158- // Save last item
159- currentItem?.let {
160- items.add(it.copy(steps = currentSteps.toList()))
161- }
162-
163- return items
164- }
165-
166- private fun extractFileLinks (text : String ): List <FileLink > {
167- val links = mutableListOf<FileLink >()
168- val matches = FILE_LINK_PATTERN .findAll(text)
169-
170- matches.forEach { match ->
171- val displayText = match.groupValues[1 ]
172- val filePath = match.groupValues[2 ]
173- links.add(FileLink (displayText, filePath))
174- }
175-
176- return links
177- }
178- }
17971
18072/* *
18173 * Displays AI-generated modification plan with modern Plan-like UI
@@ -349,21 +241,12 @@ private fun PlanItemCard(
349241) {
350242 var isExpanded by remember { mutableStateOf(true ) }
351243
352- // Determine priority color and adjust priority based on issue category
353- // Code style and formatting issues should always be MEDIUM priority
354- val isCodeStyleIssue = item.title.contains(" 代码风格" ) || item.title.contains(" Code Style" ) ||
355- item.title.contains(" 字符串格式化" ) || item.title.contains(" String Formatting" ) ||
356- item.title.contains(" 格式化" ) || item.title.contains(" Formatting" ) ||
357- item.title.contains(" 风格" ) || item.title.contains(" Style" )
358-
359- val adjustedPriority = if (isCodeStyleIssue &&
360- (item.priority.contains(" 关键" ) || item.priority.contains(" CRITICAL" ) ||
361- item.priority.contains(" 高" ) || item.priority.contains(" HIGH" ))) {
362- " MEDIUM"
363- } else {
364- item.priority
244+ // Get adjusted priority using utility function
245+ val adjustedPriority = remember(item) {
246+ PlanPriority .getAdjustedPriority(item)
365247 }
366248
249+ // Get priority color based on adjusted priority
367250 val priorityColor = when {
368251 adjustedPriority.contains(" 关键" ) || adjustedPriority.contains(" CRITICAL" ) -> AutoDevColors .Red .c600
369252 adjustedPriority.contains(" 高" ) || adjustedPriority.contains(" HIGH" ) -> AutoDevColors .Amber .c600
@@ -585,7 +468,7 @@ private fun PlanStepItem(
585468 androidx.compose.foundation.text.ClickableText (
586469 text = annotatedText,
587470 style = MaterialTheme .typography.bodySmall.copy(
588- color = MaterialTheme .colorScheme.onSurfaceVariant,
471+ color = MaterialTheme .colorScheme.onSurfaceVariant,
589472 lineHeight = MaterialTheme .typography.bodySmall.lineHeight * 1.2
590473 ),
591474 onClick = { offset ->
0 commit comments