Skip to content

Commit 21e22e6

Browse files
committed
feat(codereview): add plan item selection and file link actions #463
Enable multi-select for modification plan items and allow clicking file links to open files. Enforce one plan item per line in the template and adjust UI to reflect selection state and priority rules.
1 parent 55bc5b4 commit 21e22e6

File tree

4 files changed

+226
-29
lines changed

4 files changed

+226
-29
lines changed

mpp-core/src/commonMain/kotlin/cc/unitmesh/agent/CodeReviewAgentTemplate.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,8 @@ Generate a **specific** modification plan with **maximum 5 items**, using the Pl
698698
699699
Your output MUST be inside a code block with language `plan`:
700700
701+
**CRITICAL: Each item MUST be on a separate line. Do NOT put multiple items on the same line.**
702+
701703
```plan
702704
1. {Issue Category} - {Priority}
703705
- [ ] Fix [FileName](filepath) line {X}: {Specific issue}
@@ -714,7 +716,10 @@ Your output MUST be inside a code block with language `plan`:
714716
715717
1. **Maximum 5 items** - Focus on most critical errors (prioritize ERROR > WARNING)
716718
2. **Must be specific** - Each item must mention specific file names using [FileName](filepath) format
717-
3. **Priority**: CRITICAL (ERROR) | HIGH (WARNING) | MEDIUM (Code quality)
719+
3. **Priority**:
720+
- CRITICAL: Compilation errors, runtime crashes, security vulnerabilities
721+
- HIGH: Warnings that may cause issues, performance problems
722+
- MEDIUM: Code style, formatting, minor code quality issues (code style and formatting should ALWAYS be MEDIUM, never CRITICAL or HIGH)
718723
4. **Actionable** - "How" should provide concrete methods, not vague statements
719724
5. **Based on Lint** - Must reference actual errors from Lint results above
720725
6. **Use Plan format** - Ordered list for main items, unordered list for details
@@ -753,11 +758,13 @@ Your output MUST be inside a code block with language `plan`:
753758
**STRICT RULES**:
754759
- ✅ Maximum 5 items (no more)
755760
- ✅ Use `plan` code block format
761+
- ✅ **ONE item per line** - Each numbered item (1., 2., 3., etc.) MUST be on its own line
756762
- ✅ Each item must include [FileName](filepath) with actual file path
757763
- ✅ Must reference actual errors from Lint results
758764
- ✅ Priority based on ERROR/WARNING severity
759765
- ✅ Merge multiple similar errors in same file into one item
760766
- ✅ Use nested structure: ordered list for items, unordered list for details
767+
- ❌ DO NOT put multiple items on the same line
761768
- ❌ DO NOT use vague descriptions (like "optimize code")
762769
- ❌ DO NOT provide code examples in the plan
763770
- ❌ DO NOT use tools
@@ -785,6 +792,8 @@ ${'$'}{lintResults}
785792
786793
你的输出必须在 `plan` 代码块中:
787794
795+
**重要:每个项目必须在单独的行。不要在同一行放置多个项目。**
796+
788797
```plan
789798
1. {问题类别} - {优先级}
790799
- [ ] 修复 [文件名](文件路径) 第 {X} 行: {具体问题}
@@ -801,7 +810,10 @@ ${'$'}{lintResults}
801810
802811
1. **最多 5 项** - 聚焦最关键的错误(优先 ERROR > WARNING)
803812
2. **必须具体** - 每项必须使用 [文件名](文件路径) 格式提到具体文件
804-
3. **优先级**: 关键(ERROR)| 高(WARNING)| 中等(代码质量)
813+
3. **优先级**:
814+
- 关键:编译错误、运行时崩溃、安全漏洞
815+
- 高:可能导致问题的警告、性能问题
816+
- 中等:代码风格、格式化、轻微代码质量问题(代码风格和格式化应该始终是中等,永远不要是关键或高)
805817
4. **可执行** - "如何修复"要提供具体方法,不要泛泛而谈
806818
5. **基于 Lint** - 必须引用上面 Lint 结果中的实际错误
807819
6. **使用 Plan 格式** - 有序列表用于主要项,无序列表用于详情
@@ -840,11 +852,13 @@ ${'$'}{lintResults}
840852
**严格规则**:
841853
- ✅ 最多 5 项(不能更多)
842854
- ✅ 使用 `plan` 代码块格式
855+
- ✅ **每项单独一行** - 每个编号项(1.、2.、3. 等)必须在自己的行上
843856
- ✅ 每项必须包含 [文件名](文件路径) 和实际文件路径
844857
- ✅ 必须引用 Lint 结果中的实际错误
845858
- ✅ 优先级根据 ERROR/WARNING 严重性确定
846859
- ✅ 合并同一文件的多个相似错误到一项
847860
- ✅ 使用嵌套结构:有序列表用于项,无序列表用于详情
861+
- ❌ 不要在同一行放置多个项目
848862
- ❌ 不要使用泛泛的描述(如"优化代码")
849863
- ❌ 不要在计划中提供代码示例
850864
- ❌ 不要使用工具

mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/compose/agent/codereview/CodeReviewAgentPanel.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,21 @@ fun CodeReviewAgentPanel(
258258

259259
if (state.aiProgress.planOutput.isNotEmpty()) {
260260
item {
261+
var selectedPlanItems by remember { mutableStateOf<Set<Int>>(emptySet()) }
262+
261263
ModificationPlanSection(
262264
planOutput = state.aiProgress.planOutput,
263-
isActive = state.aiProgress.stage == AnalysisStage.GENERATING_PLAN
265+
isActive = state.aiProgress.stage == AnalysisStage.GENERATING_PLAN,
266+
selectedItems = selectedPlanItems,
267+
onItemSelectionChanged = { newSelection ->
268+
selectedPlanItems = newSelection
269+
// Store selected items in viewModel for later use in fix generation
270+
viewModel.setSelectedPlanItems(newSelection)
271+
},
272+
onFileLinkClick = { filePath ->
273+
// Open file in editor/viewer
274+
viewModel.openFile(filePath)
275+
}
264276
)
265277
}
266278
}

mpp-ui/src/commonMain/kotlin/cc/unitmesh/devins/ui/compose/agent/codereview/CodeReviewViewModel.kt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,46 @@ open class CodeReviewViewModel(
11851185
}
11861186
}
11871187

1188+
/**
1189+
* Store selected plan items for use in fix generation
1190+
*/
1191+
private var selectedPlanItems: Set<Int> = emptySet()
1192+
1193+
fun setSelectedPlanItems(items: Set<Int>) {
1194+
selectedPlanItems = items
1195+
AutoDevLogger.debug("CodeReviewViewModel") {
1196+
"Selected plan items: ${items.joinToString()}"
1197+
}
1198+
}
1199+
1200+
/**
1201+
* Get selected plan items
1202+
*/
1203+
fun getSelectedPlanItems(): Set<Int> = selectedPlanItems
1204+
1205+
/**
1206+
* Open file in editor/viewer
1207+
* Similar to MarkdownTableRenderer.kt implementation
1208+
*/
1209+
fun openFile(filePath: String) {
1210+
// Get workspace root path and construct absolute path
1211+
val root = workspace.rootPath
1212+
val absolutePath = if (root != null && !filePath.startsWith("/")) {
1213+
"$root/$filePath"
1214+
} else {
1215+
filePath
1216+
}
1217+
1218+
AutoDevLogger.info("CodeReviewViewModel") {
1219+
"Opening file: $absolutePath (original: $filePath, root: $root)"
1220+
}
1221+
1222+
// Emit notification event to open file
1223+
scope.launch {
1224+
_notificationEvent.emit("open_file" to absolutePath)
1225+
}
1226+
}
1227+
11881228
/**
11891229
* Load issue information for a specific commit asynchronously
11901230
*

0 commit comments

Comments
 (0)