Skip to content

Commit 12cde8b

Browse files
authored
Merge branch 'master' into master
2 parents 982f989 + a2529ce commit 12cde8b

File tree

32 files changed

+576
-176
lines changed

32 files changed

+576
-176
lines changed

build.gradle.kts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,9 +410,7 @@ project(":core") {
410410
testFramework(TestFrameworkType.Platform)
411411
}
412412

413-
implementation("io.modelcontextprotocol:kotlin-sdk:0.5.0") {
414-
excludeKotlinDeps()
415-
}
413+
implementation("io.modelcontextprotocol:kotlin-sdk:0.5.0")
416414

417415
implementation("io.reactivex.rxjava3:rxjava:3.1.10")
418416

core/src/233/main/resources/META-INF/autodev-core.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
<postStartupActivity implementation="cc.unitmesh.devti.update.AutoDevUpdateStartupActivity"/>
8282
<postStartupActivity implementation="cc.unitmesh.devti.mcp.MCPServerStartupValidator"/>
8383
<postStartupActivity implementation="cc.unitmesh.devti.llm2.GithubCopilotModelInitActivity"/>
84+
<jbProtocolCommand implementation="cc.unitmesh.devti.mcp.AutoDevJbProtocolService"/>
8485
<notificationGroup id="UnitMesh.MCPServer" displayType="BALLOON"/>
8586
</extensions>
8687

core/src/main/kotlin/cc/unitmesh/devti/actions/chat/FixThisAction.kt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cc.unitmesh.devti.actions.chat
22

3-
import cc.unitmesh.devti.actions.chat.base.collectElementProblemAsSting
3+
import cc.unitmesh.devti.actions.chat.base.collectProblems
4+
import cc.unitmesh.devti.actions.chat.base.commentPrefix
45
import cc.unitmesh.devti.gui.chat.message.ChatActionType
56
import cc.unitmesh.devti.settings.locale.LanguageChangedCallback.presentationText
67
import com.intellij.openapi.editor.Editor
@@ -15,6 +16,11 @@ class FixThisAction : RefactorThisAction() {
1516
override fun getActionType(): ChatActionType = ChatActionType.FIX_ISSUE
1617

1718
override fun addAdditionPrompt(project: Project, editor: Editor, element: PsiElement): String {
18-
return collectElementProblemAsSting(element, project, editor)
19-
}
20-
}
19+
val commentSymbol = commentPrefix(element)
20+
21+
val staticCodeResults = collectProblems(project, editor, element)?.let {
22+
"\n\n$commentSymbol relative static analysis result:\n$it"
23+
} ?: ""
24+
25+
return staticCodeResults
26+
}}
Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package cc.unitmesh.devti.actions.chat.base
22

3-
import cc.unitmesh.devti.provider.PsiElementDataBuilder
43
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx
54
import com.intellij.openapi.editor.Editor
65
import com.intellij.openapi.project.Project
@@ -43,38 +42,3 @@ fun collectProblems(project: Project, editor: Editor, element: PsiElement): Stri
4342
val commentSymbol = commentPrefix(element)
4443
return errors.distinct().joinToString("\n") { "$commentSymbol - $it" }
4544
}
46-
47-
/**
48-
* Collects the problems related to the given PsiElement and returns them as a formatted string.
49-
*
50-
* @param element the PsiElement for which problems need to be collected
51-
* @param project the Project in which the element exists
52-
* @param editor the Editor used for displaying the problems
53-
* @return a formatted string containing the problems related to the element, along with any relevant code snippets
54-
*/
55-
fun collectElementProblemAsSting(
56-
element: PsiElement,
57-
project: Project,
58-
editor: Editor
59-
): String {
60-
val commentSymbol = commentPrefix(element)
61-
62-
return collectProblems(project, editor, element).let { problem ->
63-
var relatedCode = ""
64-
getCanonicalName(problem).map {
65-
val classContext = PsiElementDataBuilder.forLanguage(element.language)?.lookupElement(project, it)
66-
classContext.let { context ->
67-
relatedCode += context?.format() ?: ""
68-
}
69-
}
70-
71-
buildString {
72-
if (relatedCode.isNotEmpty()) {
73-
append("\n\n$commentSymbol relative static analysis result:\n$problem")
74-
relatedCode.split("\n").forEach {
75-
append("\n$commentSymbol $it")
76-
}
77-
}
78-
}
79-
} ?: ""
80-
}

core/src/main/kotlin/cc/unitmesh/devti/bridge/utils/StructureCommandUtil.kt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package cc.unitmesh.devti.bridge.utils
22

33
import com.intellij.ide.structureView.StructureView
44
import com.intellij.ide.structureView.StructureViewTreeElement
5+
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase
56
import com.intellij.lang.LanguageStructureViewBuilder
7+
import com.intellij.lang.html.structureView.HtmlTagTreeElement
68
import com.intellij.openapi.application.ModalityState
79
import com.intellij.openapi.application.invokeLater
810
import com.intellij.openapi.application.runInEdt
@@ -64,7 +66,7 @@ object StructureCommandUtil {
6466
): TextEditor? {
6567
val future = CompletableFuture<FileEditor>()
6668
runInEdt(ModalityState.any()) {
67-
var createEditor = TextEditorProvider.getInstance().createEditor(project, file)
69+
val createEditor = TextEditorProvider.getInstance().createEditor(project, file)
6870
future.complete(createEditor)
6971
}
7072

@@ -79,7 +81,21 @@ object StructureCommandUtil {
7981
*/
8082
private fun traverseStructure(element: StructureViewTreeElement, depth: Int, sb: StringBuilder): StringBuilder {
8183
val indent = formatBeforeCode(element, depth)
82-
var str = element.presentation.presentableText
84+
val str = when(element) {
85+
is HtmlTagTreeElement -> {
86+
if (element.locationString?.length == 0 || element.locationString == null) {
87+
element.presentableText
88+
} else {
89+
element.presentableText + " " + element.locationString
90+
}
91+
}
92+
is PsiTreeElementBase<*> -> {
93+
element.presentableText
94+
}
95+
else -> {
96+
element.presentation.presentableText
97+
}
98+
}
8399

84100
if (!str.isNullOrBlank()) {
85101
sb.append(indent).append(str).append("\n")

core/src/main/kotlin/cc/unitmesh/devti/gui/chat/ui/AutoDevInputSection.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ class AutoDevInputSection(private val project: Project, val disposable: Disposab
100100
}
101101

102102
fun renderText(): String {
103-
val files = workspaceFilePanel.getAllFilesFormat()
104103
relatedFileListViewModel.clearAllFiles()
104+
val files = workspaceFilePanel.getAllFilesFormat()
105105
workspaceFilePanel.clear()
106-
return input.text + "\n" + files
106+
return input.text + files
107107
}
108108

109109
fun clearText() {

core/src/main/kotlin/cc/unitmesh/devti/gui/chat/ui/file/FilePresentation.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,16 @@ data class FilePresentation(
3131
)
3232
}
3333

34-
private fun getPresentablePath(project: Project, file: VirtualFile): String =
35-
project.basePath?.let { basePath ->
34+
private fun getPresentablePath(project: Project, file: VirtualFile): String {
35+
val path = project.basePath?.let { basePath ->
3636
when (file.parent?.path) {
3737
basePath -> file.name
3838
else -> file.path.removePrefix(basePath)
3939
}
4040
} ?: file.path
41+
42+
return path.removePrefix("/")
43+
}
4144
}
4245

4346
fun relativePath(project: Project): String {

core/src/main/kotlin/cc/unitmesh/devti/gui/chat/ui/file/WorkspaceFilePanel.kt

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package cc.unitmesh.devti.gui.chat.ui.file
22

33
import com.intellij.icons.AllIcons
4-
import com.intellij.openapi.fileChooser.FileChooser
5-
import com.intellij.openapi.fileChooser.FileChooserDescriptor
64
import com.intellij.openapi.project.Project
75
import com.intellij.openapi.vfs.VirtualFile
86
import com.intellij.ui.JBColor
@@ -54,18 +52,6 @@ class WorkspaceFilePanel(private val project: Project) : JPanel(BorderLayout())
5452
popup.show(component)
5553
}
5654

57-
private fun addFile() {
58-
val descriptor = FileChooserDescriptor(true, true, false, false, false, true)
59-
.withTitle(AutoDevBundle.message("chat.panel.select.files.title"))
60-
.withDescription(AutoDevBundle.message("chat.panel.select.files.description"))
61-
62-
FileChooser.chooseFiles(descriptor, project, null) { files ->
63-
for (file in files) {
64-
addFileToWorkspace(file)
65-
}
66-
}
67-
}
68-
6955
fun addFileToWorkspace(file: VirtualFile) {
7056
val filePresentation = FilePresentation.from(project, file)
7157
if (workspaceFiles.none { it.virtualFile == file }) {
@@ -99,13 +85,9 @@ class WorkspaceFilePanel(private val project: Project) : JPanel(BorderLayout())
9985
updateFilesPanel()
10086
}
10187

102-
fun getAllFiles(): List<FilePresentation> {
103-
return workspaceFiles.toList()
104-
}
105-
10688
fun getAllFilesFormat(): String {
10789
return workspaceFiles.joinToString(separator = "\n") {
108-
"\n/file:${it.presentablePath}"
90+
"/file:${it.presentablePath}"
10991
}
11092
}
11193
}

core/src/main/kotlin/cc/unitmesh/devti/gui/chat/ui/file/WorkspaceFileToolbar.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ object WorkspaceFileToolbar {
3939

4040
component = component.parent
4141
}
42+
4243
null
4344
}
4445

core/src/main/kotlin/cc/unitmesh/devti/gui/toolbar/CopyAllMessagesAction.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class CopyAllMessagesAction : AnAction("Copy All Messages", "Copy all messages",
4040

4141
private fun copyMessages(project: Project?) {
4242
val agentStateService = project?.getService(AgentStateService::class.java) ?: return
43-
var allText = agentStateService.getAllMessages().joinToString("\n") { it.content }
43+
val allText = agentStateService.getAllMessages().joinToString("\n") { it.content }
4444
val selection = StringSelection(allText)
4545
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
4646
clipboard.setContents(selection, null)
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package cc.unitmesh.devti.gui.toolbar
2+
3+
import cc.unitmesh.devti.AutoDevIcons
4+
import cc.unitmesh.devti.llms.LlmFactory
5+
import cc.unitmesh.devti.observer.agent.AgentStateService
6+
import cc.unitmesh.devti.settings.coder.coderSetting
7+
import cc.unitmesh.devti.statusbar.AutoDevStatus
8+
import cc.unitmesh.devti.statusbar.AutoDevStatusService
9+
import cc.unitmesh.devti.template.GENIUS_CODE
10+
import cc.unitmesh.devti.template.TemplateRender
11+
import cc.unitmesh.devti.util.AutoDevCoroutineScope
12+
import com.intellij.icons.AllIcons
13+
import com.intellij.openapi.actionSystem.*
14+
import com.intellij.openapi.actionSystem.ex.CustomComponentAction
15+
import com.intellij.openapi.application.ApplicationManager
16+
import com.intellij.openapi.command.WriteCommandAction
17+
import com.intellij.openapi.diagnostic.logger
18+
import com.intellij.openapi.editor.ScrollType
19+
import com.intellij.openapi.fileEditor.FileEditorManager
20+
import com.intellij.openapi.project.Project
21+
import com.intellij.openapi.project.guessProjectDir
22+
import com.intellij.openapi.vfs.LocalFileSystem
23+
import com.intellij.ui.components.panels.Wrapper
24+
import com.intellij.util.ui.JBInsets
25+
import com.intellij.util.ui.JBUI
26+
import kotlinx.coroutines.flow.Flow
27+
import kotlinx.coroutines.flow.cancellable
28+
import kotlinx.coroutines.launch
29+
import javax.swing.JButton
30+
import javax.swing.JComponent
31+
import kotlin.io.path.createDirectories
32+
import kotlin.io.path.exists
33+
34+
/**
35+
* Related prompts:
36+
* https://gist.github.com/transitive-bullshit/487c9cb52c75a9701d312334ed53b20c
37+
* https://www.reddit.com/r/ClaudeAI/comments/1jr52qj/here_is_claude_codes_compact_prompt/
38+
*/
39+
class SummaryMessagesAction : AnAction("Summary Messages", "Summary all current messages to memorize.md", AllIcons.Nodes.Target),
40+
CustomComponentAction {
41+
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.EDT
42+
override fun actionPerformed(e: AnActionEvent) {
43+
val project = e.project ?: return
44+
val baseDir = project.coderSetting.state.teamPromptsDir
45+
val presentation = e.presentation
46+
47+
copyMessages(project)
48+
49+
AutoDevCoroutineScope.scope(project).launch {
50+
try {
51+
updatePresentation(presentation, AutoDevIcons.LOADING, false)
52+
AutoDevStatusService.notifyApplication(AutoDevStatus.InProgress)
53+
val promptDir = project.guessProjectDir()!!.toNioPath().resolve(baseDir)
54+
if (!promptDir.exists()) {
55+
promptDir.createDirectories()
56+
}
57+
58+
val file = promptDir.resolve("memories.md").toFile()
59+
if (!file.exists()) {
60+
file.createNewFile()
61+
}
62+
63+
val systemPrompt = buildPrompt(project)
64+
val userPrompt = copyMessages(project)
65+
66+
val fileEditorManager = FileEditorManager.getInstance(project)
67+
ApplicationManager.getApplication().invokeAndWait {
68+
val virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file)
69+
if (virtualFile != null) {
70+
fileEditorManager.setSelectedEditor(virtualFile, "text-editor")
71+
}
72+
}
73+
74+
val editor = fileEditorManager.selectedTextEditor
75+
val stream: Flow<String> = LlmFactory.create(project).stream(systemPrompt, userPrompt)
76+
val result = StringBuilder()
77+
78+
stream.cancellable().collect { chunk ->
79+
result.append(chunk)
80+
WriteCommandAction.writeCommandAction(project).compute<Any, RuntimeException> {
81+
editor?.document?.setText(result.toString())
82+
editor?.caretModel?.moveToOffset(editor?.document?.textLength ?: 0)
83+
editor?.scrollingModel?.scrollToCaret(ScrollType.RELATIVE)
84+
}
85+
}
86+
87+
AutoDevStatusService.notifyApplication(AutoDevStatus.Done)
88+
} catch (e: Exception) {
89+
AutoDevStatusService.notifyApplication(AutoDevStatus.Error)
90+
e.printStackTrace()
91+
} finally {
92+
updatePresentation(presentation, AllIcons.Nodes.Target, true)
93+
}
94+
}
95+
}
96+
97+
override fun createCustomComponent(presentation: Presentation, place: String): JComponent {
98+
val button: JButton = object : JButton() {
99+
init {
100+
putClientProperty("ActionToolbar.smallVariant", true)
101+
putClientProperty("customButtonInsets", JBInsets(1, 1, 1, 1).asUIResource())
102+
103+
setOpaque(false)
104+
addActionListener {
105+
copyMessages(ActionToolbar.getDataContextFor(this).getData(CommonDataKeys.PROJECT))
106+
}
107+
}
108+
}
109+
110+
return Wrapper(button).also {
111+
it.setBorder(JBUI.Borders.empty(0, 10))
112+
}
113+
}
114+
115+
private fun copyMessages(project: Project?): String {
116+
val agentStateService = project?.getService(AgentStateService::class.java) ?: return ""
117+
val allText = agentStateService.getAllMessages().joinToString("\n") { it.content }
118+
return allText
119+
}
120+
121+
private fun updatePresentation(presentation: Presentation, icon: javax.swing.Icon, enabled: Boolean) {
122+
presentation.icon = icon
123+
presentation.isEnabled = enabled
124+
}
125+
126+
private suspend fun buildPrompt(project: Project): String {
127+
val templateRender = TemplateRender(GENIUS_CODE)
128+
val template = templateRender.getTemplate("memory.vm")
129+
130+
val prompt = templateRender.renderTemplate(template)
131+
return prompt
132+
}
133+
}

core/src/main/kotlin/cc/unitmesh/devti/indexer/DomainDictGenerateAction.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,9 @@ class DomainDictGenerateAction : AnAction() {
5959
}
6060

6161
val fileEditorManager = FileEditorManager.getInstance(project)
62-
var editors: Array<FileEditor> = emptyArray()
6362
ApplicationManager.getApplication().invokeAndWait {
6463
val virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file)
6564
if (virtualFile != null) {
66-
editors = fileEditorManager.openFile(virtualFile, true)
6765
fileEditorManager.setSelectedEditor(virtualFile, "text-editor")
6866
}
6967
}
@@ -86,7 +84,6 @@ class DomainDictGenerateAction : AnAction() {
8684
AutoDevStatusService.notifyApplication(AutoDevStatus.Error)
8785
e.printStackTrace()
8886
} finally {
89-
// Restore icon and enable the action
9087
updatePresentation(presentation, AutoDevIcons.AI_COPILOT, true)
9188
}
9289
}

0 commit comments

Comments
 (0)