├── src ├── test │ ├── resources │ │ ├── application.properties │ │ ├── indexes │ │ │ └── hnsw.index │ │ ├── images │ │ │ └── test-image.png │ │ ├── inline │ │ │ └── TestClass.java │ │ └── codecompletions │ │ │ ├── psi │ │ │ ├── python.txt │ │ │ └── java.txt │ │ │ └── code-completion-file.txt │ └── kotlin │ │ ├── ee │ │ └── carlrobert │ │ │ └── codegpt │ │ │ ├── settings │ │ │ ├── remote │ │ │ │ ├── ConfigChangeCollectorTest.kt │ │ │ │ └── RemoteSettingsFormIntegrationTest.kt │ │ │ ├── service │ │ │ │ └── custom │ │ │ │ │ └── form │ │ │ │ │ └── CustomServiceListFormTest.kt │ │ │ └── configuration │ │ │ │ └── CommitMessageTemplateTest.kt │ │ │ └── toolwindow │ │ │ └── chat │ │ │ ├── CompleteOutputParserTest.kt │ │ │ └── StreamOutputParserTest.kt │ │ └── testsupport │ │ └── IntegrationTest.kt └── main │ ├── kotlin │ └── ee │ │ └── carlrobert │ │ └── codegpt │ │ ├── settings │ │ ├── remote │ │ │ └── ConfigSyncService.kt │ │ ├── service │ │ │ ├── DialogResult.kt │ │ │ ├── custom │ │ │ │ ├── form │ │ │ │ │ ├── model │ │ │ │ │ │ ├── CustomServicesStateData.kt │ │ │ │ │ │ ├── CustomServiceChatCompletionSettingsData.kt │ │ │ │ │ │ ├── CustomServiceCodeCompletionSettingsData.kt │ │ │ │ │ │ └── CustomServiceSettingsData.kt │ │ │ │ │ └── CustomServiceNameListRenderer.kt │ │ │ │ └── CustomServicesChangeNotifier.kt │ │ │ ├── ProviderChangeNotifier.kt │ │ │ ├── codegpt │ │ │ │ ├── CodeGPTUserDetailsNotifier.kt │ │ │ │ └── CodeGPTServiceSettings.kt │ │ │ ├── google │ │ │ │ ├── GoogleSettings.kt │ │ │ │ └── GoogleSettingsConfigurable.kt │ │ │ ├── llama │ │ │ │ └── form │ │ │ │ │ └── ServerButtonConfig.kt │ │ │ ├── inception │ │ │ │ ├── InceptionSettings.kt │ │ │ │ └── InceptionSettingsForm.kt │ │ │ ├── ServiceConfigurable.kt │ │ │ ├── ollama │ │ │ │ ├── OllamaSettings.kt │ │ │ │ └── OllamaSettingsConfigurable.kt │ │ │ └── InceptionServiceConfigurable.kt │ │ ├── configuration │ │ │ ├── ConfigurationStateListener.kt │ │ │ ├── ChatMode.kt │ │ │ └── PathInputDialog.kt │ │ ├── mcp │ │ │ ├── form │ │ │ │ ├── McpFormUtil.kt │ │ │ │ ├── details │ │ │ │ │ └── McpFormDetails.kt │ │ │ │ └── McpFileProvider.kt │ │ │ └── McpConfigurable.kt │ │ ├── documentation │ │ │ └── DocumentationsConfigurable.kt │ │ ├── persona │ │ │ └── PersonaSettings.kt │ │ ├── prompts │ │ │ └── PromptsConfigurable.kt │ │ └── models │ │ │ ├── ModelSettingsConfigurable.kt │ │ │ └── ModelSettingsState.kt │ │ ├── psistructure │ │ ├── models │ │ │ ├── ClassLanguage.kt │ │ │ ├── ClassName.kt │ │ │ ├── EnumEntryName.kt │ │ │ ├── ClassType.kt │ │ │ ├── FieldStructure.kt │ │ │ ├── ParameterInfo.kt │ │ │ ├── ConstructorStructure.kt │ │ │ ├── MethodStructure.kt │ │ │ └── ClassStructure.kt │ │ ├── PsiDepthFile.kt │ │ └── PsiFileDepthQueue.kt │ │ ├── inlineedit │ │ └── engine │ │ │ ├── ApplyStrategy.kt │ │ │ ├── InlineEditEngine.kt │ │ │ ├── ApplyContext.kt │ │ │ └── InlineEditApplyStrategyFactory.kt │ │ ├── toolwindow │ │ ├── chat │ │ │ ├── parser │ │ │ │ └── MessageParser.kt │ │ │ ├── editor │ │ │ │ ├── ToolWindowEditorFileDetails.kt │ │ │ │ ├── state │ │ │ │ │ └── EditorState.kt │ │ │ │ ├── diff │ │ │ │ │ └── DiffUtil.kt │ │ │ │ └── ErrorHandler.kt │ │ │ └── ChatToolWindowListener.kt │ │ └── history │ │ │ └── BaseFilterAction.kt │ │ ├── util │ │ ├── file │ │ │ ├── FileExtensionLanguageDetails.kt │ │ │ └── LanguageFileExtensionDetails.kt │ │ ├── MapConverter.kt │ │ ├── coroutines │ │ │ ├── DisposableCoroutineScope.kt │ │ │ ├── EdtCoroutineDispatcherExtensions.kt │ │ │ ├── EdtCoroutineDispatcher.kt │ │ │ └── CoroutineDispatchers.kt │ │ ├── ProjectPathUtils.kt │ │ ├── ApplicationUtil.kt │ │ └── BaseConverter.kt │ │ ├── ui │ │ ├── textarea │ │ │ ├── TagProcessor.kt │ │ │ ├── header │ │ │ │ └── tag │ │ │ │ │ ├── TagManagerListener.kt │ │ │ │ │ └── TagUtil.kt │ │ │ ├── lookup │ │ │ │ ├── LookupUtil.kt │ │ │ │ ├── action │ │ │ │ │ ├── git │ │ │ │ │ │ ├── IncludeCurrentChangesActionItem.kt │ │ │ │ │ │ └── GitCommitActionItem.kt │ │ │ │ │ ├── personas │ │ │ │ │ │ ├── PersonaActionItem.kt │ │ │ │ │ │ └── AddPersonaActionItem.kt │ │ │ │ │ ├── AbstractLookupActionItem.kt │ │ │ │ │ ├── CodeAnalyzeActionItem.kt │ │ │ │ │ ├── files │ │ │ │ │ │ └── IncludeOpenFilesActionItem.kt │ │ │ │ │ ├── HistoryActionItem.kt │ │ │ │ │ ├── docs │ │ │ │ │ │ └── ViewAllDocsActionItem.kt │ │ │ │ │ ├── mcp │ │ │ │ │ │ └── McpServerActionItem.kt │ │ │ │ │ └── WebActionItem.kt │ │ │ │ ├── group │ │ │ │ │ └── AbstractLookupGroupItem.kt │ │ │ │ ├── LookupItem.kt │ │ │ │ └── AbstractLookupItem.kt │ │ │ ├── TagDetailsComparator.kt │ │ │ └── PromptTextFieldConstants.kt │ │ └── URLTextField.kt │ │ ├── nextedit │ │ ├── NextEditProvider.kt │ │ ├── ProxyAINextEditProvider.kt │ │ ├── NextEditCoordinator.kt │ │ └── AcceptNextEditAction.kt │ │ ├── completions │ │ ├── llama │ │ │ ├── logging │ │ │ │ ├── ServerLoggingStrategy.kt │ │ │ │ ├── NoOpLoggingStrategy.kt │ │ │ │ └── SettingsFormLoggingStrategy.kt │ │ │ └── LlamaConstants.kt │ │ └── ToolApprovalMode.kt │ │ ├── autoimport │ │ └── AutoImportResolver.kt │ │ ├── codecompletions │ │ ├── psi │ │ │ ├── LanguageContextFinder.kt │ │ │ └── PsiUtil.kt │ │ ├── CompletionProgressNotifier.kt │ │ ├── CompletionTracker.kt │ │ ├── edit │ │ │ └── GrpcCallCredentials.kt │ │ ├── CodeCompletionProviderPresentation.kt │ │ └── CodeCompletionSuggestionUpdateAdapter.kt │ │ ├── tokens │ │ └── TokenComputationService.kt │ │ ├── actions │ │ ├── editor │ │ │ ├── InlineEditAction.kt │ │ │ ├── AddSelectionToContextAction.kt │ │ │ └── ShowEditorActionGroupAction.kt │ │ └── GenerateCommitMessageAction.kt │ │ └── mcp │ │ └── McpSessionAttachment.kt │ ├── resources │ ├── icons │ │ ├── qwen.png │ │ ├── deepseek.png │ │ ├── greenCheckmark.svg │ │ ├── greenCheckmark_dark.svg │ │ ├── relace.svg │ │ ├── relace_dark.svg │ │ ├── expandAll.svg │ │ ├── collapseAll.svg │ │ ├── expandAll_dark.svg │ │ ├── collapseAll_dark.svg │ │ ├── listFiles.svg │ │ ├── vcs.svg │ │ ├── vcs_dark.svg │ │ ├── listFiles_dark.svg │ │ ├── inception.svg │ │ ├── inception_dark.svg │ │ ├── google.svg │ │ ├── locked.svg │ │ ├── locked_dark.svg │ │ ├── openNewTab.svg │ │ ├── openNewTab_dark.svg │ │ ├── sendToTheLeft.svg │ │ ├── sendToTheLeft_dark.svg │ │ ├── user_dark.svg │ │ ├── user.svg │ │ ├── lightning.svg │ │ ├── lightning_dark.svg │ │ ├── lighting_disabled.svg │ │ ├── addFile.svg │ │ ├── addFile_dark.svg │ │ ├── anthropic.svg │ │ ├── dbrx.svg │ │ ├── upload.svg │ │ ├── upload_dark.svg │ │ ├── codegpt-model.svg │ │ ├── codegpt-model_dark.svg │ │ ├── mcp.svg │ │ ├── mcp_dark.svg │ │ ├── tree.svg │ │ ├── send.svg │ │ ├── send_dark.svg │ │ ├── inSelection.svg │ │ └── inSelection_dark.svg │ ├── META-INF │ │ ├── plugin-cpp.xml │ │ ├── plugin-javascript.xml │ │ ├── plugin-kotlin.xml │ │ ├── plugin-python.xml │ │ └── plugin-java.xml │ └── prompts │ │ ├── core │ │ ├── generate-name-lookups.txt │ │ ├── generate-commit-message.txt │ │ ├── fix-compile-errors.txt │ │ └── edit-code-ask-mode.txt │ │ └── chat │ │ ├── write-tests.txt │ │ ├── explain.txt │ │ ├── find-bugs.txt │ │ ├── optimize.txt │ │ └── refactor.txt │ ├── java │ └── ee │ │ └── carlrobert │ │ └── codegpt │ │ ├── completions │ │ ├── TotalUsageExceededException.java │ │ ├── llama │ │ │ ├── LlamaServerMessage.java │ │ │ └── LlamaServerStartupParams.java │ │ ├── ConversationType.java │ │ └── CompletionResponseEventListener.java │ │ ├── settings │ │ ├── service │ │ │ ├── FeatureType.java │ │ │ ├── llama │ │ │ │ └── form │ │ │ │ │ ├── InfillPromptTemplatePanel.java │ │ │ │ │ └── ChatPromptTemplatePanel.java │ │ │ ├── mistral │ │ │ │ ├── MistralSettingsState.java │ │ │ │ └── MistralSettings.java │ │ │ ├── openai │ │ │ │ └── OpenAISettings.java │ │ │ └── anthropic │ │ │ │ └── AnthropicSettings.java │ │ ├── IncludedFilesSettingsState.java │ │ ├── GeneralSettings.java │ │ ├── advanced │ │ │ └── AdvancedSettings.java │ │ ├── GeneralSettingsComponent.java │ │ ├── GeneralSettingsState.java │ │ ├── IncludedFilesSettings.java │ │ └── GeneralSettingsConfigurable.java │ │ ├── toolwindow │ │ └── chat │ │ │ ├── ui │ │ │ └── textarea │ │ │ │ └── AttachImageNotifier.java │ │ │ ├── ChatToolWindowType.java │ │ │ ├── structure │ │ │ └── data │ │ │ │ └── PsiStructureState.kt │ │ │ ├── ChatSession.java │ │ │ └── editor │ │ │ └── actions │ │ │ └── EditAction.java │ │ ├── conversations │ │ ├── converter │ │ │ ├── ConversationConverter.java │ │ │ ├── ConversationsConverter.java │ │ │ └── ConversationListConverter.java │ │ └── ConversationsContainer.java │ │ ├── actions │ │ ├── ActionType.java │ │ ├── toolwindow │ │ │ ├── ClearChatTagsAction.kt │ │ │ ├── MoveUpAction.java │ │ │ ├── MoveDownAction.java │ │ │ ├── CreateNewConversationAction.java │ │ │ └── ClearChatWindowAction.java │ │ ├── OpenSettingsAction.java │ │ ├── TrackableAction.java │ │ └── editor │ │ │ └── OpenNewChatAction.java │ │ ├── CodeGPTBundle.java │ │ ├── ui │ │ ├── checkbox │ │ │ ├── FileCheckboxTreeCellRenderer.java │ │ │ └── FileCheckboxTree.java │ │ ├── IconActionButton.java │ │ └── ModelIconLabel.java │ │ ├── util │ │ ├── EditWindowConfig.java │ │ └── CommitWorkflowChanges.java │ │ ├── statusbar │ │ └── CodeGPTStatusBarWidgetFactory.java │ │ └── CodeGPTPlugin.java │ └── proto │ ├── next-edit.proto │ └── code-completion.proto ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── feature_request.yml │ └── bug_report.yml └── dependabot.yml ├── gradle-win-arm64.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle.kts ├── .gitmodules ├── codegpt-telemetry ├── src │ └── main │ │ ├── resources │ │ ├── segment.properties │ │ └── segment-defaults.properties │ │ └── java │ │ └── ee │ │ └── carlrobert │ │ └── codegpt │ │ └── telemetry │ │ ├── TelemetryMessageProvider.java │ │ ├── TelemetryAction.java │ │ └── core │ │ ├── configuration │ │ ├── IConfiguration.java │ │ ├── SystemProperties.java │ │ ├── AbstractConfiguration.java │ │ └── ClasspathConfiguration.java │ │ ├── service │ │ └── segment │ │ │ ├── ISegmentConfiguration.java │ │ │ └── IdentifyTraits.java │ │ ├── ITelemetryService.java │ │ ├── IMessageBroker.java │ │ └── util │ │ ├── Directories.java │ │ └── Lazy.java ├── README.md └── build.gradle.kts ├── config └── checkstyle │ └── suppressions.xml └── .gitignore /src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.gif filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true -------------------------------------------------------------------------------- /gradle-win-arm64.properties: -------------------------------------------------------------------------------- 1 | platformVersion = 2023.1 2 | javaVersion = 17 -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/remote/ConfigSyncService.kt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/kotlin/ee/carlrobert/codegpt/settings/remote/ConfigChangeCollectorTest.kt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/kotlin/ee/carlrobert/codegpt/toolwindow/chat/CompleteOutputParserTest.kt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/kotlin/ee/carlrobert/codegpt/toolwindow/chat/StreamOutputParserTest.kt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/kotlin/ee/carlrobert/codegpt/settings/remote/RemoteSettingsFormIntegrationTest.kt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/test/kotlin/ee/carlrobert/codegpt/settings/service/custom/form/CustomServiceListFormTest.kt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/carlrobertoh/ProxyAI/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "CodeGPT" 2 | include(":codegpt-treesitter") 3 | include(":codegpt-telemetry") 4 | -------------------------------------------------------------------------------- /src/main/resources/icons/qwen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/carlrobertoh/ProxyAI/HEAD/src/main/resources/icons/qwen.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "llama.cpp"] 2 | path = src/main/cpp/llama.cpp 3 | url = https://github.com/ggerganov/llama.cpp 4 | -------------------------------------------------------------------------------- /src/main/resources/icons/deepseek.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/carlrobertoh/ProxyAI/HEAD/src/main/resources/icons/deepseek.png -------------------------------------------------------------------------------- /src/test/resources/indexes/hnsw.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/carlrobertoh/ProxyAI/HEAD/src/test/resources/indexes/hnsw.index -------------------------------------------------------------------------------- /src/test/resources/images/test-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/carlrobertoh/ProxyAI/HEAD/src/test/resources/images/test-image.png -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/resources/segment.properties: -------------------------------------------------------------------------------- 1 | writeKey=2WKbksXZRM3HXxD9XdE9fUL2rhT 2 | debugWriteKey=2WKbksXZRM3HXxD9XdE9fUL2rhT 3 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/plugin-cpp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/resources/segment-defaults.properties: -------------------------------------------------------------------------------- 1 | writeKey=JO2CLEDKOdQklP9TKKVuUyONel5H2RXk 2 | debugWriteKey=JO2CLEDKOdQklP9TKKVuUyONel5H2RXk 3 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/plugin-javascript.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/test/resources/inline/TestClass.java: -------------------------------------------------------------------------------- 1 | public class TestClass { 2 | 3 | public static void myTestMethod() { 4 | System.out.println("Hello world"); 5 | } 6 | } -------------------------------------------------------------------------------- /codegpt-telemetry/README.md: -------------------------------------------------------------------------------- 1 | ## ProxyAI Telemetry 2 | 3 | Telemetry implementation based on [Red Hat Telemetry](https://github.com/redhat-developer/intellij-redhat-telemetry) plugin 4 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/psistructure/models/ClassLanguage.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.psistructure.models 2 | 3 | enum class ClassLanguage { 4 | KOTLIN, 5 | } 6 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/psistructure/models/ClassName.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.psistructure.models 2 | 3 | @JvmInline 4 | value class ClassName(val value: String) 5 | -------------------------------------------------------------------------------- /codegpt-telemetry/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("codegpt.java-conventions") 3 | } 4 | 5 | dependencies { 6 | implementation(libs.analytics) 7 | implementation(libs.gson) 8 | } 9 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/psistructure/models/EnumEntryName.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.psistructure.models 2 | 3 | @JvmInline 4 | value class EnumEntryName(val value: String) 5 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/inlineedit/engine/ApplyStrategy.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.inlineedit.engine 2 | 3 | interface ApplyStrategy { 4 | fun apply(ctx: ApplyContext) 5 | } 6 | 7 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/completions/TotalUsageExceededException.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.completions; 2 | 3 | public class TotalUsageExceededException extends RuntimeException { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/DialogResult.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service 2 | 3 | enum class DialogResult { 4 | APPLY_MODELS, 5 | KEEP_MODELS, 6 | CANCEL_ALL 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/parser/MessageParser.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.chat.parser 2 | 3 | interface MessageParser { 4 | 5 | fun parse(input: String): List 6 | } -------------------------------------------------------------------------------- /src/main/resources/prompts/core/generate-name-lookups.txt: -------------------------------------------------------------------------------- 1 | Provide five alternative names for a given function or method body. Your response should be a list of names, separated by commas, without any extra information. 2 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/psistructure/models/ClassType.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.psistructure.models 2 | 3 | enum class ClassType { 4 | ENUM, 5 | CLASS, 6 | OBJECT, 7 | COMPANION_OBJECT, 8 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/util/file/FileExtensionLanguageDetails.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util.file 2 | 3 | @JvmRecord 4 | data class FileExtensionLanguageDetails(val extension: String, val value: String) 5 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/psistructure/PsiDepthFile.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.psistructure 2 | 3 | import com.intellij.psi.PsiFile 4 | 5 | data class PsiDepthFile( 6 | val psiFile: PsiFile, 7 | val depth: Int, 8 | ) -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/util/file/LanguageFileExtensionDetails.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util.file 2 | 3 | @JvmRecord 4 | data class LanguageFileExtensionDetails(val name: String, val type: String, val extensions: List?) 5 | -------------------------------------------------------------------------------- /src/main/resources/icons/greenCheckmark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/psistructure/models/FieldStructure.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.psistructure.models 2 | 3 | data class FieldStructure( 4 | val name: String, 5 | val type: ClassName, 6 | val modifiers: List, 7 | ) 8 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/psistructure/models/ParameterInfo.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.psistructure.models 2 | 3 | data class ParameterInfo( 4 | val name: String, 5 | val type: ClassName, 6 | val modifiers: List, 7 | ) 8 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/custom/form/model/CustomServicesStateData.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.custom.form.model 2 | 3 | data class CustomServicesStateData(val services: List) 4 | -------------------------------------------------------------------------------- /src/main/resources/icons/greenCheckmark_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/psistructure/models/ConstructorStructure.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.psistructure.models 2 | 3 | data class ConstructorStructure( 4 | val parameters: List, 5 | val modifiers: List, 6 | ) 7 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/plugin-kotlin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/plugin-python.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/TagProcessor.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea 2 | 3 | import ee.carlrobert.codegpt.conversations.message.Message 4 | 5 | fun interface TagProcessor { 6 | fun process(message: Message, promptBuilder: StringBuilder) 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/service/FeatureType.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service; 2 | 3 | public enum FeatureType { 4 | CHAT, 5 | CODE_COMPLETION, 6 | AUTO_APPLY, 7 | COMMIT_MESSAGE, 8 | INLINE_EDIT, 9 | NEXT_EDIT, 10 | LOOKUP 11 | } 12 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/nextedit/NextEditProvider.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.nextedit 2 | 3 | import com.intellij.openapi.editor.Editor 4 | 5 | interface NextEditProvider { 6 | fun request(editor: Editor, fileContent: String, caretOffset: Int, addToQueue: Boolean) 7 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/ToolWindowEditorFileDetails.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.chat.editor 2 | 3 | import com.intellij.openapi.vfs.VirtualFile 4 | 5 | data class ToolWindowEditorFileDetails(val path: String, val virtualFile: VirtualFile? = null) -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/psistructure/models/MethodStructure.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.psistructure.models 2 | 3 | data class MethodStructure( 4 | val name: String, 5 | val returnType: ClassName, 6 | val parameters: List, 7 | val modifiers: List, 8 | ) 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /src/main/resources/prompts/core/generate-commit-message.txt: -------------------------------------------------------------------------------- 1 | Branch: {BRANCH_NAME} 2 | Date: {DATE_ISO_8601} 3 | 4 | Write a short and descriptive git commit message for the following git diff. 5 | Use imperative mood, present tense, active voice and verbs. 6 | Your entire response will be passed directly into git commit. -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerMessage.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.completions.llama; 2 | 3 | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 4 | 5 | @JsonIgnoreProperties(ignoreUnknown = true) 6 | public record LlamaServerMessage(String level, String msg) { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/prompts/core/fix-compile-errors.txt: -------------------------------------------------------------------------------- 1 | I will provide you with a snippet of code that is causing a compilation error. 2 | Your task is to identify the potential causes of the compilation error(s) and propose code solutions to fix them. 3 | Please approach this step by step, explaining your reasoning as you go. -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/completions/ConversationType.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.completions; 2 | 3 | public enum ConversationType { 4 | CUSTOM_PROMPT, 5 | DEFAULT, 6 | EDITOR_ACTION, 7 | FIX_COMPILE_ERRORS, 8 | MULTI_FILE, 9 | INLINE_COMPLETION, 10 | INLINE_EDIT, 11 | REVIEW_CHANGES 12 | } 13 | -------------------------------------------------------------------------------- /src/test/resources/codecompletions/psi/python.txt: -------------------------------------------------------------------------------- 1 | import random 2 | from typing import List 3 | 4 | class Util: 5 | 6 | test: str = "" 7 | 8 | def __init__(self, test: str): 9 | self.test = test 10 | 11 | def randomStrings(n: int) -> List[str]: 12 | return [str(random.randint(0, 100)) for _ in range(n)] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/custom/form/model/CustomServiceChatCompletionSettingsData.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.custom.form.model 2 | 3 | data class CustomServiceChatCompletionSettingsData( 4 | val url: String?, 5 | val headers: Map, 6 | val body: Map 7 | ) 8 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/completions/llama/logging/ServerLoggingStrategy.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.completions.llama.logging 2 | 3 | interface ServerLoggingStrategy { 4 | fun logMessage(message: String, isError: Boolean, isBuildLog: Boolean = false) 5 | fun setPhase(phase: String) 6 | fun startProgress() 7 | fun stopProgress() 8 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/inlineedit/engine/InlineEditEngine.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.inlineedit.engine 2 | 3 | interface InlineEditEngine { 4 | fun apply(ctx: ApplyContext) 5 | } 6 | 7 | class InlineEditEngineImpl : InlineEditEngine { 8 | override fun apply(ctx: ApplyContext) { 9 | InlineEditApplyStrategyFactory.get().apply(ctx) 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/tag/TagManagerListener.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.header.tag 2 | 3 | import com.intellij.openapi.editor.SelectionModel 4 | 5 | interface TagManagerListener { 6 | fun onTagAdded(tag: TagDetails) 7 | fun onTagRemoved(tag: TagDetails) 8 | fun onTagSelectionChanged(tag: TagDetails, selectionModel: SelectionModel) 9 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/util/MapConverter.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util 2 | 3 | import com.fasterxml.jackson.core.type.TypeReference 4 | 5 | class MapConverter : 6 | BaseConverter>(object : TypeReference>() {}) { 7 | override fun fromString(value: String): Map? { 8 | return super.fromString(value) ?: emptyMap() 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/icons/relace.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/resources/icons/relace_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/ProviderChangeNotifier.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service 2 | 3 | import com.intellij.util.messages.Topic 4 | 5 | interface ProviderChangeNotifier { 6 | 7 | fun providerChanged(provider: ServiceType) 8 | 9 | companion object { 10 | @JvmStatic 11 | val TOPIC = Topic.create("providerChange", ProviderChangeNotifier::class.java) 12 | } 13 | } -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ui/textarea/AttachImageNotifier.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.chat.ui.textarea; 2 | 3 | import com.intellij.util.messages.Topic; 4 | 5 | public interface AttachImageNotifier { 6 | 7 | Topic IMAGE_ATTACHMENT_FILE_PATH_TOPIC = 8 | Topic.create("imageAttachmentFilePath", AttachImageNotifier.class); 9 | 10 | void imageAttached(String filePath); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowType.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.chat; 2 | 3 | public enum ChatToolWindowType { 4 | CODEGPT_CHAT("CodeGPT Chat"), 5 | CODEGPT_CHAT_WITHOUT_PERSONA("CodeGPT Chat without Persona"), 6 | CODEGPT_CHAT_WITH_PERSONA("CodeGPT Chat with Persona"); 7 | 8 | private final String name; 9 | 10 | ChatToolWindowType(String name) { 11 | this.name = name; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/prompts/chat/write-tests.txt: -------------------------------------------------------------------------------- 1 | Your task is to create concise, effective tests for the given code. 2 | 3 | Generate unit tests for the provided code. Focus on: 4 | 1. Testing main functionalities 5 | 2. Edge cases 6 | 3. Input validation 7 | 8 | Provide your test code in the same language as the original code. Use common testing frameworks and assertions appropriate for the language. 9 | 10 | Here's the code to write tests for: 11 | {SELECTION} -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/autoimport/AutoImportResolver.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.autoimport 2 | 3 | import com.intellij.openapi.util.TextRange 4 | import com.intellij.psi.PsiFile 5 | 6 | interface AutoImportResolver { 7 | fun supports(file: PsiFile): Boolean 8 | fun getUnresolvedImports(file: PsiFile, searchRange: TextRange): Map> 9 | fun applyImport(file: PsiFile, importFqn: String): Boolean 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/icons/expandAll.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/icons/collapseAll.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/icons/expandAll_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/icons/collapseAll_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/plugin-java.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/test/resources/codecompletions/psi/java.txt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions; 2 | 3 | import java.util.List; 4 | import java.util.stream.IntStream; 5 | 6 | public class Util { 7 | 8 | private final String test; 9 | 10 | 11 | public Util(String test) { 12 | this.test = test; 13 | } 14 | 15 | public List randomStrings(int number) { 16 | 17 | return IntStream.range(0, number).mapToObj(i -> Math.floor(100 * Math.random()) + "").toList(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/conversations/converter/ConversationConverter.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.conversations.converter; 2 | 3 | import com.fasterxml.jackson.core.type.TypeReference; 4 | import ee.carlrobert.codegpt.conversations.Conversation; 5 | import ee.carlrobert.codegpt.util.BaseConverter; 6 | 7 | public class ConversationConverter extends BaseConverter { 8 | 9 | public ConversationConverter() { 10 | super(new TypeReference<>() {}); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/actions/ActionType.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions; 2 | 3 | public enum ActionType { 4 | 5 | CLEAR_CHAT_WINDOW, 6 | CREATE_NEW_CHAT, 7 | DELETE_ALL_CONVERSATIONS, 8 | DELETE_CONVERSATION, 9 | DISCARD_TOKEN_LIMIT, 10 | OPEN_CONVERSATION_IN_EDITOR, 11 | DIFF_CODE, 12 | INLINE_EDIT, 13 | CREATE_NEW_FILE, 14 | COPY_CODE, 15 | AUTO_APPLY, 16 | REPLACE_IN_MAIN_EDITOR, 17 | INSERT_AT_CARET, 18 | RELOAD_MESSAGE, 19 | CHANGE_PROVIDER 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/codecompletions/psi/LanguageContextFinder.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.codecompletions.psi 2 | 3 | import com.intellij.psi.PsiElement 4 | import ee.carlrobert.codegpt.codecompletions.InfillContext 5 | 6 | interface LanguageContextFinder { 7 | /** 8 | * Determines relevant enclosing [PsiElement] and [PsiElement]s relevant to the context and returns their source code [PsiElement]. 9 | */ 10 | fun findContext(psiElement: PsiElement): InfillContext 11 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/configuration/ConfigurationStateListener.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.configuration 2 | 3 | import com.intellij.util.messages.Topic 4 | 5 | fun interface ConfigurationStateListener { 6 | fun onConfigurationChanged(newState: ConfigurationSettingsState) 7 | 8 | companion object { 9 | val TOPIC: Topic = 10 | Topic.create("Configuration Changed", ConfigurationStateListener::class.java) 11 | } 12 | } -------------------------------------------------------------------------------- /src/main/resources/prompts/chat/explain.txt: -------------------------------------------------------------------------------- 1 | Your task is to provide a clear, concise explanation of what this code does. Focus on the main functionality and purpose of the code, avoiding unnecessary details. Explain any complex logic or algorithms if present. 2 | 3 | Provide your explanation in a few sentences, using simple language that a junior programmer could understand. If there are any notable best practices or potential improvements, briefly mention them at the end. 4 | 5 | Here's the code to analyze: 6 | {SELECTION} -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/conversations/converter/ConversationsConverter.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.conversations.converter; 2 | 3 | import com.fasterxml.jackson.core.type.TypeReference; 4 | import ee.carlrobert.codegpt.conversations.ConversationsContainer; 5 | import ee.carlrobert.codegpt.util.BaseConverter; 6 | 7 | public class ConversationsConverter extends BaseConverter { 8 | 9 | public ConversationsConverter() { 10 | super(new TypeReference<>() {}); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/codecompletions/psi/PsiUtil.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.codecompletions.psi 2 | 3 | import com.intellij.openapi.application.ApplicationManager 4 | import com.intellij.psi.PsiElement 5 | 6 | 7 | fun PsiElement.filePath(): String { 8 | return ApplicationManager.getApplication() 9 | .runReadAction { this.containingFile.virtualFile.path } 10 | } 11 | 12 | fun PsiElement.readText(): String { 13 | return ApplicationManager.getApplication().runReadAction { this.text } 14 | } -------------------------------------------------------------------------------- /src/main/resources/icons/listFiles.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/icons/vcs.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/resources/icons/vcs_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/inlineedit/engine/ApplyContext.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.inlineedit.engine 2 | 3 | import com.intellij.openapi.editor.ex.EditorEx 4 | import ee.carlrobert.codegpt.inlineedit.InlineEditInlay 5 | import ee.carlrobert.codegpt.inlineedit.InlineEditSubmissionHandler 6 | 7 | data class ApplyContext( 8 | val editor: EditorEx, 9 | val inlay: InlineEditInlay, 10 | val submissionHandler: InlineEditSubmissionHandler, 11 | val promptText: String, 12 | val lastAssistantResponse: String 13 | ) 14 | 15 | -------------------------------------------------------------------------------- /src/main/resources/icons/listFiles_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/completions/llama/LlamaServerStartupParams.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.completions.llama; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public record LlamaServerStartupParams(String modelPath, int contextLength, int threads, int port, 7 | List additionalRunParameters, 8 | List additionalBuildParameters, 9 | Map additionalEnvironmentVariables) { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTUserDetailsNotifier.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.codegpt 2 | 3 | import com.intellij.util.messages.Topic 4 | import ee.carlrobert.llm.client.codegpt.CodeGPTUserDetails 5 | 6 | interface CodeGPTUserDetailsNotifier { 7 | fun userDetailsObtained(userDetails: CodeGPTUserDetails?) 8 | 9 | companion object { 10 | @JvmStatic 11 | val CODEGPT_USER_DETAILS_TOPIC = 12 | Topic.create("codegptUserDetails", CodeGPTUserDetailsNotifier::class.java) 13 | } 14 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/custom/form/model/CustomServiceCodeCompletionSettingsData.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.custom.form.model 2 | 3 | import ee.carlrobert.codegpt.codecompletions.InfillPromptTemplate 4 | 5 | data class CustomServiceCodeCompletionSettingsData( 6 | val codeCompletionsEnabled: Boolean, 7 | val parseResponseAsChatCompletions: Boolean, 8 | val infillTemplate: InfillPromptTemplate, 9 | val url: String?, 10 | val headers: Map, 11 | val body: Map 12 | ) 13 | -------------------------------------------------------------------------------- /config/checkstyle/suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 11 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/state/EditorState.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.chat.editor.state 2 | 3 | import com.intellij.openapi.editor.ex.EditorEx 4 | import com.intellij.openapi.project.Project 5 | import ee.carlrobert.codegpt.toolwindow.chat.parser.Segment 6 | import javax.swing.JComponent 7 | 8 | interface EditorState { 9 | val editor: EditorEx 10 | val segment: Segment 11 | val project: Project 12 | 13 | fun updateContent(segment: Segment) 14 | fun createHeaderComponent(readOnly: Boolean): JComponent? 15 | } 16 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/google/GoogleSettings.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.google 2 | 3 | import com.intellij.openapi.components.* 4 | import ee.carlrobert.llm.client.google.models.GoogleModel 5 | 6 | @Service 7 | @State(name = "CodeGPT_GoogleSettings_210", storages = [Storage("CodeGPT_GoogleSettings_210.xml")]) 8 | class GoogleSettings : SimplePersistentStateComponent(GoogleSettingsState()) 9 | 10 | class GoogleSettingsState : BaseState() { 11 | var model by string(GoogleModel.GEMINI_2_5_PRO.code) 12 | } 13 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/completions/llama/logging/NoOpLoggingStrategy.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.completions.llama.logging 2 | 3 | object NoOpLoggingStrategy : ServerLoggingStrategy { 4 | override fun logMessage(message: String, isError: Boolean, isBuildLog: Boolean) { 5 | // No-op: silent logging for headless operations 6 | } 7 | 8 | override fun setPhase(phase: String) { 9 | // No-op 10 | } 11 | 12 | override fun startProgress() { 13 | // No-op 14 | } 15 | 16 | override fun stopProgress() { 17 | // No-op 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/completions/ToolApprovalMode.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.completions 2 | 3 | /** 4 | * Defines how tool calls should be approved during chat completion. 5 | */ 6 | enum class ToolApprovalMode { 7 | /** 8 | * All tool calls are automatically approved without user interaction. 9 | */ 10 | AUTO_APPROVE, 11 | 12 | /** 13 | * Each tool call requires explicit user approval before execution. 14 | */ 15 | REQUIRE_APPROVAL, 16 | 17 | /** 18 | * Tool calls are blocked and not executed. 19 | */ 20 | BLOCK_ALL 21 | } -------------------------------------------------------------------------------- /src/main/resources/prompts/chat/find-bugs.txt: -------------------------------------------------------------------------------- 1 | Your task is to find potential bugs in the given code snippet. 2 | 3 | Carefully examine the code for potential bugs, logical errors, or common programming mistakes. Consider issues such as: 4 | - Syntax errors 5 | - Off-by-one errors 6 | - Null pointer exceptions 7 | - Memory leaks 8 | - Infinite loops 9 | - Incorrect logic 10 | - Unhandled exceptions 11 | 12 | Provide a concise list of potential bugs you've identified. If you don't find any bugs, state that the code appears to be bug-free based on your analysis. 13 | 14 | Here's the code to analyze: 15 | {SELECTION} -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/llama/form/ServerButtonConfig.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.llama.form 2 | 3 | import com.intellij.ui.PortField 4 | import com.intellij.ui.components.JBTextField 5 | import com.intellij.ui.components.fields.IntegerField 6 | 7 | data class ServerButtonConfig( 8 | val portField: PortField, 9 | val contextSizeField: IntegerField, 10 | val threadsField: IntegerField, 11 | val additionalParametersField: JBTextField, 12 | val additionalBuildParametersField: JBTextField, 13 | val additionalEnvironmentVariablesField: JBTextField 14 | ) -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/actions/toolwindow/ClearChatTagsAction.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions.toolwindow 2 | 3 | import com.intellij.openapi.actionSystem.AnAction 4 | import com.intellij.openapi.actionSystem.AnActionEvent 5 | import com.intellij.openapi.project.Project 6 | import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager 7 | 8 | class ClearChatTagsAction : AnAction() { 9 | 10 | override fun actionPerformed(event: AnActionEvent) { 11 | val project: Project = event.project ?: return 12 | project.getService(ChatToolWindowContentManager::class.java).clearAllTags() 13 | } 14 | } -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | 8 | - package-ecosystem: "gradle" 9 | directory: "/" 10 | schedule: 11 | interval: "daily" 12 | 13 | - package-ecosystem: "gradle" 14 | directory: "/buildSrc/src/main/kotlin" # /buildSrc and /codegpt-telemetry use only references 15 | schedule: 16 | interval: "daily" 17 | 18 | - package-ecosystem: "gradle" 19 | directory: "/codegpt-treesitter" 20 | schedule: 21 | interval: "daily" 22 | ignore: 23 | - dependency-name: "*" 24 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/custom/form/model/CustomServiceSettingsData.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.custom.form.model 2 | 3 | import ee.carlrobert.codegpt.settings.service.custom.template.CustomServiceTemplate 4 | import java.util.UUID 5 | 6 | data class CustomServiceSettingsData( 7 | val id: String = UUID.randomUUID().toString(), 8 | val name: String?, 9 | val template: CustomServiceTemplate, 10 | val apiKey: String?, 11 | val chatCompletionSettings: CustomServiceChatCompletionSettingsData, 12 | val codeCompletionSettings: CustomServiceCodeCompletionSettingsData 13 | ) 14 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/conversations/ConversationsContainer.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.conversations; 2 | 3 | import java.util.HashMap; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | public class ConversationsContainer { 8 | 9 | private Map> conversationsMapping = new HashMap<>(); 10 | 11 | public Map> getConversationsMapping() { 12 | return conversationsMapping; 13 | } 14 | 15 | public void setConversationsMapping(Map> conversationsMapping) { 16 | this.conversationsMapping = conversationsMapping; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/resources/icons/inception.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/resources/icons/inception_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/CodeGPTBundle.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt; 2 | 3 | import com.intellij.DynamicBundle; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.PropertyKey; 6 | 7 | public class CodeGPTBundle extends DynamicBundle { 8 | 9 | private static final CodeGPTBundle INSTANCE = new CodeGPTBundle(); 10 | 11 | private CodeGPTBundle() { 12 | super("messages.codegpt"); 13 | } 14 | 15 | public static String get( 16 | @NotNull @PropertyKey(resourceBundle = "messages.codegpt") String key, 17 | Object... params) { 18 | return INSTANCE.getMessage(key, params); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/completions/llama/LlamaConstants.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.completions.llama 2 | 3 | object LlamaConstants { 4 | const val PROGRESS_CMAKE_SETUP = 0.0 5 | const val PROGRESS_CMAKE_BUILD = 0.33 6 | const val PROGRESS_SERVER_START = 0.66 7 | 8 | const val BUILD_PARALLEL_JOBS = 4 9 | const val BUILD_CONFIGURATION = "Release" 10 | const val BUILD_DIRECTORY = "build" 11 | 12 | const val SERVER_EXECUTABLE_PATH = "./build/bin/llama-server" 13 | const val SERVER_LISTENING_MESSAGE = "server is listening" 14 | 15 | const val MAX_LOG_ENTRIES = 10000 16 | const val MAX_LOG_SESSIONS = 5 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/inlineedit/engine/InlineEditApplyStrategyFactory.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.inlineedit.engine 2 | 3 | import ee.carlrobert.codegpt.settings.service.FeatureType 4 | import ee.carlrobert.codegpt.settings.service.ModelSelectionService 5 | import ee.carlrobert.codegpt.settings.service.ServiceType 6 | 7 | object InlineEditApplyStrategyFactory { 8 | fun get(): ApplyStrategy { 9 | val serviceType = ModelSelectionService.getInstance().getServiceForFeature(FeatureType.INLINE_EDIT) 10 | return if (serviceType == ServiceType.PROXYAI) ProxyAIApplyStrategy() else SearchReplaceApplyStrategy() 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/toolwindow/chat/structure/data/PsiStructureState.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.chat.structure.data 2 | 3 | import ee.carlrobert.codegpt.psistructure.models.ClassStructure 4 | import ee.carlrobert.codegpt.ui.textarea.header.tag.TagDetails 5 | 6 | sealed class PsiStructureState { 7 | 8 | data class UpdateInProgress( 9 | val currentlyAnalyzedTags: Set, 10 | ) : PsiStructureState() 11 | 12 | data object Disabled : PsiStructureState() 13 | 14 | data class Content( 15 | val currentlyAnalyzedTags: Set, 16 | val elements: Set 17 | ) : PsiStructureState() 18 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/mcp/form/McpFormUtil.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.mcp.form 2 | 3 | import ee.carlrobert.codegpt.settings.mcp.McpServerDetailsState 4 | import ee.carlrobert.codegpt.settings.mcp.form.details.McpServerDetails 5 | 6 | object McpFormUtil { 7 | fun McpServerDetails.toState(): McpServerDetailsState { 8 | val state = McpServerDetailsState() 9 | state.id = this.id 10 | state.name = this.name 11 | state.command = this.command 12 | state.arguments = this.arguments.toMutableList() 13 | state.environmentVariables = this.environmentVariables.toMutableMap() 14 | return state 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/configuration/ChatMode.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.configuration 2 | 3 | enum class ChatMode( 4 | val displayName: String, 5 | val description: String, 6 | val isEnabled: Boolean = true 7 | ) { 8 | ASK( 9 | displayName = "Ask", 10 | description = "Conversational responses with explanations" 11 | ), 12 | EDIT( 13 | displayName = "Edit", 14 | description = "Code modifications with search/replace blocks" 15 | ), 16 | AGENT( 17 | displayName = "Agent (soon)", 18 | description = "AI agent with tool access and reasoning", 19 | isEnabled = false 20 | ); 21 | } -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/TelemetryMessageProvider.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.telemetry; 2 | 3 | import ee.carlrobert.codegpt.telemetry.core.service.TelemetryMessageBuilder; 4 | import ee.carlrobert.codegpt.telemetry.core.util.Lazy; 5 | 6 | public class TelemetryMessageProvider { 7 | 8 | private static final TelemetryMessageProvider INSTANCE = new TelemetryMessageProvider(); 9 | 10 | private final Lazy builder = new Lazy<>(() -> 11 | new TelemetryMessageBuilder(TelemetryMessageProvider.class.getClassLoader())); 12 | 13 | public static TelemetryMessageBuilder builder() { 14 | return INSTANCE.builder.get(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/main/resources/prompts/core/edit-code-ask-mode.txt: -------------------------------------------------------------------------------- 1 | You are an AI assistant that helps with code editing and modifications. When asked to modify code, provide the complete updated code with your changes applied. 2 | 3 | Guidelines: 4 | 1. Analyze the code to understand its purpose and structure 5 | 2. Apply the requested modifications carefully 6 | 3. Ensure the modified code is complete and functional 7 | 4. Maintain the original formatting and coding style 8 | 5. Include any necessary imports or dependencies 9 | 10 | Format your response as: 11 | ```[language] 12 | [complete modified code] 13 | ``` 14 | 15 | Focus on providing clean, working code that incorporates the requested changes. Be thorough but concise. -------------------------------------------------------------------------------- /src/main/resources/prompts/chat/optimize.txt: -------------------------------------------------------------------------------- 1 | Your task is to improve the code's efficiency, readability, and adherence to best practices without changing its core functionality. 2 | 3 | Analyze the code and suggest optimizations that could improve its performance, readability, or maintainability. Focus on: 4 | 5 | 1. Reducing time complexity 6 | 2. Improving space efficiency 7 | 3. Enhancing code readability 8 | 4. Applying relevant design patterns or coding best practices 9 | 10 | Provide your optimized version of the code, along with brief comments explaining the key changes and their benefits. 11 | 12 | Keep your response concise and focused on the most impactful optimizations. 13 | 14 | Here's the code to optimize: 15 | {SELECTION} -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an idea for this project 3 | labels: ["enhancement"] 4 | body: 5 | 6 | - type: textarea 7 | id: cause 8 | attributes: 9 | label: Describe the need of your request 10 | description: A clear and concise description of what the need or problem is. 11 | 12 | - type: textarea 13 | id: solution 14 | attributes: 15 | label: Proposed solution 16 | description: A clear and concise description of what you want to happen. 17 | 18 | - type: textarea 19 | id: context 20 | attributes: 21 | label: Additional context 22 | description: Add any other context or screenshots about the feature request here. -------------------------------------------------------------------------------- /src/main/resources/icons/google.svg: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/inception/InceptionSettings.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.inception 2 | 3 | import com.intellij.openapi.components.BaseState 4 | import com.intellij.openapi.components.SimplePersistentStateComponent 5 | import com.intellij.openapi.components.State 6 | import com.intellij.openapi.components.Storage 7 | 8 | @State(name = "CodeGPT_InceptionSettings", storages = [Storage("CodeGPT_InceptionSettings.xml")]) 9 | class InceptionSettings : SimplePersistentStateComponent(InceptionSettingsState()) 10 | 11 | class InceptionSettingsState : BaseState() { 12 | var codeCompletionsEnabled by property(true) 13 | var nextEditsEnabled by property(true) 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/LookupUtil.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup 2 | 3 | import com.intellij.codeInsight.completion.PrefixMatcher 4 | import com.intellij.codeInsight.completion.PrioritizedLookupElement 5 | import com.intellij.codeInsight.lookup.impl.LookupImpl 6 | 7 | object LookupUtil { 8 | 9 | fun addLookupItem(lookup: LookupImpl, lookupItem: LookupItem, priority: Double = 5.0) { 10 | if (!lookup.isLookupDisposed) { 11 | lookup.addItem( 12 | PrioritizedLookupElement.withPriority(lookupItem.createLookupElement(), priority), 13 | PrefixMatcher.ALWAYS_TRUE 14 | ) 15 | lookup.refreshUi(true, true) 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/resources/prompts/chat/refactor.txt: -------------------------------------------------------------------------------- 1 | Your task is to improve the code's readability, efficiency, and maintainability without changing its functionality. Follow these steps: 2 | 3 | 1. Analyze the following selected code: 4 | 5 | 2. Identify areas for improvement, such as: 6 | - Simplifying complex logic 7 | - Removing redundant code 8 | - Improving naming conventions 9 | - Enhancing code structure 10 | 11 | 3. Refactor the code, keeping these guidelines in mind: 12 | - Maintain the original functionality 13 | - Follow best practices for the programming language used 14 | - Prioritize readability and maintainability 15 | 16 | Be concise in your explanation, focusing on the most important improvements made. 17 | 18 | Here's the code to refactor: 19 | {SELECTION} -------------------------------------------------------------------------------- /src/main/resources/icons/locked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/icons/locked_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/TelemetryAction.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.telemetry; 2 | 3 | import ee.carlrobert.codegpt.telemetry.core.service.TelemetryMessageBuilder.ActionMessage; 4 | 5 | public enum TelemetryAction { 6 | 7 | COMPLETION("CodeGPT-Completion"), 8 | COMPLETION_ERROR("CodeGPT-Completion-Error"), 9 | IDE_ACTION("CodeGPT-Action"), 10 | IDE_ACTION_ERROR("CodeGPT-Action-Error"), 11 | SETTINGS_CHANGED("CodeGPT-Settings-Changed"); 12 | 13 | private final String code; 14 | 15 | TelemetryAction(String code) { 16 | this.code = code; 17 | } 18 | 19 | public String getCode() { 20 | return code; 21 | } 22 | 23 | public ActionMessage createActionMessage() { 24 | return TelemetryMessageProvider.builder().action(getCode()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/ui/checkbox/FileCheckboxTreeCellRenderer.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.checkbox; 2 | 3 | import com.intellij.ui.CheckboxTree; 4 | import com.intellij.ui.CheckedTreeNode; 5 | import javax.swing.JTree; 6 | 7 | public abstract class FileCheckboxTreeCellRenderer extends CheckboxTree.CheckboxTreeCellRenderer { 8 | 9 | abstract void updatePresentation(Object userObject); 10 | 11 | @Override 12 | public void customizeRenderer( 13 | JTree tree, 14 | Object value, 15 | boolean selected, 16 | boolean expanded, 17 | boolean leaf, 18 | int row, 19 | boolean hasFocus) { 20 | if (!(value instanceof CheckedTreeNode)) { 21 | return; 22 | } 23 | 24 | updatePresentation(((CheckedTreeNode) value).getUserObject()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/util/coroutines/DisposableCoroutineScope.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util.coroutines 2 | 3 | import com.intellij.openapi.Disposable 4 | import kotlinx.coroutines.* 5 | import kotlin.coroutines.CoroutineContext 6 | 7 | internal class DisposableCoroutineScope( 8 | scopeDispatcher: CoroutineDispatcher = EdtDispatchers.Default 9 | ) : Disposable, CoroutineScope { 10 | 11 | private val coroutineScope = CoroutineScope(SupervisorJob() + scopeDispatcher) 12 | 13 | fun launch(block: suspend CoroutineScope.() -> Unit): Job = 14 | coroutineScope.launch { block() } 15 | 16 | 17 | override fun dispose() { 18 | coroutineScope.cancel() 19 | } 20 | 21 | override val coroutineContext: CoroutineContext 22 | get() = coroutineScope.coroutineContext 23 | } -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/conversations/converter/ConversationListConverter.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.conversations.converter; 2 | 3 | import com.fasterxml.jackson.core.type.TypeReference; 4 | import ee.carlrobert.codegpt.conversations.Conversation; 5 | import ee.carlrobert.codegpt.util.BaseConverter; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | public class ConversationListConverter extends BaseConverter> { 11 | 12 | public ConversationListConverter() { 13 | super(new TypeReference<>() {}); 14 | } 15 | 16 | @Override 17 | public List fromString(@NotNull String value) { 18 | List result = super.fromString(value); 19 | return result != null ? result : new ArrayList<>(); 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/util/coroutines/EdtCoroutineDispatcherExtensions.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util.coroutines 2 | 3 | import com.intellij.openapi.application.ModalityState 4 | import kotlinx.coroutines.CoroutineScope 5 | import kotlinx.coroutines.withContext 6 | 7 | suspend fun withEdt( 8 | modalityState: ModalityState = ModalityState.defaultModalityState(), 9 | block: suspend CoroutineScope.() -> T, 10 | ): T { 11 | return withContext(EdtDispatchers.withModalityState(modalityState), block) 12 | } 13 | 14 | suspend fun withCurrentEdt(block: suspend CoroutineScope.() -> T): T { 15 | return withContext(EdtDispatchers.Current, block) 16 | } 17 | 18 | suspend fun withNonModalEdt(block: suspend CoroutineScope.() -> T): T { 19 | return withContext(EdtDispatchers.NonModal, block) 20 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/tokens/TokenComputationService.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.tokens 2 | 3 | import com.intellij.openapi.application.ApplicationManager 4 | import com.intellij.openapi.components.Service 5 | import ee.carlrobert.codegpt.EncodingManager 6 | 7 | @Service 8 | class TokenComputationService { 9 | private val encodingManager = EncodingManager.getInstance() 10 | 11 | fun countTextTokens(text: String?): Int { 12 | if (text.isNullOrEmpty()) return 0 13 | return encodingManager.countTokens(text) 14 | } 15 | 16 | fun estimateTokensByLength(length: Int): Int = length / 4 17 | 18 | companion object { 19 | fun getInstance(): TokenComputationService = 20 | ApplicationManager.getApplication().getService(TokenComputationService::class.java) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/resources/icons/openNewTab.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/core/configuration/IConfiguration.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at http://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package ee.carlrobert.codegpt.telemetry.core.configuration; 12 | 13 | public interface IConfiguration { 14 | String get(String key); 15 | void put(String key, String value); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/util/EditWindowConfig.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util; 2 | 3 | public final class EditWindowConfig { 4 | public final int editAbove; 5 | public final int editBelow; 6 | public final int fullAbove; 7 | public final int fullBelow; 8 | 9 | public EditWindowConfig(int editAbove, int editBelow, int fullAbove, int fullBelow) { 10 | if (editAbove < 0 || editBelow < 0 || fullAbove < 0 || fullBelow < 0) { 11 | throw new IllegalArgumentException("window sizes must be non-negative"); 12 | } 13 | this.editAbove = editAbove; 14 | this.editBelow = editBelow; 15 | this.fullAbove = fullAbove; 16 | this.fullBelow = fullBelow; 17 | } 18 | 19 | public static EditWindowConfig defaults() { 20 | return new EditWindowConfig(15, 25, 150, 250); 21 | 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/main/resources/icons/openNewTab_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/core/service/segment/ISegmentConfiguration.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at http://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package ee.carlrobert.codegpt.telemetry.core.service.segment; 12 | 13 | public interface ISegmentConfiguration { 14 | String getNormalWriteKey(); 15 | String getDebugWriteKey(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/mcp/McpConfigurable.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.mcp 2 | 3 | import com.intellij.openapi.options.Configurable 4 | import ee.carlrobert.codegpt.settings.mcp.form.McpForm 5 | import javax.swing.JComponent 6 | 7 | class McpConfigurable : Configurable { 8 | 9 | private lateinit var component: McpForm 10 | 11 | override fun getDisplayName(): String { 12 | return "ProxyAI: MCP Servers" 13 | } 14 | 15 | override fun createComponent(): JComponent { 16 | component = McpForm() 17 | return component.createPanel() 18 | } 19 | 20 | override fun isModified(): Boolean = component.isModified() 21 | 22 | override fun apply() { 23 | component.applyChanges() 24 | } 25 | 26 | override fun reset() { 27 | component.resetChanges() 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/resources/icons/sendToTheLeft.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/custom/CustomServicesChangeNotifier.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.custom 2 | 3 | import com.intellij.openapi.diagnostic.thisLogger 4 | 5 | object CustomServicesChangeNotifier { 6 | private val logger = thisLogger() 7 | private val listeners = mutableListOf<() -> Unit>() 8 | 9 | fun addListener(listener: () -> Unit) { 10 | listeners.add(listener) 11 | } 12 | 13 | fun removeListener(listener: () -> Unit) { 14 | listeners.remove(listener) 15 | } 16 | 17 | fun notifyServicesChanged() { 18 | listeners.forEach { listener -> 19 | try { 20 | listener() 21 | } catch (e: Exception) { 22 | logger.error("Error notifying listener", e) 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/util/coroutines/EdtCoroutineDispatcher.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util.coroutines 2 | 3 | import com.intellij.openapi.application.ApplicationManager 4 | import com.intellij.openapi.application.ModalityState 5 | import kotlinx.coroutines.CoroutineDispatcher 6 | import kotlinx.coroutines.Runnable 7 | import kotlin.coroutines.CoroutineContext 8 | 9 | class EdtCoroutineDispatcher( 10 | private val modalityState: ModalityState = ModalityState.defaultModalityState() 11 | ) : CoroutineDispatcher() { 12 | 13 | override fun dispatch(context: CoroutineContext, block: Runnable) { 14 | val app = ApplicationManager.getApplication() 15 | 16 | if (app.isDispatchThread) { 17 | block.run() 18 | } else { 19 | app.invokeLater({ block.run() }, modalityState) 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/resources/icons/sendToTheLeft_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/core/ITelemetryService.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at http://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package ee.carlrobert.codegpt.telemetry.core; 12 | 13 | import ee.carlrobert.codegpt.telemetry.core.service.TelemetryEvent; 14 | 15 | public interface ITelemetryService { 16 | void send(TelemetryEvent event); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/resources/icons/user_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CompletionProgressNotifier.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.codecompletions 2 | 3 | import com.intellij.openapi.project.Project 4 | import com.intellij.util.messages.Topic 5 | import ee.carlrobert.codegpt.CodeGPTKeys 6 | 7 | interface CompletionProgressNotifier { 8 | 9 | fun update() 10 | 11 | companion object { 12 | @JvmStatic 13 | val COMPLETION_PROGRESS_TOPIC = 14 | Topic.create("completionProgressTopic", CompletionProgressNotifier::class.java) 15 | 16 | @JvmStatic 17 | fun update(project: Project, loading: Boolean) { 18 | if (project.isDisposed) return 19 | 20 | CodeGPTKeys.COMPLETION_IN_PROGRESS.set(project, loading) 21 | 22 | project.messageBus.syncPublisher(COMPLETION_PROGRESS_TOPIC)?.update() 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/resources/icons/user.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/core/IMessageBroker.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at http://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package ee.carlrobert.codegpt.telemetry.core; 12 | 13 | import ee.carlrobert.codegpt.telemetry.core.service.TelemetryEvent; 14 | 15 | public interface IMessageBroker { 16 | void send(TelemetryEvent event); 17 | void dispose(); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/completions/llama/logging/SettingsFormLoggingStrategy.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.completions.llama.logging 2 | 3 | import ee.carlrobert.codegpt.settings.service.llama.form.LlamaSettingsForm 4 | 5 | class SettingsFormLoggingStrategy( 6 | private val settingsForm: LlamaSettingsForm 7 | ) : ServerLoggingStrategy { 8 | 9 | override fun logMessage(message: String, isError: Boolean, isBuildLog: Boolean) { 10 | settingsForm.logToConsole(message, isError, isBuildLog) 11 | } 12 | 13 | override fun setPhase(phase: String) { 14 | settingsForm.updateServerStatusWithPhase(phase) 15 | } 16 | 17 | override fun startProgress() { 18 | settingsForm.updateServerStatusWithPhase("Initializing...") 19 | } 20 | 21 | override fun stopProgress() { 22 | settingsForm.refreshServerStatus() 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/documentation/DocumentationsConfigurable.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.documentation 2 | 3 | import com.intellij.openapi.options.Configurable 4 | import javax.swing.JComponent 5 | 6 | class DocumentationsConfigurable : Configurable { 7 | 8 | private lateinit var component: DocumentationsSettingsForm 9 | 10 | override fun getDisplayName(): String { 11 | return "ProxyAI: Documentations" 12 | } 13 | 14 | override fun createComponent(): JComponent { 15 | component = DocumentationsSettingsForm() 16 | return component.createPanel() 17 | } 18 | 19 | override fun isModified(): Boolean = component.isModified() 20 | 21 | override fun apply() { 22 | component.applyChanges() 23 | } 24 | 25 | override fun reset() { 26 | component.resetChanges() 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/actions/editor/InlineEditAction.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions.editor 2 | 3 | import com.intellij.openapi.application.runInEdt 4 | import com.intellij.openapi.editor.Editor 5 | import com.intellij.openapi.project.Project 6 | import ee.carlrobert.codegpt.Icons 7 | import ee.carlrobert.codegpt.inlineedit.InlineEditInlay 8 | import javax.swing.Icon 9 | 10 | open class InlineEditAction(icon: Icon) : BaseEditorAction(icon) { 11 | override fun actionPerformed(project: Project, editor: Editor, selectedText: String) { 12 | runInEdt { 13 | editor.getUserData(InlineEditInlay.INLAY_KEY)?.dispose() 14 | 15 | InlineEditInlay(editor).show() 16 | } 17 | } 18 | } 19 | 20 | class InlineEditFloatingMenuAction : InlineEditAction(Icons.DefaultSmall) 21 | 22 | class InlineEditContextMenuAction : InlineEditAction(Icons.Sparkle) 23 | -------------------------------------------------------------------------------- /src/main/resources/icons/lightning.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/persona/PersonaSettings.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.persona 2 | 3 | import com.intellij.openapi.components.* 4 | import ee.carlrobert.codegpt.settings.prompts.PersonasState 5 | 6 | @Deprecated("Use PromptsSettings instead") 7 | @Service 8 | @State( 9 | name = "CodeGPT_PersonaSettings", 10 | storages = [Storage("CodeGPT_PersonaSettings.xml")] 11 | ) 12 | class PersonaSettings : 13 | SimplePersistentStateComponent(PersonaSettingsState()) 14 | 15 | class PersonaSettingsState : BaseState() { 16 | var userCreatedPersonas by list() 17 | } 18 | 19 | class PersonaDetailsState : BaseState() { 20 | var id by property(PersonasState.DEFAULT_PERSONA.id) 21 | var name by string(PersonasState.DEFAULT_PERSONA.name) 22 | var instructions by string(PersonasState.DEFAULT_PERSONA.instructions) 23 | } 24 | -------------------------------------------------------------------------------- /src/main/resources/icons/lightning_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/actions/toolwindow/MoveUpAction.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions.toolwindow; 2 | 3 | import com.intellij.icons.AllIcons; 4 | import com.intellij.openapi.project.Project; 5 | import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil; 6 | import ee.carlrobert.codegpt.conversations.Conversation; 7 | import ee.carlrobert.codegpt.conversations.ConversationService; 8 | import java.util.Optional; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class MoveUpAction extends MoveAction { 12 | 13 | public MoveUpAction(Runnable onRefresh) { 14 | super("Move Up", "Move up", AllIcons.Actions.MoveUp, onRefresh); 15 | EditorActionsUtil.registerAction(this); 16 | } 17 | 18 | @Override 19 | protected Optional getConversation(@NotNull Project project) { 20 | return ConversationService.getInstance().getNextConversation(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/resources/codecompletions/code-completion-file.txt: -------------------------------------------------------------------------------- 1 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 2 | zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz 3 | [INPUT] 4 | 5 | [\INPUT] 6 | zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz 7 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/URLTextField.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui 2 | 3 | import com.intellij.ui.components.JBTextField 4 | import java.awt.event.FocusAdapter 5 | import java.awt.event.FocusEvent 6 | 7 | /** 8 | * [JBTextField] that automatically removes all trailing "/" after loosing focus. 9 | */ 10 | class URLTextField : JBTextField { 11 | constructor() : super() 12 | constructor(columns: Int) : super(columns) 13 | constructor(text: String?) : super(text) 14 | constructor(text: String?, columns: Int) : super(text, columns) 15 | 16 | init { 17 | addFocusListener(object : FocusAdapter() { 18 | override fun focusLost(e: FocusEvent) { 19 | val text: String = getText() 20 | if (text.endsWith("/")) { 21 | setText(text.trimEnd('/')) 22 | } 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/action/git/IncludeCurrentChangesActionItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.action.git 2 | 3 | import com.intellij.openapi.project.Project 4 | import ee.carlrobert.codegpt.CodeGPTBundle 5 | import ee.carlrobert.codegpt.ui.textarea.UserInputPanel 6 | import ee.carlrobert.codegpt.ui.textarea.header.tag.CurrentGitChangesTagDetails 7 | import ee.carlrobert.codegpt.ui.textarea.lookup.action.AbstractLookupActionItem 8 | import javax.swing.Icon 9 | 10 | class IncludeCurrentChangesActionItem : AbstractLookupActionItem() { 11 | 12 | override val displayName: String = 13 | CodeGPTBundle.get("suggestionActionItem.includeCurrentChanges.displayName") 14 | override val icon: Icon? = null 15 | 16 | override fun execute(project: Project, userInputPanel: UserInputPanel) { 17 | userInputPanel.addTag(CurrentGitChangesTagDetails()) 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/actions/toolwindow/MoveDownAction.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions.toolwindow; 2 | 3 | import com.intellij.icons.AllIcons; 4 | import com.intellij.openapi.project.Project; 5 | import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil; 6 | import ee.carlrobert.codegpt.conversations.Conversation; 7 | import ee.carlrobert.codegpt.conversations.ConversationService; 8 | import java.util.Optional; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class MoveDownAction extends MoveAction { 12 | 13 | public MoveDownAction(Runnable onRefresh) { 14 | super("Move Down", "Move Down", AllIcons.Actions.MoveDown, onRefresh); 15 | EditorActionsUtil.registerAction(this); 16 | } 17 | 18 | @Override 19 | protected Optional getConversation(@NotNull Project project) { 20 | return ConversationService.getInstance().getPreviousConversation(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/diff/DiffUtil.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.chat.editor.diff 2 | 3 | import com.intellij.diff.tools.fragmented.UnifiedDiffChange 4 | 5 | object DiffUtil { 6 | 7 | fun calculateDiffStats(changes: List): Triple = 8 | changes.fold(Triple(0, 0, 0)) { (ins, del, mod), change -> 9 | val deletedLines = change.lineFragment.endLine1 - change.lineFragment.startLine1 10 | val insertedLines = change.lineFragment.endLine2 - change.lineFragment.startLine2 11 | val minLines = minOf(deletedLines, insertedLines) 12 | val newMod = if (deletedLines > 0 && insertedLines > 0) mod + minLines else mod 13 | val newDel = del + (deletedLines - minLines) 14 | val newIns = ins + (insertedLines - minLines) 15 | Triple(newIns, newDel, newMod) 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/action/personas/PersonaActionItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.action.personas 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.openapi.project.Project 5 | import ee.carlrobert.codegpt.settings.prompts.PersonaDetails 6 | import ee.carlrobert.codegpt.ui.textarea.UserInputPanel 7 | import ee.carlrobert.codegpt.ui.textarea.header.tag.PersonaTagDetails 8 | import ee.carlrobert.codegpt.ui.textarea.lookup.action.AbstractLookupActionItem 9 | 10 | class PersonaActionItem( 11 | private val personaDetails: PersonaDetails 12 | ) : AbstractLookupActionItem() { 13 | 14 | override val displayName = personaDetails.name 15 | override val icon = AllIcons.General.User 16 | 17 | override fun execute(project: Project, userInputPanel: UserInputPanel) { 18 | userInputPanel.addTag(PersonaTagDetails(personaDetails)) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/psistructure/models/ClassStructure.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.psistructure.models 2 | 3 | import com.intellij.openapi.vfs.VirtualFile 4 | 5 | data class ClassStructure( 6 | val name: ClassName, 7 | val virtualFile: VirtualFile, 8 | val simpleName: ClassName, 9 | val classType: ClassType, 10 | val modifierList: List, 11 | val packageName: String, 12 | val repositoryName: String, 13 | val lang: ClassLanguage = ClassLanguage.KOTLIN, 14 | val constructors: MutableList = mutableListOf(), 15 | val fields: MutableList = mutableListOf(), 16 | val methods: MutableList = mutableListOf(), 17 | val supertypes: MutableList = mutableListOf(), 18 | val enumEntries: MutableList = mutableListOf(), 19 | val classes: MutableList = mutableListOf() 20 | ) 21 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/action/AbstractLookupActionItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.action 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement 4 | import com.intellij.codeInsight.lookup.LookupElementPresentation 5 | import ee.carlrobert.codegpt.ui.textarea.lookup.AbstractLookupItem 6 | import ee.carlrobert.codegpt.ui.textarea.lookup.LookupActionItem 7 | import java.util.UUID 8 | 9 | abstract class AbstractLookupActionItem : AbstractLookupItem(), LookupActionItem { 10 | 11 | private val id: UUID = UUID.randomUUID() 12 | 13 | override fun setPresentation(element: LookupElement, presentation: LookupElementPresentation) { 14 | presentation.icon = icon 15 | presentation.itemText = displayName 16 | presentation.isItemTextBold = false 17 | } 18 | 19 | override fun getLookupString(): String { 20 | return "action_${id}" 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/resources/icons/lighting_disabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/core/service/segment/IdentifyTraits.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at http://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package ee.carlrobert.codegpt.telemetry.core.service.segment; 12 | 13 | /** 14 | * Traits that the segment broker sends with am identify event. 15 | */ 16 | public record IdentifyTraits(String locale, String timezone, String osName, String osVersion, String osDistribution) { 17 | } 18 | -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/core/configuration/SystemProperties.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at http://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package ee.carlrobert.codegpt.telemetry.core.configuration; 12 | 13 | import java.util.Properties; 14 | 15 | public class SystemProperties extends AbstractConfiguration { 16 | 17 | @Override 18 | protected Properties loadProperties() { 19 | return System.getProperties(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/core/util/Directories.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2022 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at http://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package ee.carlrobert.codegpt.telemetry.core.util; 12 | 13 | import java.nio.file.Path; 14 | import java.nio.file.Paths; 15 | 16 | public class Directories { 17 | 18 | public static final Path PATH = Paths.get( 19 | System.getProperty("user.home"), 20 | ".codegpt"); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/proto/next-edit.proto: -------------------------------------------------------------------------------- 1 | // src/main/proto/edit.proto 2 | syntax = "proto3"; 3 | option java_multiple_files = true; 4 | option java_package = "ee.carlrobert.service"; 5 | 6 | import "google/protobuf/empty.proto"; 7 | 8 | service NextEditServiceImpl { 9 | rpc NextEdit (NextEditRequest) returns (stream NextEditResponse); 10 | rpc AcceptEdit (AcceptEditRequest) returns (google.protobuf.Empty); 11 | } 12 | 13 | message NextEditRequest { 14 | string file_content = 1; 15 | string file_name = 2; 16 | int32 cursor_position = 3; 17 | string git_diff = 4; 18 | map recently_viewed_files = 5; 19 | string plugin_version = 6; 20 | } 21 | 22 | message NextEditResponse { 23 | string id = 1; 24 | string next_revision = 2; 25 | string old_revision = 3; 26 | } 27 | 28 | message AcceptEditRequest { 29 | string response_id = 1; 30 | string old_hunk = 2; 31 | string new_hunk = 3; 32 | int32 cursor_position = 4; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/ServiceConfigurable.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service 2 | 3 | import com.intellij.openapi.options.Configurable 4 | import javax.swing.JComponent 5 | 6 | class ServiceConfigurable : Configurable { 7 | 8 | private lateinit var component: ServiceConfigurableComponent 9 | 10 | override fun getDisplayName(): String { 11 | return "ProxyAI: Services" 12 | } 13 | 14 | override fun createComponent(): JComponent { 15 | component = ServiceConfigurableComponent() 16 | return component.getPanel() 17 | } 18 | 19 | override fun isModified(): Boolean { 20 | return false 21 | } 22 | 23 | override fun apply() { 24 | // No-op: service selection is now handled per feature in ModelSettings 25 | } 26 | 27 | override fun reset() { 28 | // No-op: service selection is now handled per feature in ModelSettings 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/toolwindow/history/BaseFilterAction.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.history 2 | 3 | import com.intellij.openapi.actionSystem.ActionUpdateThread 4 | import com.intellij.openapi.actionSystem.AnAction 5 | import com.intellij.openapi.actionSystem.AnActionEvent 6 | import com.intellij.openapi.util.Key 7 | import javax.swing.Icon 8 | 9 | abstract class BaseFilterAction( 10 | text: String, 11 | description: String? = null, 12 | icon: Icon? = null 13 | ) : AnAction(text, description, icon) { 14 | 15 | companion object { 16 | val KEY: Key = Key.create("SELECTED_STATE") 17 | } 18 | 19 | override fun getActionUpdateThread(): ActionUpdateThread { 20 | return ActionUpdateThread.BGT 21 | } 22 | 23 | override fun update(e: AnActionEvent) { 24 | e.presentation.putClientProperty(KEY, isSelected()) 25 | } 26 | 27 | abstract fun isSelected(): Boolean 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/action/git/GitCommitActionItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.action.git 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.openapi.project.Project 5 | import ee.carlrobert.codegpt.ui.textarea.UserInputPanel 6 | import ee.carlrobert.codegpt.ui.textarea.header.tag.GitCommitTagDetails 7 | import ee.carlrobert.codegpt.ui.textarea.lookup.action.AbstractLookupActionItem 8 | import git4idea.GitCommit 9 | 10 | class GitCommitActionItem( 11 | private val gitCommit: GitCommit, 12 | ) : AbstractLookupActionItem() { 13 | 14 | val description: String = gitCommit.id.asString().take(6) 15 | 16 | override val displayName: String = gitCommit.subject 17 | override val icon = AllIcons.Vcs.CommitNode 18 | 19 | override fun execute(project: Project, userInputPanel: UserInputPanel) { 20 | userInputPanel.addTag(GitCommitTagDetails(gitCommit)) 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/actions/OpenSettingsAction.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions; 2 | 3 | import com.intellij.icons.AllIcons.General; 4 | import com.intellij.openapi.actionSystem.AnAction; 5 | import com.intellij.openapi.actionSystem.AnActionEvent; 6 | import com.intellij.openapi.options.ShowSettingsUtil; 7 | import ee.carlrobert.codegpt.CodeGPTBundle; 8 | import ee.carlrobert.codegpt.settings.service.ServiceConfigurable; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class OpenSettingsAction extends AnAction { 12 | 13 | public OpenSettingsAction() { 14 | super(CodeGPTBundle.get("action.openSettings.title"), 15 | CodeGPTBundle.get("action.openSettings.description"), 16 | General.Settings); 17 | } 18 | 19 | @Override 20 | public void actionPerformed(@NotNull AnActionEvent e) { 21 | ShowSettingsUtil.getInstance().showSettingsDialog(e.getProject(), ServiceConfigurable.class); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/InfillPromptTemplatePanel.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.llama.form; 2 | 3 | import ee.carlrobert.codegpt.codecompletions.InfillPromptTemplate; 4 | import ee.carlrobert.codegpt.codecompletions.InfillRequest; 5 | 6 | public class InfillPromptTemplatePanel extends BasePromptTemplatePanel { 7 | 8 | public InfillPromptTemplatePanel( 9 | InfillPromptTemplate initiallySelectedTemplate, 10 | boolean enabled) { 11 | super( 12 | InfillPromptTemplate.class, 13 | initiallySelectedTemplate, 14 | enabled, 15 | "settingsConfigurable.service.llama.infillTemplate.comment"); 16 | } 17 | 18 | @Override 19 | protected String buildPromptDescription(InfillPromptTemplate template) { 20 | return template.buildPrompt(new InfillRequest 21 | .Builder("PREFIX", "SUFFIX", 0) 22 | .build()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/editor/ErrorHandler.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.chat.editor 2 | 3 | import com.intellij.notification.NotificationType 4 | import ee.carlrobert.codegpt.ui.OverlayUtil 5 | import ee.carlrobert.llm.client.openai.completion.ErrorDetails 6 | 7 | object ErrorHandler { 8 | 9 | fun handleError(error: ErrorDetails?, ex: Throwable?) { 10 | val errorMessage = formatErrorMessage(error, ex) 11 | OverlayUtil.showNotification(errorMessage, NotificationType.ERROR) 12 | } 13 | 14 | fun formatErrorMessage(error: ErrorDetails?, ex: Throwable?): String { 15 | return when { 16 | error?.code == "insufficient_quota" -> "You exceeded your current quota, please check your plan and billing details." 17 | ex?.message != null -> "Error: ${ex.message}" 18 | else -> "An unknown error occurred while applying changes." 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/service/llama/form/ChatPromptTemplatePanel.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.llama.form; 2 | 3 | import ee.carlrobert.codegpt.completions.llama.PromptTemplate; 4 | import ee.carlrobert.codegpt.conversations.message.Message; 5 | import java.util.List; 6 | 7 | public class ChatPromptTemplatePanel extends BasePromptTemplatePanel { 8 | 9 | public ChatPromptTemplatePanel(PromptTemplate initiallySelectedTemplate, boolean enabled) { 10 | super( 11 | PromptTemplate.class, 12 | initiallySelectedTemplate, 13 | enabled, 14 | "settingsConfigurable.service.llama.promptTemplate.comment"); 15 | } 16 | 17 | @Override 18 | protected String buildPromptDescription(PromptTemplate template) { 19 | return template.buildPrompt( 20 | "SYSTEM_PROMPT", 21 | "USER_PROMPT", 22 | List.of(new Message("PREV_PROMPT", "PREV_RESPONSE"))); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/mcp/form/details/McpFormDetails.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.mcp.form.details 2 | 3 | import ee.carlrobert.codegpt.settings.mcp.McpServerDetailsState 4 | import javax.swing.JComponent 5 | 6 | interface McpDetailsPanel { 7 | fun getPanel(): JComponent 8 | fun updateData(details: McpServerDetails) 9 | fun remove(details: McpServerDetails) 10 | } 11 | 12 | data class McpServerDetails( 13 | val id: Long, 14 | var name: String, 15 | var command: String, 16 | var arguments: MutableList, 17 | var environmentVariables: MutableMap 18 | ) { 19 | constructor(state: McpServerDetailsState) : this( 20 | id = state.id, 21 | name = state.name ?: "New MCP Server", 22 | command = state.command ?: "npx", 23 | arguments = state.arguments.toMutableList(), 24 | environmentVariables = state.environmentVariables.toMutableMap() 25 | ) 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowListener.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.chat 2 | 3 | import com.intellij.openapi.project.Project 4 | import com.intellij.openapi.wm.ToolWindow 5 | import com.intellij.openapi.wm.ex.ToolWindowManagerListener 6 | 7 | class ChatToolWindowListener : ToolWindowManagerListener { 8 | 9 | override fun toolWindowShown(toolWindow: ToolWindow) { 10 | if ("ProxyAI" == toolWindow.id) { 11 | requestFocusForTextArea(toolWindow.project) 12 | } 13 | } 14 | 15 | private fun requestFocusForTextArea(project: Project) { 16 | val contentManager = project.getService(ChatToolWindowContentManager::class.java) 17 | contentManager.tryFindChatTabbedPane().ifPresent { tabbedPane -> 18 | tabbedPane.tryFindActiveTabPanel().ifPresent { tabPanel -> 19 | tabPanel.requestFocusForTextArea() 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/proto/code-completion.proto: -------------------------------------------------------------------------------- 1 | // src/main/proto/code-completion.proto 2 | syntax = "proto3"; 3 | option java_multiple_files = true; 4 | option java_package = "ee.carlrobert.service"; 5 | 6 | import "google/protobuf/empty.proto"; 7 | 8 | service CodeCompletionServiceImpl { 9 | rpc GetCodeCompletion (GrpcCodeCompletionRequest) returns (stream PartialCodeCompletionResponse); 10 | rpc AcceptCodeCompletion (AcceptCodeCompletionRequest) returns (google.protobuf.Empty); 11 | } 12 | 13 | message GrpcCodeCompletionRequest { 14 | string model = 1; 15 | string file_content = 2; 16 | string file_path = 3; 17 | int32 cursor_position = 4; 18 | string git_diff = 5; 19 | string plugin_version = 6; 20 | } 21 | 22 | message PartialCodeCompletionResponse { 23 | string id = 1; 24 | string partial_completion = 2; 25 | bool done = 3; 26 | } 27 | 28 | message AcceptCodeCompletionRequest { 29 | string response_id = 1; 30 | string accepted_completion = 2; 31 | } 32 | -------------------------------------------------------------------------------- /src/main/resources/icons/addFile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/icons/addFile_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/icons/anthropic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/icons/dbrx.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/icons/upload.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/service/mistral/MistralSettingsState.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.mistral; 2 | 3 | import java.util.Objects; 4 | 5 | public class MistralSettingsState { 6 | 7 | private boolean codeCompletionsEnabled = true; 8 | 9 | public boolean isCodeCompletionsEnabled() { 10 | return codeCompletionsEnabled; 11 | } 12 | 13 | public void setCodeCompletionsEnabled(boolean codeCompletionsEnabled) { 14 | this.codeCompletionsEnabled = codeCompletionsEnabled; 15 | } 16 | 17 | @Override 18 | public boolean equals(Object o) { 19 | if (this == o) { 20 | return true; 21 | } 22 | if (o == null || getClass() != o.getClass()) { 23 | return false; 24 | } 25 | MistralSettingsState that = (MistralSettingsState) o; 26 | return codeCompletionsEnabled == that.codeCompletionsEnabled; 27 | } 28 | 29 | @Override 30 | public int hashCode() { 31 | return Objects.hash(codeCompletionsEnabled); 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/resources/icons/upload_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/test/kotlin/testsupport/IntegrationTest.kt: -------------------------------------------------------------------------------- 1 | package testsupport 2 | 3 | import com.intellij.openapi.util.Key 4 | import com.intellij.testFramework.fixtures.BasePlatformTestCase 5 | import ee.carlrobert.codegpt.CodeGPTKeys 6 | import ee.carlrobert.llm.client.mixin.ExternalServiceTestMixin 7 | import testsupport.mixin.ShortcutsTestMixin 8 | 9 | open class IntegrationTest : BasePlatformTestCase(), ExternalServiceTestMixin, ShortcutsTestMixin { 10 | 11 | @Throws(Exception::class) 12 | override fun tearDown() { 13 | ExternalServiceTestMixin.clearAll() 14 | clearKeys() 15 | super.tearDown() 16 | } 17 | 18 | private fun clearKeys() { 19 | putUserData(CodeGPTKeys.IMAGE_ATTACHMENT_FILE_PATH, "") 20 | } 21 | 22 | private fun putUserData(key: Key, value: T) { 23 | project.putUserData(key, value) 24 | } 25 | 26 | companion object { 27 | init { 28 | ExternalServiceTestMixin.init() 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettings.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.ollama 2 | 3 | import com.intellij.openapi.components.BaseState 4 | import com.intellij.openapi.components.SimplePersistentStateComponent 5 | import com.intellij.openapi.components.State 6 | import com.intellij.openapi.components.Storage 7 | import ee.carlrobert.codegpt.codecompletions.InfillPromptTemplate 8 | 9 | @State(name = "CodeGPT_OllamaSettings_210", storages = [Storage("CodeGPT_OllamaSettings_210.xml")]) 10 | class OllamaSettings : 11 | SimplePersistentStateComponent(OllamaSettingsState()) 12 | 13 | class OllamaSettingsState : BaseState() { 14 | var host by string("http://localhost:11434") 15 | var model by string() 16 | var codeCompletionsEnabled by property(false) 17 | var fimOverride by property(true) 18 | var fimTemplate by enum(InfillPromptTemplate.CODE_QWEN_2_5) 19 | var availableModels by list() 20 | } -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/statusbar/CodeGPTStatusBarWidgetFactory.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.statusbar; 2 | 3 | import com.intellij.openapi.project.Project; 4 | import com.intellij.openapi.wm.StatusBarWidget; 5 | import com.intellij.openapi.wm.impl.status.widget.StatusBarEditorBasedWidgetFactory; 6 | import ee.carlrobert.codegpt.CodeGPTBundle; 7 | import org.jetbrains.annotations.Nls; 8 | import org.jetbrains.annotations.NonNls; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class CodeGPTStatusBarWidgetFactory extends StatusBarEditorBasedWidgetFactory { 12 | 13 | @Override 14 | public @NonNls @NotNull String getId() { 15 | return "ee.carlrobert.codegpt.statusbar.widget"; 16 | } 17 | 18 | @Override 19 | public @NotNull String getDisplayName() { 20 | return CodeGPTBundle.get("project.label"); 21 | } 22 | 23 | @Override 24 | public @NotNull StatusBarWidget createWidget(@NotNull Project project) { 25 | return new CodeGPTStatusBarWidget(project); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/completions/CompletionResponseEventListener.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.completions; 2 | 3 | import ee.carlrobert.codegpt.conversations.Conversation; 4 | import ee.carlrobert.codegpt.conversations.message.Message; 5 | import ee.carlrobert.codegpt.events.CodeGPTEvent; 6 | import ee.carlrobert.llm.client.openai.completion.ErrorDetails; 7 | import javax.swing.JPanel; 8 | 9 | public interface CompletionResponseEventListener { 10 | 11 | default void handleMessage(String message) { 12 | } 13 | 14 | default void handleError(ErrorDetails error, Throwable ex) { 15 | } 16 | 17 | default void handleTokensExceeded(Conversation conversation, Message message) { 18 | } 19 | 20 | default void handleCompleted(String fullMessage) { 21 | } 22 | 23 | default void handleCompleted(String fullMessage, ChatCompletionParameters callParameters) { 24 | } 25 | 26 | default void handleCodeGPTEvent(CodeGPTEvent event) { 27 | } 28 | 29 | default void handleRequestOpen() { 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/PromptsConfigurable.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.prompts 2 | 3 | import com.intellij.openapi.options.Configurable 4 | import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil 5 | import ee.carlrobert.codegpt.settings.prompts.form.PromptsForm 6 | import javax.swing.JComponent 7 | 8 | class PromptsConfigurable : Configurable { 9 | 10 | private lateinit var component: PromptsForm 11 | 12 | override fun getDisplayName(): String { 13 | return "ProxyAI: Prompts" 14 | } 15 | 16 | override fun createComponent(): JComponent { 17 | component = PromptsForm() 18 | return component.createPanel() 19 | } 20 | 21 | override fun isModified(): Boolean { 22 | return component.isModified() 23 | } 24 | 25 | override fun apply() { 26 | component.applyChanges() 27 | EditorActionsUtil.refreshActions() 28 | } 29 | 30 | override fun reset() { 31 | component.resetChanges() 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CompletionTracker.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.codecompletions 2 | 3 | import com.intellij.openapi.editor.Editor 4 | import com.intellij.openapi.util.Key 5 | 6 | object CompletionTracker { 7 | 8 | private val LAST_COMPLETION_REQUEST_TIME: Key = Key.create("LAST_COMPLETION_REQUEST_TIME") 9 | private const val DEBOUNCE_INTERVAL_MS = 500L 10 | 11 | fun calcDebounceTime(editor: Editor): Long { 12 | val lastCompletionTimestamp = editor.getUserData(LAST_COMPLETION_REQUEST_TIME) 13 | if (lastCompletionTimestamp != null) { 14 | val elapsed = System.currentTimeMillis() - lastCompletionTimestamp 15 | if (elapsed < DEBOUNCE_INTERVAL_MS) { 16 | return DEBOUNCE_INTERVAL_MS - elapsed 17 | } 18 | } 19 | return 0 20 | } 21 | 22 | fun updateLastCompletionRequestTime(editor: Editor) { 23 | editor.putUserData(LAST_COMPLETION_REQUEST_TIME, System.currentTimeMillis()) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/codecompletions/edit/GrpcCallCredentials.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.codecompletions.edit 2 | 3 | import io.grpc.CallCredentials 4 | import io.grpc.Metadata 5 | import io.grpc.Status 6 | import java.util.concurrent.Executor 7 | 8 | class GrpcCallCredentials(private val apiKey: String) : CallCredentials() { 9 | 10 | companion object { 11 | private val API_KEY_HEADER = Metadata.Key.of("x-api-key", Metadata.ASCII_STRING_MARSHALLER) 12 | } 13 | 14 | override fun applyRequestMetadata( 15 | requestInfo: RequestInfo?, 16 | executor: Executor, 17 | metadataApplier: MetadataApplier 18 | ) { 19 | executor.execute { 20 | try { 21 | val headers = Metadata() 22 | headers.put(API_KEY_HEADER, apiKey) 23 | metadataApplier.apply(headers) 24 | } catch (e: Throwable) { 25 | metadataApplier.fail(Status.UNAUTHENTICATED.withCause(e)) 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/group/AbstractLookupGroupItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.group 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement 4 | import com.intellij.codeInsight.lookup.LookupElementPresentation 5 | import com.intellij.icons.AllIcons 6 | import ee.carlrobert.codegpt.ui.textarea.lookup.AbstractLookupItem 7 | import ee.carlrobert.codegpt.ui.textarea.lookup.LookupGroupItem 8 | 9 | abstract class AbstractLookupGroupItem : AbstractLookupItem(), LookupGroupItem { 10 | 11 | override fun setPresentation(element: LookupElement, presentation: LookupElementPresentation) { 12 | presentation.itemText = displayName 13 | presentation.icon = icon 14 | presentation.setTypeText("", AllIcons.Icons.Ide.NextStep) 15 | presentation.isTypeIconRightAligned = true 16 | presentation.isItemTextBold = false 17 | } 18 | 19 | override fun getLookupString(): String { 20 | return "group_${displayName.replace(" ", "_").lowercase()}" 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/resources/icons/codegpt-model.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/main/resources/icons/codegpt-model_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/main/resources/icons/mcp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | codegpt-core/src/main/java/grammar/* 2 | !codegpt-core/src/main/java/grammar/PythonLexerBase.java 3 | !codegpt-core/src/main/java/grammar/PythonParserBase.java 4 | !codegpt-core/src/main/java/grammar/PythonVersion.java 5 | !codegpt-core/src/main/java/grammar/TypeScriptLexerBase.java 6 | !codegpt-core/src/main/java/grammar/TypeScriptParserBase.java 7 | 8 | .gradle 9 | .kotlin 10 | build/ 11 | !gradle/wrapper/gradle-wrapper.jar 12 | !**/src/main/**/build/ 13 | !**/src/test/**/build/ 14 | local.properties 15 | 16 | ### IntelliJ IDEA ### 17 | .idea/* 18 | .intellijPlatform/* 19 | *.iws 20 | *.iml 21 | *.ipr 22 | out/ 23 | !**/src/main/**/out/ 24 | !**/src/test/**/out/ 25 | 26 | ### Eclipse ### 27 | .apt_generated 28 | .classpath 29 | .factorypath 30 | .project 31 | .settings 32 | .springBeans 33 | .sts4-cache 34 | bin/ 35 | !**/src/main/**/bin/ 36 | !**/src/test/**/bin/ 37 | 38 | ### NetBeans ### 39 | /nbproject/private/ 40 | /nbbuild/ 41 | /dist/ 42 | /nbdist/ 43 | /.nb-gradle/ 44 | 45 | ### VS Code ### 46 | .vscode/ 47 | 48 | ### Mac OS ### 49 | .DS_Store 50 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/ui/IconActionButton.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui; 2 | 3 | import com.intellij.openapi.actionSystem.ActionPlaces; 4 | import com.intellij.openapi.actionSystem.ActionToolbar; 5 | import com.intellij.openapi.actionSystem.AnAction; 6 | import com.intellij.openapi.actionSystem.Presentation; 7 | import com.intellij.openapi.actionSystem.impl.ActionButton; 8 | 9 | public class IconActionButton extends ActionButton { 10 | 11 | public IconActionButton(AnAction action, String actionCode) { 12 | super(action, 13 | getPresentation(action), 14 | ActionPlaces.TOOLWINDOW_CONTENT, 15 | ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE); 16 | putClientProperty("actionCode", actionCode); 17 | } 18 | 19 | private static Presentation getPresentation(AnAction action) { 20 | var actionPresentation = action.getTemplatePresentation(); 21 | var presentation = new Presentation(actionPresentation.getText()); 22 | presentation.setIcon(actionPresentation.getIcon()); 23 | return presentation; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/resources/icons/mcp_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/actions/editor/AddSelectionToContextAction.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions.editor 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.openapi.components.service 5 | import com.intellij.openapi.editor.Editor 6 | import com.intellij.openapi.project.Project 7 | import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager 8 | 9 | class AddSelectionToContextAction : BaseEditorAction(AllIcons.General.Add) { 10 | 11 | override fun actionPerformed(project: Project, editor: Editor, selectedText: String) { 12 | val chatToolWindowContentManager = project.service() 13 | val chatTabPanel = chatToolWindowContentManager 14 | .tryFindActiveChatTabPanel() 15 | .orElseThrow() 16 | 17 | val toolwindow = chatToolWindowContentManager.toolWindow 18 | if (!toolwindow.isActive) { 19 | toolwindow.show() 20 | } 21 | 22 | chatTabPanel.addSelection(editor.virtualFile, editor.selectionModel) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/custom/form/CustomServiceNameListRenderer.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.custom.form 2 | 3 | import ee.carlrobert.codegpt.settings.service.custom.form.model.CustomServiceSettingsData 4 | import java.awt.Component 5 | import javax.swing.JLabel 6 | import javax.swing.JList 7 | import javax.swing.ListCellRenderer 8 | 9 | internal class CustomServiceNameListRenderer : JLabel(), ListCellRenderer { 10 | 11 | override fun getListCellRendererComponent( 12 | list: JList, 13 | value: CustomServiceSettingsData?, 14 | index: Int, 15 | isSelected: Boolean, 16 | cellHasFocus: Boolean 17 | ): Component { 18 | text = value?.name ?: "" 19 | isOpaque = true 20 | background = if (isSelected) list.selectionBackground else list.background 21 | foreground = if (isSelected) list.selectionForeground else list.foreground 22 | font = list.font 23 | return this 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/header/tag/TagUtil.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.header.tag 2 | 3 | import com.intellij.openapi.components.service 4 | import com.intellij.openapi.project.Project 5 | import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager 6 | 7 | object TagUtil { 8 | fun isTagTypePresent( 9 | project: Project, 10 | tagClass: Class 11 | ): Boolean { 12 | return project.service() 13 | .tryFindActiveChatTabPanel() 14 | .map { it.selectedTags } 15 | .orElse(emptyList()) 16 | .any { tagClass.isInstance(it) } 17 | } 18 | 19 | fun getExistingTags( 20 | project: Project, 21 | tagClass: Class 22 | ): List { 23 | return project.service() 24 | .tryFindActiveChatTabPanel() 25 | .map { it.selectedTags } 26 | .orElse(emptyList()) 27 | .filterIsInstance(tagClass) 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/ollama/OllamaSettingsConfigurable.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.ollama 2 | 3 | import com.intellij.openapi.options.Configurable 4 | import ee.carlrobert.codegpt.settings.service.ModelReplacementDialog 5 | import ee.carlrobert.codegpt.settings.service.ServiceType 6 | import javax.swing.JComponent 7 | 8 | class OllamaSettingsConfigurable : Configurable { 9 | 10 | private lateinit var component: OllamaSettingsForm 11 | 12 | override fun getDisplayName(): String { 13 | return "ProxyAI: Ollama Service" 14 | } 15 | 16 | override fun createComponent(): JComponent { 17 | component = OllamaSettingsForm() 18 | return component.getForm() 19 | } 20 | 21 | override fun isModified(): Boolean { 22 | return component.isModified() 23 | } 24 | 25 | override fun apply() { 26 | component.applyChanges() 27 | 28 | ModelReplacementDialog.showDialogIfNeeded(ServiceType.OLLAMA) 29 | } 30 | 31 | override fun reset() { 32 | component.resetForm() 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/action/personas/AddPersonaActionItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.action.personas 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.openapi.components.service 5 | import com.intellij.openapi.options.ShowSettingsUtil 6 | import com.intellij.openapi.project.Project 7 | import ee.carlrobert.codegpt.CodeGPTBundle 8 | import ee.carlrobert.codegpt.settings.prompts.PromptsConfigurable 9 | import ee.carlrobert.codegpt.ui.textarea.UserInputPanel 10 | import ee.carlrobert.codegpt.ui.textarea.lookup.action.AbstractLookupActionItem 11 | 12 | class AddPersonaActionItem : AbstractLookupActionItem() { 13 | 14 | override val displayName: String = 15 | CodeGPTBundle.get("suggestionActionItem.createPersona.displayName") 16 | override val icon = AllIcons.General.Add 17 | 18 | override fun execute(project: Project, userInputPanel: UserInputPanel) { 19 | service().showSettingsDialog( 20 | project, 21 | PromptsConfigurable::class.java 22 | ) 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/util/ProjectPathUtils.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util 2 | 3 | object ProjectPathUtils { 4 | private const val PROJECT_NAME_MAX_LENGTH = 30 5 | 6 | fun extractProjectName(projectPath: String?): String? { 7 | if (projectPath.isNullOrEmpty()) return null 8 | 9 | val separators = listOf('/', '\\') 10 | val lastSeparatorIndex = separators.maxOfOrNull { projectPath.lastIndexOf(it) } ?: -1 11 | 12 | return if (lastSeparatorIndex >= 0 && lastSeparatorIndex < projectPath.length - 1) { 13 | projectPath.substring(lastSeparatorIndex + 1) 14 | } else { 15 | projectPath 16 | } 17 | } 18 | 19 | fun extractProjectNameTruncated(projectPath: String?): String? { 20 | val projectName = extractProjectName(projectPath) ?: return null 21 | 22 | return if (projectName.length > PROJECT_NAME_MAX_LENGTH) { 23 | projectName.substring(0, PROJECT_NAME_MAX_LENGTH - 3) + "..." 24 | } else { 25 | projectName 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeCompletionProviderPresentation.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.codecompletions 2 | 3 | import com.intellij.codeInsight.inline.completion.InlineCompletionProviderPresentation 4 | import com.intellij.openapi.components.service 5 | import com.intellij.openapi.project.Project 6 | import com.intellij.ui.components.JBLabel 7 | import ee.carlrobert.codegpt.Icons 8 | import javax.swing.JComponent 9 | import javax.swing.SwingConstants 10 | 11 | class CodeCompletionProviderPresentation : InlineCompletionProviderPresentation { 12 | 13 | override fun getTooltip(project: Project?): JComponent { 14 | val selectedModelCode = 15 | service().getSelectedModelCode() ?: "" 16 | val text = if (selectedModelCode.isNotEmpty()) { 17 | buildString { 18 | append("Model: ($selectedModelCode)") 19 | } 20 | } else { 21 | "ProxyAI" 22 | } 23 | 24 | return JBLabel(text, Icons.DefaultSmall, SwingConstants.LEADING) 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/models/ModelSettingsConfigurable.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.models 2 | 3 | import com.intellij.openapi.options.Configurable 4 | import com.intellij.openapi.util.Disposer 5 | import ee.carlrobert.codegpt.CodeGPTBundle 6 | import javax.swing.JComponent 7 | 8 | class ModelSettingsConfigurable : Configurable { 9 | private var form: ModelSettingsForm? = null 10 | 11 | override fun getDisplayName(): String { 12 | return CodeGPTBundle.get("settings.models.displayName") 13 | } 14 | 15 | override fun createComponent(): JComponent { 16 | form = ModelSettingsForm() 17 | return form!!.createPanel() 18 | } 19 | 20 | override fun isModified(): Boolean { 21 | return form?.isModified() == true 22 | } 23 | 24 | override fun apply() { 25 | form?.applyChanges() 26 | } 27 | 28 | override fun reset() { 29 | form?.resetForm() 30 | } 31 | 32 | override fun disposeUIResources() { 33 | form?.let { Disposer.dispose(it) } 34 | form = null 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/IncludedFilesSettingsState.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings; 2 | 3 | public class IncludedFilesSettingsState { 4 | 5 | public static final String DEFAULT_PROMPT_TEMPLATE = """ 6 | Use the following context to answer question at the end: 7 | 8 | {REPEATABLE_CONTEXT} 9 | 10 | Question: {QUESTION}"""; 11 | public static final String DEFAULT_REPEATABLE_CONTEXT = """ 12 | File Path: {FILE_PATH} 13 | File Content: 14 | {FILE_CONTENT}"""; 15 | 16 | private String promptTemplate = DEFAULT_PROMPT_TEMPLATE; 17 | private String repeatableContext = DEFAULT_REPEATABLE_CONTEXT; 18 | 19 | public String getPromptTemplate() { 20 | return promptTemplate; 21 | } 22 | 23 | public void setPromptTemplate(String promptTemplate) { 24 | this.promptTemplate = promptTemplate; 25 | } 26 | 27 | public String getRepeatableContext() { 28 | return repeatableContext; 29 | } 30 | 31 | public void setRepeatableContext(String repeatableContext) { 32 | this.repeatableContext = repeatableContext; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/util/coroutines/CoroutineDispatchers.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util.coroutines 2 | 3 | import com.intellij.openapi.application.ModalityState 4 | import kotlinx.coroutines.CoroutineDispatcher 5 | import kotlinx.coroutines.Dispatchers 6 | 7 | class CoroutineDispatchers { 8 | fun default(): CoroutineDispatcher = Dispatchers.Default 9 | 10 | fun unconfined(): CoroutineDispatcher = Dispatchers.Unconfined 11 | 12 | fun io(): CoroutineDispatcher = Dispatchers.IO 13 | 14 | fun edtNonModal(): CoroutineDispatcher = EdtDispatchers.NonModal 15 | 16 | fun edtCurrent(): CoroutineDispatcher = EdtDispatchers.Current 17 | 18 | fun edtDefault(): CoroutineDispatcher = EdtDispatchers.Default 19 | } 20 | 21 | object EdtDispatchers { 22 | val NonModal = EdtCoroutineDispatcher(ModalityState.nonModal()) 23 | val Default = EdtCoroutineDispatcher() 24 | val Current = EdtCoroutineDispatcher(ModalityState.current()) 25 | 26 | fun withModalityState(modalityState: ModalityState): CoroutineDispatcher { 27 | return EdtCoroutineDispatcher(modalityState) 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/TagDetailsComparator.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea 2 | 3 | import ee.carlrobert.codegpt.ui.textarea.header.tag.* 4 | 5 | internal class TagDetailsComparator : Comparator { 6 | override fun compare(o1: TagDetails, o2: TagDetails): Int { 7 | return getPriority(o1).compareTo(getPriority(o2)) 8 | } 9 | 10 | private fun getPriority(tag: TagDetails): Int { 11 | if (!tag.selected && tag !is CodeAnalyzeTagDetails) { 12 | return Int.MAX_VALUE 13 | } 14 | 15 | return when (tag) { 16 | is CodeAnalyzeTagDetails, 17 | is EditorSelectionTagDetails -> 0 18 | 19 | is SelectionTagDetails -> 5 20 | is DocumentationTagDetails, 21 | is PersonaTagDetails, 22 | is GitCommitTagDetails, 23 | is CurrentGitChangesTagDetails, 24 | is FolderTagDetails, 25 | is WebTagDetails -> 10 26 | 27 | is EditorTagDetails, 28 | is FileTagDetails -> 15 29 | 30 | else -> 20 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/core/util/Lazy.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at http://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package ee.carlrobert.codegpt.telemetry.core.util; 12 | 13 | import java.util.function.Supplier; 14 | 15 | public class Lazy implements Supplier { 16 | 17 | private final Supplier factory; 18 | private volatile T value; 19 | 20 | public Lazy(Supplier factory) { 21 | this.factory = factory; 22 | } 23 | 24 | @Override 25 | public T get() { 26 | if (value == null) { 27 | this.value = factory.get(); 28 | } 29 | return value; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/codegpt/CodeGPTServiceSettings.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.codegpt 2 | 3 | import com.intellij.openapi.components.* 4 | import ee.carlrobert.codegpt.settings.models.ModelRegistry 5 | 6 | @Service 7 | @State( 8 | name = "CodeGPT_CodeGPTServiceSettings_280", 9 | storages = [Storage("CodeGPT_CodeGPTServiceSettings_280.xml")] 10 | ) 11 | class CodeGPTServiceSettings : 12 | SimplePersistentStateComponent(CodeGPTServiceSettingsState()) 13 | 14 | class CodeGPTServiceSettingsState : BaseState() { 15 | var chatCompletionSettings by property(CodeGPTServiceChatCompletionSettingsState()) 16 | var codeCompletionSettings by property(CodeGPTServiceCodeCompletionSettingsState()) 17 | var nextEditsEnabled by property(true) 18 | } 19 | 20 | class CodeGPTServiceChatCompletionSettingsState : BaseState() { 21 | var model by string(ModelRegistry.GPT_5_MINI) 22 | } 23 | 24 | class CodeGPTServiceCodeCompletionSettingsState : BaseState() { 25 | var codeCompletionsEnabled by property(true) 26 | var model by string(ModelRegistry.MERCURY_CODER) 27 | } 28 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/PromptTextFieldConstants.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea 2 | 3 | object PromptTextFieldConstants { 4 | const val SEARCH_DELAY_MS = 200L 5 | const val MIN_DYNAMIC_SEARCH_LENGTH = 2 6 | const val MAX_SEARCH_RESULTS = 100 7 | const val DEFAULT_TOOL_WINDOW_HEIGHT = 400 8 | const val BORDER_PADDING = 4 9 | const val BORDER_SIDE_PADDING = 8 10 | const val HEIGHT_PADDING = 8 11 | const val PASTE_PLACEHOLDER_MIN_LENGTH = 250 12 | 13 | val DEFAULT_GROUP_NAMES = listOf( 14 | "files", "file", "f", 15 | "folders", "folder", "fold", 16 | "git", "g", 17 | "conversations", "conversation", "conv", "c", 18 | "history", "hist", "h", 19 | "personas", "persona", "p", 20 | "docs", "doc", "d", 21 | "diagnostics", "diagnostic", "diag", 22 | "mcp", "m", 23 | "web", "w", 24 | "image", "img", "i" 25 | ) 26 | 27 | const val AT_SYMBOL = "@" 28 | const val SPACE = " " 29 | const val NEWLINE = "\n" 30 | 31 | const val LIGHT_THEME_COLOR = 0x00627A 32 | const val DARK_THEME_COLOR = 0xCC7832 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/GeneralSettings.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.components.PersistentStateComponent; 5 | import com.intellij.openapi.components.State; 6 | import com.intellij.openapi.components.Storage; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | @State(name = "CodeGPT_GeneralSettings_270", storages = @Storage("CodeGPT_GeneralSettings_270.xml")) 10 | public class GeneralSettings implements PersistentStateComponent { 11 | 12 | private GeneralSettingsState state = new GeneralSettingsState(); 13 | 14 | @Override 15 | @NotNull 16 | public GeneralSettingsState getState() { 17 | return state; 18 | } 19 | 20 | @Override 21 | public void loadState(@NotNull GeneralSettingsState state) { 22 | this.state = state; 23 | } 24 | 25 | public static GeneralSettingsState getCurrentState() { 26 | return getInstance().getState(); 27 | } 28 | 29 | public static GeneralSettings getInstance() { 30 | return ApplicationManager.getApplication().getService(GeneralSettings.class); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/resources/icons/tree.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/inception/InceptionSettingsForm.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.inception 2 | 3 | import com.intellij.ui.components.JBPasswordField 4 | import com.intellij.util.ui.FormBuilder 5 | import ee.carlrobert.codegpt.CodeGPTBundle 6 | import ee.carlrobert.codegpt.ui.UIUtil 7 | import javax.swing.JComponent 8 | import javax.swing.JLabel 9 | import javax.swing.JPanel 10 | 11 | class InceptionSettingsForm { 12 | private val apiKeyField = JBPasswordField().apply { columns = 30 } 13 | 14 | private val panel: JPanel = FormBuilder.createFormBuilder() 15 | .addLabeledComponent(CodeGPTBundle.get("settingsConfigurable.shared.apiKey.label"), apiKeyField) 16 | .addComponentToRightColumn( 17 | UIUtil.createComment("settingsConfigurable.service.inception.apiKey.comment") as JLabel 18 | ) 19 | .addComponentFillVertically(JPanel(), 0) 20 | .panel 21 | 22 | fun getForm(): JComponent = panel 23 | 24 | fun getApiKey(): String? = String(apiKeyField.password).ifEmpty { null } 25 | 26 | fun setApiKey(value: String?) { 27 | apiKeyField.text = value ?: "" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/service/mistral/MistralSettings.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.mistral; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.components.PersistentStateComponent; 5 | import com.intellij.openapi.components.State; 6 | import com.intellij.openapi.components.Storage; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | @State(name = "CodeGPT_MistralSettings", storages = @Storage("CodeGPT_MistralSettings.xml")) 10 | public class MistralSettings implements PersistentStateComponent { 11 | 12 | private MistralSettingsState state = new MistralSettingsState(); 13 | 14 | @Override 15 | @NotNull 16 | public MistralSettingsState getState() { 17 | return state; 18 | } 19 | 20 | @Override 21 | public void loadState(@NotNull MistralSettingsState state) { 22 | this.state = state; 23 | } 24 | 25 | public static MistralSettingsState getCurrentState() { 26 | return getInstance().getState(); 27 | } 28 | 29 | public static MistralSettings getInstance() { 30 | return ApplicationManager.getApplication().getService(MistralSettings.class); 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/service/openai/OpenAISettings.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.openai; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.components.PersistentStateComponent; 5 | import com.intellij.openapi.components.State; 6 | import com.intellij.openapi.components.Storage; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | @State(name = "CodeGPT_OpenAISettings_210", storages = @Storage("CodeGPT_OpenAISettings_210.xml")) 10 | public class OpenAISettings implements PersistentStateComponent { 11 | 12 | private OpenAISettingsState state = new OpenAISettingsState(); 13 | 14 | @Override 15 | @NotNull 16 | public OpenAISettingsState getState() { 17 | return state; 18 | } 19 | 20 | @Override 21 | public void loadState(@NotNull OpenAISettingsState state) { 22 | this.state = state; 23 | } 24 | 25 | public static OpenAISettingsState getCurrentState() { 26 | return getInstance().getState(); 27 | } 28 | 29 | public static OpenAISettings getInstance() { 30 | return ApplicationManager.getApplication().getService(OpenAISettings.class); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/CodeGPTPlugin.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt; 2 | 3 | import static java.io.File.separator; 4 | import static java.util.Objects.requireNonNull; 5 | 6 | import com.intellij.ide.plugins.PluginManagerCore; 7 | import com.intellij.openapi.application.PathManager; 8 | import com.intellij.openapi.extensions.PluginId; 9 | import java.nio.file.Path; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | public final class CodeGPTPlugin { 13 | 14 | public static final PluginId CODEGPT_ID = PluginId.getId("ee.carlrobert.chatgpt"); 15 | 16 | private CodeGPTPlugin() { 17 | } 18 | 19 | public static @NotNull String getVersion() { 20 | return requireNonNull(PluginManagerCore.getPlugin(CODEGPT_ID)).getVersion(); 21 | } 22 | 23 | public static @NotNull Path getPluginBasePath() { 24 | return requireNonNull(PluginManagerCore.getPlugin(CODEGPT_ID)).getPluginPath(); 25 | } 26 | 27 | public static @NotNull String getPluginOptionsPath() { 28 | return PathManager.getOptionsPath() + separator + "CodeGPT"; 29 | } 30 | 31 | public static @NotNull String getLlamaSourcePath() { 32 | return getPluginBasePath() + separator + "llama.cpp"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/ui/checkbox/FileCheckboxTree.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.checkbox; 2 | 3 | import com.intellij.openapi.fileTypes.FileTypeManager; 4 | import com.intellij.openapi.vfs.VirtualFile; 5 | import com.intellij.ui.CheckboxTree; 6 | import com.intellij.ui.CheckedTreeNode; 7 | import com.intellij.ui.ColoredTreeCellRenderer; 8 | import ee.carlrobert.codegpt.util.file.FileUtil; 9 | import java.util.List; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | public abstract class FileCheckboxTree extends CheckboxTree { 13 | 14 | public FileCheckboxTree(FileCheckboxTreeCellRenderer cellRenderer, CheckedTreeNode node) { 15 | super(cellRenderer, node); 16 | } 17 | 18 | public abstract List getReferencedFiles(); 19 | 20 | protected static void updateFilePresentation( 21 | ColoredTreeCellRenderer textRenderer, 22 | @NotNull VirtualFile virtualFile) { 23 | var fileType = FileTypeManager.getInstance().getFileTypeByFile(virtualFile); 24 | textRenderer.setIcon(fileType.getIcon()); 25 | textRenderer.append(virtualFile.getName()); 26 | textRenderer.append(" - " + FileUtil.convertFileSize(virtualFile.getLength())); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/configuration/PathInputDialog.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.configuration 2 | 3 | import com.intellij.openapi.ui.DialogWrapper 4 | import com.intellij.openapi.ui.TextFieldWithBrowseButton 5 | import com.intellij.util.ui.FormBuilder 6 | import com.intellij.util.ui.JBUI 7 | import ee.carlrobert.codegpt.CodeGPTBundle 8 | import java.awt.Dimension 9 | import javax.swing.JComponent 10 | 11 | class PathInputDialog( 12 | title: String, 13 | private val textField: TextFieldWithBrowseButton 14 | ) : DialogWrapper(true) { 15 | 16 | init { 17 | this.title = title 18 | init() 19 | } 20 | 21 | override fun createCenterPanel(): JComponent { 22 | val panel = FormBuilder.createFormBuilder() 23 | .addLabeledComponent( 24 | CodeGPTBundle.get("configurationConfigurable.screenshotPaths.dialog.path.label"), 25 | textField, 26 | true 27 | ) 28 | .panel 29 | panel.preferredSize = Dimension(JBUI.scale(500), panel.preferredSize.height) 30 | return panel 31 | } 32 | 33 | override fun getPreferredFocusedComponent(): JComponent = textField 34 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/actions/editor/ShowEditorActionGroupAction.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions.editor 2 | 3 | import com.intellij.openapi.actionSystem.ActionGroup 4 | import com.intellij.openapi.actionSystem.ActionManager 5 | import com.intellij.openapi.actionSystem.AnAction 6 | import com.intellij.openapi.actionSystem.AnActionEvent 7 | import com.intellij.openapi.ui.popup.JBPopupFactory 8 | import com.intellij.openapi.ui.popup.JBPopupFactory.ActionSelectionAid 9 | import com.intellij.ui.awt.RelativePoint 10 | import ee.carlrobert.codegpt.CodeGPTBundle 11 | import java.awt.MouseInfo 12 | 13 | class ShowEditorActionGroupAction : AnAction() { 14 | override fun actionPerformed(e: AnActionEvent) { 15 | val actionManager = ActionManager.getInstance() 16 | val actionGroup = actionManager.getAction("action.editor.group.EditorActionGroup") 17 | JBPopupFactory.getInstance() 18 | .createActionGroupPopup( 19 | CodeGPTBundle.get("project.label"), (actionGroup as ActionGroup), e.dataContext, 20 | ActionSelectionAid.ALPHA_NUMBERING, true 21 | ) 22 | .show(RelativePoint(MouseInfo.getPointerInfo().location)) 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/mcp/McpSessionAttachment.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.mcp 2 | 3 | data class McpSessionAttachment( 4 | var serverId: String = "", 5 | var serverName: String = "", 6 | var connectionStatus: ConnectionStatus = ConnectionStatus.DISCONNECTED, 7 | var availableTools: List = emptyList(), 8 | var availableResources: List = emptyList(), 9 | var attachedAt: Long = System.currentTimeMillis(), 10 | var lastError: String? = null 11 | ) { 12 | fun isConnected(): Boolean = connectionStatus == ConnectionStatus.CONNECTED 13 | fun hasError(): Boolean = connectionStatus == ConnectionStatus.ERROR 14 | } 15 | 16 | enum class ConnectionStatus { 17 | CONNECTING, 18 | CONNECTED, 19 | DISCONNECTED, 20 | ERROR 21 | } 22 | 23 | data class McpTool( 24 | var name: String = "", 25 | var description: String = "", 26 | var serverId: String = "", 27 | var schema: MutableMap = mutableMapOf() 28 | ) 29 | 30 | data class McpResource( 31 | var uri: String = "", 32 | var name: String = "", 33 | var description: String? = null, 34 | var serverId: String = "", 35 | var mimeType: String? = null 36 | ) 37 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/advanced/AdvancedSettings.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.advanced; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.components.PersistentStateComponent; 5 | import com.intellij.openapi.components.State; 6 | import com.intellij.openapi.components.Storage; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | @State( 10 | name = "CodeGPT_AdvancedSettings_210", 11 | storages = @Storage("CodeGPT_AdvancedSettings_210.xml")) 12 | public class AdvancedSettings implements PersistentStateComponent { 13 | 14 | private AdvancedSettingsState state = new AdvancedSettingsState(); 15 | 16 | @Override 17 | @NotNull 18 | public AdvancedSettingsState getState() { 19 | return state; 20 | } 21 | 22 | @Override 23 | public void loadState(@NotNull AdvancedSettingsState state) { 24 | this.state = state; 25 | } 26 | 27 | public static AdvancedSettingsState getCurrentState() { 28 | return getInstance().getState(); 29 | } 30 | 31 | public static AdvancedSettings getInstance() { 32 | return ApplicationManager.getApplication().getService(AdvancedSettings.class); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/service/anthropic/AnthropicSettings.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.anthropic; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.components.PersistentStateComponent; 5 | import com.intellij.openapi.components.State; 6 | import com.intellij.openapi.components.Storage; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | @State(name = "CodeGPT_AnthropicSettings", storages = @Storage("CodeGPT_AnthropicSettings.xml")) 10 | public class AnthropicSettings implements PersistentStateComponent { 11 | 12 | private AnthropicSettingsState state = new AnthropicSettingsState(); 13 | 14 | @Override 15 | @NotNull 16 | public AnthropicSettingsState getState() { 17 | return state; 18 | } 19 | 20 | @Override 21 | public void loadState(@NotNull AnthropicSettingsState state) { 22 | this.state = state; 23 | } 24 | 25 | public static AnthropicSettingsState getCurrentState() { 26 | return getInstance().getState(); 27 | } 28 | 29 | public static AnthropicSettings getInstance() { 30 | return ApplicationManager.getApplication().getService(AnthropicSettings.class); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsComponent.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings; 2 | 3 | import com.intellij.ui.components.JBTextField; 4 | import com.intellij.util.ui.FormBuilder; 5 | import ee.carlrobert.codegpt.CodeGPTBundle; 6 | import javax.swing.JComponent; 7 | import javax.swing.JPanel; 8 | 9 | public class GeneralSettingsComponent { 10 | 11 | private final JBTextField displayNameField; 12 | 13 | public GeneralSettingsComponent(GeneralSettings settings) { 14 | displayNameField = new JBTextField(settings.getState().getDisplayName(), 20); 15 | } 16 | 17 | public JPanel getPanel() { 18 | return FormBuilder.createFormBuilder() 19 | .addLabeledComponent( 20 | CodeGPTBundle.get("settingsConfigurable.displayName.label"), 21 | displayNameField) 22 | .addComponentFillVertically(new JPanel(), 0) 23 | .getPanel(); 24 | } 25 | 26 | public JComponent getPreferredFocusedComponent() { 27 | return displayNameField; 28 | } 29 | 30 | public String getDisplayName() { 31 | return displayNameField.getText(); 32 | } 33 | 34 | public void setDisplayName(String displayName) { 35 | displayNameField.setText(displayName); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/util/ApplicationUtil.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util 2 | 3 | import com.intellij.openapi.application.ApplicationManager 4 | import com.intellij.openapi.project.Project 5 | import com.intellij.openapi.project.ProjectManager 6 | import com.intellij.openapi.wm.IdeFocusManager 7 | 8 | object ApplicationUtil { 9 | @JvmStatic 10 | fun isUnitTestingMode(): Boolean { 11 | val app = ApplicationManager.getApplication() 12 | return app != null && app.isUnitTestMode 13 | } 14 | 15 | @JvmStatic 16 | fun findCurrentProject(): Project? { 17 | val frame = IdeFocusManager.getGlobalInstance().lastFocusedFrame 18 | val project = frame?.project 19 | if (isValidProject(project)) { 20 | return project 21 | } 22 | return findProjectFromOpenProjects() 23 | } 24 | 25 | private fun findProjectFromOpenProjects(): Project? { 26 | for (project in ProjectManager.getInstance().openProjects) { 27 | if (isValidProject(project)) { 28 | return project 29 | } 30 | } 31 | return null 32 | } 33 | 34 | private fun isValidProject(project: Project?): Boolean { 35 | return project != null && !project.isDisposed && !project.isDefault 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsState.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings; 2 | 3 | import ee.carlrobert.codegpt.settings.service.ServiceType; 4 | 5 | public class GeneralSettingsState { 6 | 7 | private String displayName = ""; 8 | private String avatarBase64 = ""; 9 | private ServiceType selectedService = null; 10 | 11 | public String getDisplayName() { 12 | if (displayName == null || displayName.isEmpty()) { 13 | var systemUserName = System.getProperty("user.name"); 14 | if (systemUserName == null || systemUserName.isEmpty()) { 15 | return "User"; 16 | } 17 | return systemUserName; 18 | } 19 | return displayName; 20 | } 21 | 22 | public void setDisplayName(String displayName) { 23 | this.displayName = displayName; 24 | } 25 | 26 | public String getAvatarBase64() { 27 | return avatarBase64; 28 | } 29 | 30 | public void setAvatarBase64(String avatarBase64) { 31 | this.avatarBase64 = avatarBase64; 32 | } 33 | 34 | public ServiceType getSelectedService() { 35 | return selectedService; 36 | } 37 | 38 | public void setSelectedService(ServiceType selectedService) { 39 | this.selectedService = selectedService; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/IncludedFilesSettings.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings; 2 | 3 | import com.intellij.openapi.application.ApplicationManager; 4 | import com.intellij.openapi.components.PersistentStateComponent; 5 | import com.intellij.openapi.components.State; 6 | import com.intellij.openapi.components.Storage; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | @State( 10 | name = "CodeGPT_IncludedFilesSettings", 11 | storages = @Storage("CodeGPT_IncludedFilesSettings.xml")) 12 | public class IncludedFilesSettings implements PersistentStateComponent { 13 | 14 | private IncludedFilesSettingsState state = new IncludedFilesSettingsState(); 15 | 16 | @Override 17 | @NotNull 18 | public IncludedFilesSettingsState getState() { 19 | return state; 20 | } 21 | 22 | @Override 23 | public void loadState(@NotNull IncludedFilesSettingsState state) { 24 | this.state = state; 25 | } 26 | 27 | public static IncludedFilesSettingsState getCurrentState() { 28 | return getInstance().getState(); 29 | } 30 | 31 | public static IncludedFilesSettings getInstance() { 32 | return ApplicationManager.getApplication().getService(IncludedFilesSettings.class); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/psistructure/PsiFileDepthQueue.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.psistructure 2 | 3 | import com.intellij.psi.PsiFile 4 | 5 | class PsiFileDepthQueue( 6 | initial: List, 7 | private val maxDepth: Int = -1, 8 | ) { 9 | 10 | private val psiFiles = mutableSetOf().apply { 11 | addAll(initial.map { PsiDepthFile(it, 0) }) 12 | } 13 | 14 | private val queue = ArrayDeque(initial.map { PsiDepthFile(it, 0) }) 15 | 16 | @Synchronized 17 | fun pop(): PsiFile? { 18 | while (queue.isNotEmpty()) { 19 | val first = queue.first() 20 | if (maxDepth == -1 || first.depth <= maxDepth) { 21 | return queue.removeFirst().psiFile 22 | } else { 23 | queue.removeFirst() 24 | } 25 | } 26 | return null 27 | } 28 | 29 | @Synchronized 30 | fun put(psiFile: PsiFile, baseFileName: String) { 31 | if (psiFiles.any { it.psiFile.name == psiFile.name }) return 32 | val baseFileDepth = psiFiles.find { it.psiFile.name == baseFileName }?.depth ?: 0 33 | val newItem = PsiDepthFile(psiFile, baseFileDepth + 1) 34 | queue.add(newItem) 35 | psiFiles.add(newItem) 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/resources/icons/send.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/actions/toolwindow/CreateNewConversationAction.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions.toolwindow; 2 | 3 | import com.intellij.icons.AllIcons; 4 | import com.intellij.openapi.actionSystem.AnAction; 5 | import com.intellij.openapi.actionSystem.AnActionEvent; 6 | import ee.carlrobert.codegpt.actions.ActionType; 7 | import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil; 8 | import ee.carlrobert.codegpt.telemetry.TelemetryAction; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class CreateNewConversationAction extends AnAction { 12 | 13 | private final Runnable onCreate; 14 | 15 | public CreateNewConversationAction(Runnable onCreate) { 16 | super("Create New Chat", "Create new chat", AllIcons.General.Add); 17 | this.onCreate = onCreate; 18 | EditorActionsUtil.registerAction(this); 19 | } 20 | 21 | @Override 22 | public void actionPerformed(@NotNull AnActionEvent event) { 23 | try { 24 | var project = event.getProject(); 25 | if (project != null) { 26 | onCreate.run(); 27 | } 28 | } finally { 29 | TelemetryAction.IDE_ACTION.createActionMessage() 30 | .property("action", ActionType.CREATE_NEW_CHAT.name()) 31 | .send(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/icons/send_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/actions/GenerateCommitMessageAction.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions 2 | 3 | import com.intellij.openapi.project.Project 4 | import com.intellij.vcs.commit.CommitWorkflowUi 5 | import ee.carlrobert.codegpt.codecompletions.CompletionProgressNotifier 6 | import ee.carlrobert.codegpt.completions.CommitMessageCompletionParameters 7 | import ee.carlrobert.codegpt.completions.CompletionRequestService 8 | import ee.carlrobert.codegpt.settings.prompts.CommitMessageTemplate 9 | 10 | class GenerateCommitMessageAction : BaseCommitWorkflowAction() { 11 | 12 | override fun getTitle(commitWorkflowUi: CommitWorkflowUi): String { 13 | return "Generate Message" 14 | } 15 | 16 | override fun performAction( 17 | project: Project, 18 | commitWorkflowUi: CommitWorkflowUi, 19 | gitDiff: String 20 | ) { 21 | CompletionProgressNotifier.update(project, true) 22 | CompletionRequestService.getInstance().getCommitMessageAsync( 23 | CommitMessageCompletionParameters( 24 | gitDiff, 25 | project.getService(CommitMessageTemplate::class.java).getSystemPrompt() 26 | ), 27 | CommitMessageEventListener(project, commitWorkflowUi) 28 | ) 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatSession.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.chat; 2 | 3 | import ee.carlrobert.codegpt.ReferencedFile; 4 | import java.util.ArrayList; 5 | import java.util.HashSet; 6 | import java.util.List; 7 | import java.util.Set; 8 | import java.util.UUID; 9 | 10 | public class ChatSession { 11 | 12 | private final UUID id; 13 | private final Set referencedFiles; 14 | private String name; 15 | 16 | public ChatSession() { 17 | this.id = UUID.randomUUID(); 18 | this.referencedFiles = new HashSet<>(); 19 | } 20 | 21 | public UUID getId() { 22 | return id; 23 | } 24 | 25 | public List getReferencedFiles() { 26 | return new ArrayList<>(referencedFiles); 27 | } 28 | 29 | public void addReferencedFiles(List files) { 30 | if (files == null) { 31 | throw new IllegalArgumentException("Referenced files cannot be null"); 32 | } 33 | referencedFiles.addAll(files); 34 | } 35 | 36 | public void setName(String name) { 37 | this.name = name; 38 | } 39 | 40 | public String getName() { 41 | return name; 42 | } 43 | 44 | public String getDisplayName() { 45 | return name != null && !name.trim().isEmpty() ? name : null; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/LookupItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup 2 | 3 | import com.intellij.codeInsight.lookup.LookupElement 4 | import com.intellij.codeInsight.lookup.LookupElementPresentation 5 | import com.intellij.codeInsight.lookup.impl.LookupImpl 6 | import com.intellij.openapi.project.Project 7 | import com.intellij.openapi.util.Key 8 | import ee.carlrobert.codegpt.ui.textarea.UserInputPanel 9 | import javax.swing.Icon 10 | 11 | interface LookupItem { 12 | companion object { 13 | val KEY: Key = Key.create("SUGGESTION_ITEM_KEY") 14 | } 15 | 16 | val displayName: String 17 | val icon: Icon? 18 | val enabled: Boolean 19 | get() = true 20 | 21 | fun createLookupElement(): LookupElement 22 | fun setPresentation(element: LookupElement, presentation: LookupElementPresentation) 23 | } 24 | 25 | interface LookupGroupItem : LookupItem { 26 | suspend fun getLookupItems(searchText: String = ""): List 27 | } 28 | 29 | interface DynamicLookupGroupItem : LookupGroupItem { 30 | suspend fun updateLookupList(lookup: LookupImpl, searchText: String) 31 | } 32 | 33 | interface LookupActionItem : LookupItem { 34 | fun execute(project: Project, userInputPanel: UserInputPanel) 35 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/nextedit/ProxyAINextEditProvider.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.nextedit 2 | 3 | import com.intellij.openapi.components.service 4 | import com.intellij.openapi.editor.Editor 5 | import ee.carlrobert.codegpt.codecompletions.edit.GrpcClientService 6 | import ee.carlrobert.codegpt.nextedit.NextEditProvider 7 | import ee.carlrobert.codegpt.settings.service.FeatureType 8 | import ee.carlrobert.codegpt.settings.service.ModelSelectionService 9 | import ee.carlrobert.codegpt.settings.service.ServiceType 10 | import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTServiceSettings 11 | 12 | class ProxyAINextEditProvider : NextEditProvider { 13 | override fun request(editor: Editor, fileContent: String, caretOffset: Int, addToQueue: Boolean) { 14 | if (service().getServiceForFeature(FeatureType.NEXT_EDIT) != ServiceType.PROXYAI 15 | || !service().state.nextEditsEnabled 16 | ) { 17 | return 18 | } 19 | editor.project?.service()?.cancelNextEdit() 20 | editor.project?.service()?.getNextEdit( 21 | editor, 22 | fileContent, 23 | caretOffset, 24 | addToQueue 25 | ) 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/actions/TrackableAction.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions; 2 | 3 | import com.intellij.openapi.actionSystem.AnAction; 4 | import com.intellij.openapi.actionSystem.AnActionEvent; 5 | import ee.carlrobert.codegpt.telemetry.TelemetryAction; 6 | import javax.swing.Icon; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | public abstract class TrackableAction extends AnAction { 10 | 11 | private final ActionType actionType; 12 | 13 | public TrackableAction( 14 | String text, 15 | String description, 16 | Icon icon, 17 | ActionType actionType) { 18 | super(text, description, icon); 19 | this.actionType = actionType; 20 | } 21 | 22 | public abstract void handleAction(@NotNull AnActionEvent e); 23 | 24 | @Override 25 | public void actionPerformed(@NotNull AnActionEvent e) { 26 | try { 27 | handleAction(e); 28 | } catch (Exception ex) { 29 | TelemetryAction.IDE_ACTION_ERROR 30 | .createActionMessage() 31 | .error(ex) 32 | .send(); 33 | throw ex; 34 | } finally { 35 | TelemetryAction.IDE_ACTION 36 | .createActionMessage() 37 | .property("group", null) 38 | .property("action", actionType.name()) 39 | .send(); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/resources/icons/inSelection.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/ui/ModelIconLabel.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui; 2 | 3 | import com.intellij.ui.components.JBLabel; 4 | import com.intellij.util.ui.JBFont; 5 | import ee.carlrobert.codegpt.Icons; 6 | import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionModel; 7 | import java.util.NoSuchElementException; 8 | import javax.swing.SwingConstants; 9 | 10 | public class ModelIconLabel extends JBLabel { 11 | 12 | public ModelIconLabel(String clientCode, String modelCode) { 13 | if ("chat.completion".equals(clientCode)) { 14 | setIcon(Icons.OpenAI); 15 | } 16 | if ("anthropic.chat.completion".equals(clientCode)) { 17 | setIcon(Icons.Anthropic); 18 | } 19 | if ("llama.chat.completion".equals(clientCode)) { 20 | setIcon(Icons.Llama); 21 | } 22 | if ("google.chat.completion".equals(clientCode)) { 23 | setIcon(Icons.Google); 24 | } 25 | setText(formatModelName(modelCode)); 26 | setFont(JBFont.small()); 27 | setHorizontalAlignment(SwingConstants.LEADING); 28 | } 29 | 30 | private String formatModelName(String modelCode) { 31 | try { 32 | return OpenAIChatCompletionModel.findByCode(modelCode).getDescription(); 33 | } catch (NoSuchElementException e) { 34 | return modelCode; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/resources/icons/inSelection_dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yml: -------------------------------------------------------------------------------- 1 | name: Bug report 2 | description: Create a report to help us improve 3 | labels: ["bug"] 4 | body: 5 | 6 | - type: textarea 7 | id: issue 8 | attributes: 9 | label: What happened? 10 | description: A clear and concise description of what the bug is. 11 | validations: 12 | required: true 13 | 14 | - type: textarea 15 | id: logs 16 | attributes: 17 | label: Relevant log output or stack trace 18 | description: | 19 | Please copy and paste any relevant log output. 20 | Add the full stack trace if available. 21 | If possible, run the failing task with `--stacktrace` flag. 22 | 23 | *This will be automatically formatted into code, so there is no need for backticks.* 24 | render: shell 25 | 26 | - type: textarea 27 | id: steps 28 | attributes: 29 | label: Steps to reproduce 30 | description: Steps to reproduce the behavior 31 | 32 | - type: input 33 | id: version 34 | attributes: 35 | label: CodeGPT version 36 | placeholder: 1.16.0 37 | validations: 38 | required: true 39 | 40 | - type: dropdown 41 | id: os 42 | attributes: 43 | label: Operating System 44 | options: 45 | - macOS 46 | - Linux 47 | - Windows -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/core/configuration/AbstractConfiguration.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at http://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package ee.carlrobert.codegpt.telemetry.core.configuration; 12 | 13 | import ee.carlrobert.codegpt.telemetry.core.util.Lazy; 14 | import java.util.Properties; 15 | 16 | public abstract class AbstractConfiguration implements IConfiguration { 17 | 18 | protected final Lazy properties = new Lazy<>(this::loadProperties); 19 | 20 | @Override 21 | public String get(String key) { 22 | return properties.get().getProperty(key); 23 | } 24 | 25 | @Override 26 | public void put(String key, String value) { 27 | properties.get().put(key, value); 28 | } 29 | 30 | protected abstract Properties loadProperties(); 31 | } 32 | -------------------------------------------------------------------------------- /src/test/kotlin/ee/carlrobert/codegpt/settings/configuration/CommitMessageTemplateTest.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.configuration 2 | 3 | import com.intellij.openapi.components.service 4 | import ee.carlrobert.codegpt.settings.prompts.CommitMessageTemplate 5 | import ee.carlrobert.codegpt.settings.prompts.PromptsSettings 6 | import git4idea.commands.GitCommand 7 | import org.assertj.core.api.Assertions.assertThat 8 | import testsupport.VcsTestCase 9 | import java.time.LocalDate 10 | 11 | class CommitMessageTemplateTest : VcsTestCase() { 12 | 13 | fun `test commit message system prompt construction`() { 14 | git(GitCommand.INIT) 15 | git(GitCommand.CHECKOUT, listOf("-b", "feature/my-cool-feature")) 16 | registerRepository() 17 | service().state.coreActions.generateCommitMessage.instructions = buildString { 18 | append("Branch: {BRANCH_NAME}\n") 19 | append("Date: {DATE_ISO_8601}") 20 | } 21 | 22 | val systemPrompt = project.service().getSystemPrompt() 23 | 24 | assertThat(systemPrompt).isEqualTo( 25 | buildString { 26 | append("Branch: feature/my-cool-feature\n") 27 | append("Date: ${LocalDate.now()}") 28 | } 29 | ) 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/AbstractLookupItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup 2 | 3 | import com.intellij.codeInsight.completion.PrioritizedLookupElement 4 | import com.intellij.codeInsight.lookup.LookupElement 5 | import com.intellij.codeInsight.lookup.LookupElementBuilder 6 | import com.intellij.codeInsight.lookup.LookupElementPresentation 7 | import com.intellij.codeInsight.lookup.LookupElementRenderer 8 | 9 | abstract class AbstractLookupItem : LookupItem { 10 | override fun createLookupElement(): LookupElement { 11 | val lookupElement = LookupElementBuilder.create(getLookupString()) 12 | .withPresentableText(displayName) 13 | .withIcon(icon) 14 | .withRenderer(object : LookupElementRenderer() { 15 | override fun renderElement( 16 | element: LookupElement, 17 | presentation: LookupElementPresentation 18 | ) { 19 | setPresentation(element, presentation) 20 | } 21 | }) 22 | .apply { 23 | putUserData(LookupItem.KEY, this@AbstractLookupItem) 24 | } 25 | return PrioritizedLookupElement.withPriority(lookupElement, 1.0) 26 | } 27 | 28 | abstract fun getLookupString(): String 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/action/CodeAnalyzeActionItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.action 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.openapi.project.Project 5 | import ee.carlrobert.codegpt.CodeGPTBundle 6 | import ee.carlrobert.codegpt.ui.textarea.UserInputPanel 7 | import ee.carlrobert.codegpt.ui.textarea.header.tag.CodeAnalyzeTagDetails 8 | import ee.carlrobert.codegpt.ui.textarea.header.tag.EditorTagDetails 9 | import ee.carlrobert.codegpt.ui.textarea.header.tag.FileTagDetails 10 | import ee.carlrobert.codegpt.ui.textarea.header.tag.TagDetails 11 | import ee.carlrobert.codegpt.ui.textarea.header.tag.TagManager 12 | 13 | class CodeAnalyzeActionItem( 14 | private val tagManager: TagManager 15 | ) : AbstractLookupActionItem() { 16 | 17 | override val displayName: String = CodeGPTBundle.get("suggestionGroupItem.codeAnalyze.displayName") 18 | override val icon = AllIcons.Actions.DependencyAnalyzer 19 | override val enabled: Boolean 20 | get() = tagManager.getTags().none { it is CodeAnalyzeTagDetails } && 21 | tagManager.getTags().any { it is FileTagDetails || it is EditorTagDetails } 22 | 23 | 24 | override fun execute(project: Project, userInputPanel: UserInputPanel) { 25 | userInputPanel.addTag(CodeAnalyzeTagDetails()) 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/util/BaseConverter.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util 2 | 3 | import com.fasterxml.jackson.core.JsonProcessingException 4 | import com.fasterxml.jackson.core.type.TypeReference 5 | import com.fasterxml.jackson.databind.ObjectMapper 6 | import com.fasterxml.jackson.datatype.jdk8.Jdk8Module 7 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule 8 | import com.intellij.openapi.diagnostic.thisLogger 9 | import com.intellij.util.xmlb.Converter 10 | 11 | abstract class BaseConverter protected constructor(private val typeReference: TypeReference) : Converter() { 12 | private val objectMapper: ObjectMapper = ObjectMapper() 13 | .registerModule(Jdk8Module()) 14 | .registerModule(JavaTimeModule()) 15 | 16 | private val logger = thisLogger() 17 | 18 | override fun fromString(value: String): T? { 19 | try { 20 | return objectMapper.readValue(value, typeReference) 21 | } catch (e: JsonProcessingException) { 22 | logger.debug("Unable to deserialize data", e) 23 | return null 24 | } 25 | } 26 | 27 | override fun toString(value: T): String? { 28 | try { 29 | return objectMapper.writeValueAsString(value) 30 | } catch (e: JsonProcessingException) { 31 | logger.debug("Unable to serialize data", e) 32 | return null 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/nextedit/NextEditCoordinator.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.nextedit 2 | 3 | import com.intellij.openapi.application.runReadAction 4 | import com.intellij.openapi.components.service 5 | import com.intellij.openapi.editor.Editor 6 | import ee.carlrobert.codegpt.codecompletions.CompletionProgressNotifier 7 | import ee.carlrobert.codegpt.settings.service.FeatureType 8 | import ee.carlrobert.codegpt.settings.service.ModelSelectionService 9 | import ee.carlrobert.codegpt.settings.service.ServiceType 10 | 11 | object NextEditCoordinator { 12 | 13 | private val providers: Map = mapOf( 14 | ServiceType.PROXYAI to ProxyAINextEditProvider(), 15 | ServiceType.INCEPTION to InceptionNextEditProvider() 16 | ) 17 | 18 | fun requestNextEdit( 19 | editor: Editor, 20 | fileContent: String, 21 | caretOffset: Int = runReadAction { editor.caretModel.offset }, 22 | addToQueue: Boolean = false, 23 | ) { 24 | val serviceType = 25 | service().getServiceForFeature(FeatureType.NEXT_EDIT) 26 | val provider = providers[serviceType] ?: return 27 | 28 | editor.project?.let { CompletionProgressNotifier.Companion.update(it, true) } 29 | provider.request(editor, fileContent, caretOffset, addToQueue) 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/action/files/IncludeOpenFilesActionItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.action.files 2 | 3 | import com.intellij.openapi.components.service 4 | import com.intellij.openapi.fileEditor.FileEditorManager 5 | import com.intellij.openapi.project.Project 6 | import ee.carlrobert.codegpt.CodeGPTBundle 7 | import ee.carlrobert.codegpt.Icons 8 | import ee.carlrobert.codegpt.ui.textarea.UserInputPanel 9 | import ee.carlrobert.codegpt.ui.textarea.header.tag.FileTagDetails 10 | import ee.carlrobert.codegpt.ui.textarea.lookup.action.AbstractLookupActionItem 11 | import javax.swing.Icon 12 | 13 | class IncludeOpenFilesActionItem : AbstractLookupActionItem() { 14 | override val displayName: String = 15 | CodeGPTBundle.get("suggestionActionItem.includeOpenFiles.displayName") 16 | override val icon: Icon = Icons.ListFiles 17 | 18 | override fun execute(project: Project, userInputPanel: UserInputPanel) { 19 | val fileTags = userInputPanel.getSelectedTags().filterIsInstance() 20 | project.service().openFiles 21 | .filter { openFile -> 22 | fileTags.none { it.virtualFile == openFile } 23 | } 24 | .forEach { 25 | userInputPanel.addTag(FileTagDetails(it)) 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/action/HistoryActionItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.action 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.openapi.project.Project 5 | import ee.carlrobert.codegpt.conversations.Conversation 6 | import ee.carlrobert.codegpt.ui.textarea.UserInputPanel 7 | import ee.carlrobert.codegpt.ui.textarea.header.tag.HistoryTagDetails 8 | import javax.swing.Icon 9 | 10 | class HistoryActionItem( 11 | private val conversation: Conversation, 12 | ) : AbstractLookupActionItem() { 13 | 14 | companion object { 15 | fun getConversationTitle(conversation: Conversation): String { 16 | return conversation.messages.firstOrNull()?.let { firstMessage -> 17 | firstMessage.prompt?.take(60) ?: firstMessage.response?.take(60) 18 | } ?: "Conversation" 19 | } 20 | } 21 | 22 | override val displayName: String 23 | get() = getConversationTitle(conversation) 24 | 25 | override val icon: Icon 26 | get() = AllIcons.General.Balloon 27 | 28 | override fun execute(project: Project, userInputPanel: UserInputPanel) { 29 | userInputPanel.addTag( 30 | HistoryTagDetails( 31 | conversationId = conversation.id, 32 | title = displayName, 33 | ) 34 | ) 35 | } 36 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/action/docs/ViewAllDocsActionItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.action.docs 2 | 3 | import com.intellij.openapi.components.service 4 | import com.intellij.openapi.options.ShowSettingsUtil 5 | import com.intellij.openapi.project.Project 6 | import ee.carlrobert.codegpt.CodeGPTBundle 7 | import ee.carlrobert.codegpt.settings.documentation.DocumentationsConfigurable 8 | import ee.carlrobert.codegpt.settings.service.FeatureType 9 | import ee.carlrobert.codegpt.settings.service.ModelSelectionService 10 | import ee.carlrobert.codegpt.settings.service.ServiceType 11 | import ee.carlrobert.codegpt.ui.textarea.UserInputPanel 12 | import ee.carlrobert.codegpt.ui.textarea.lookup.action.AbstractLookupActionItem 13 | 14 | class ViewAllDocsActionItem : AbstractLookupActionItem() { 15 | 16 | override val displayName: String = 17 | "${CodeGPTBundle.get("suggestionActionItem.viewDocumentations.displayName")} →" 18 | override val icon = null 19 | override val enabled = ModelSelectionService.getInstance().getServiceForFeature(FeatureType.CHAT) == ServiceType.PROXYAI 20 | 21 | override fun execute(project: Project, userInputPanel: UserInputPanel) { 22 | service().showSettingsDialog( 23 | project, 24 | DocumentationsConfigurable::class.java 25 | ) 26 | } 27 | } -------------------------------------------------------------------------------- /codegpt-telemetry/src/main/java/ee/carlrobert/codegpt/telemetry/core/configuration/ClasspathConfiguration.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2021 Red Hat, Inc. 3 | * Distributed under license by Red Hat, Inc. All rights reserved. 4 | * This program is made available under the terms of the 5 | * Eclipse Public License v2.0 which accompanies this distribution, 6 | * and is available at http://www.eclipse.org/legal/epl-v20.html 7 | * 8 | * Contributors: 9 | * Red Hat, Inc. - initial API and implementation 10 | ******************************************************************************/ 11 | package ee.carlrobert.codegpt.telemetry.core.configuration; 12 | 13 | import java.io.InputStream; 14 | import java.nio.file.Path; 15 | 16 | public class ClasspathConfiguration extends FileConfiguration { 17 | 18 | private final ClassLoader classloader; 19 | 20 | public ClasspathConfiguration(Path file) { 21 | this(file, ClasspathConfiguration.class.getClassLoader()); 22 | } 23 | 24 | public ClasspathConfiguration(Path file, ClassLoader classLoader) { 25 | super(file); 26 | this.classloader = classLoader; 27 | } 28 | 29 | @Override 30 | protected InputStream createInputStream(Path path) { 31 | if (path == null) { 32 | return null; 33 | } 34 | return classloader.getResourceAsStream(path.toString()); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/util/CommitWorkflowChanges.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.util; 2 | 3 | import com.intellij.openapi.vcs.FilePath; 4 | import com.intellij.openapi.vcs.changes.Change; 5 | import com.intellij.openapi.vfs.VirtualFile; 6 | import com.intellij.vcs.commit.CommitWorkflowUi; 7 | import java.util.List; 8 | import java.util.Objects; 9 | 10 | public class CommitWorkflowChanges { 11 | 12 | private final List includedVersionedFilePaths; 13 | private final List includedUnversionedFilePaths; 14 | 15 | public CommitWorkflowChanges(CommitWorkflowUi commitWorkflowUi) { 16 | includedVersionedFilePaths = commitWorkflowUi.getIncludedChanges().stream() 17 | .map(Change::getVirtualFile) 18 | .filter(Objects::nonNull) 19 | .map(VirtualFile::getPath) 20 | .toList(); 21 | includedUnversionedFilePaths = commitWorkflowUi.getIncludedUnversionedFiles().stream() 22 | .map(FilePath::getPath) 23 | .toList(); 24 | } 25 | 26 | public List getIncludedVersionedFilePaths() { 27 | return includedVersionedFilePaths; 28 | } 29 | 30 | public List getIncludedUnversionedFilePaths() { 31 | return includedUnversionedFilePaths; 32 | } 33 | 34 | public boolean isFilesSelected() { 35 | return !includedVersionedFilePaths.isEmpty() || !includedUnversionedFilePaths.isEmpty(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/action/mcp/McpServerActionItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.action.mcp 2 | 3 | import com.intellij.openapi.components.service 4 | import com.intellij.openapi.project.Project 5 | import ee.carlrobert.codegpt.Icons 6 | import ee.carlrobert.codegpt.conversations.ConversationsState 7 | import ee.carlrobert.codegpt.mcp.McpStatusBridge 8 | import ee.carlrobert.codegpt.settings.mcp.McpServerDetailsState 9 | import ee.carlrobert.codegpt.ui.textarea.UserInputPanel 10 | import ee.carlrobert.codegpt.ui.textarea.lookup.action.AbstractLookupActionItem 11 | 12 | class McpServerActionItem( 13 | private val serverDetails: McpServerDetailsState 14 | ) : AbstractLookupActionItem() { 15 | 16 | override val displayName = serverDetails.name ?: "Unknown Server" 17 | override val icon = Icons.MCP 18 | 19 | override fun execute(project: Project, userInputPanel: UserInputPanel) { 20 | val conversationId = ConversationsState.getCurrentConversation()?.id 21 | if (conversationId == null) { 22 | return 23 | } 24 | 25 | val statusBridge = service() 26 | statusBridge.attachServerAndUpdateUi( 27 | conversationId, 28 | serverDetails.id.toString(), 29 | serverDetails.name ?: "Unknown Server", 30 | userInputPanel 31 | ) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/actions/toolwindow/ClearChatWindowAction.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions.toolwindow; 2 | 3 | import com.intellij.icons.AllIcons; 4 | import com.intellij.openapi.actionSystem.ActionUpdateThread; 5 | import com.intellij.openapi.actionSystem.AnActionEvent; 6 | import com.intellij.openapi.project.DumbAwareAction; 7 | import ee.carlrobert.codegpt.actions.ActionType; 8 | import ee.carlrobert.codegpt.actions.editor.EditorActionsUtil; 9 | import ee.carlrobert.codegpt.telemetry.TelemetryAction; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | public class ClearChatWindowAction extends DumbAwareAction { 13 | 14 | private final Runnable onActionPerformed; 15 | 16 | public ClearChatWindowAction(Runnable onActionPerformed) { 17 | super("Clear Window", "Clears a chat window", AllIcons.General.Reset); 18 | this.onActionPerformed = onActionPerformed; 19 | EditorActionsUtil.registerAction(this); 20 | } 21 | 22 | @Override 23 | public void actionPerformed(@NotNull AnActionEvent event) { 24 | try { 25 | onActionPerformed.run(); 26 | } finally { 27 | TelemetryAction.IDE_ACTION.createActionMessage() 28 | .property("action", ActionType.CLEAR_CHAT_WINDOW.name()) 29 | .send(); 30 | } 31 | } 32 | 33 | @Override 34 | public @NotNull ActionUpdateThread getActionUpdateThread() { 35 | return ActionUpdateThread.BGT; 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/InceptionServiceConfigurable.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service 2 | 3 | import com.intellij.openapi.options.Configurable 4 | import ee.carlrobert.codegpt.credentials.CredentialsStore 5 | import ee.carlrobert.codegpt.credentials.CredentialsStore.CredentialKey.InceptionApiKey 6 | import ee.carlrobert.codegpt.settings.service.inception.InceptionSettingsForm 7 | import javax.swing.JComponent 8 | 9 | class InceptionServiceConfigurable : Configurable { 10 | 11 | private lateinit var component: InceptionSettingsForm 12 | 13 | override fun getDisplayName(): String { 14 | return "ProxyAI: Inception Service" 15 | } 16 | 17 | override fun createComponent(): JComponent { 18 | component = InceptionSettingsForm() 19 | component.setApiKey(CredentialsStore.getCredential(InceptionApiKey)) 20 | return component.getForm() 21 | } 22 | 23 | override fun isModified(): Boolean { 24 | return component.getApiKey() != CredentialsStore.getCredential(InceptionApiKey) 25 | } 26 | 27 | override fun apply() { 28 | CredentialsStore.setCredential(InceptionApiKey, component.getApiKey()) 29 | ModelReplacementDialog.showDialogIfNeeded(ServiceType.INCEPTION) 30 | } 31 | 32 | override fun reset() { 33 | component.setApiKey(CredentialsStore.getCredential(InceptionApiKey)) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/service/google/GoogleSettingsConfigurable.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.service.google; 2 | 3 | import com.intellij.openapi.options.Configurable 4 | import ee.carlrobert.codegpt.credentials.CredentialsStore.CredentialKey.GoogleApiKey 5 | import ee.carlrobert.codegpt.credentials.CredentialsStore.getCredential 6 | import ee.carlrobert.codegpt.credentials.CredentialsStore.setCredential 7 | import ee.carlrobert.codegpt.settings.service.ModelReplacementDialog 8 | import ee.carlrobert.codegpt.settings.service.ServiceType 9 | import javax.swing.JComponent 10 | 11 | class GoogleSettingsConfigurable : Configurable { 12 | 13 | private lateinit var component: GoogleSettingsForm 14 | 15 | override fun getDisplayName(): String { 16 | return "ProxyAI: Google Service" 17 | } 18 | 19 | override fun createComponent(): JComponent { 20 | component = GoogleSettingsForm() 21 | return component.getForm() 22 | } 23 | 24 | override fun isModified(): Boolean { 25 | return component.isModified() || component.getApiKey() != getCredential(GoogleApiKey) 26 | } 27 | 28 | override fun apply() { 29 | setCredential(GoogleApiKey, component.getApiKey()) 30 | 31 | ModelReplacementDialog.showDialogIfNeeded(ServiceType.GOOGLE) 32 | } 33 | 34 | override fun reset() { 35 | component.resetForm() 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/ui/textarea/lookup/action/WebActionItem.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.ui.textarea.lookup.action 2 | 3 | import com.intellij.icons.AllIcons 4 | import com.intellij.openapi.project.Project 5 | import ee.carlrobert.codegpt.CodeGPTBundle 6 | import ee.carlrobert.codegpt.settings.service.FeatureType 7 | import ee.carlrobert.codegpt.settings.service.ModelSelectionService 8 | import ee.carlrobert.codegpt.settings.service.ServiceType 9 | import ee.carlrobert.codegpt.ui.textarea.UserInputPanel 10 | import ee.carlrobert.codegpt.ui.textarea.header.tag.TagManager 11 | import ee.carlrobert.codegpt.ui.textarea.header.tag.WebTagDetails 12 | 13 | class WebActionItem(private val tagManager: TagManager) : AbstractLookupActionItem() { 14 | 15 | override val displayName: String = 16 | CodeGPTBundle.get("suggestionActionItem.webSearch.displayName") 17 | override val icon = AllIcons.General.Web 18 | override val enabled: Boolean 19 | get() = enabled() 20 | 21 | fun enabled(): Boolean { 22 | if (ModelSelectionService.getInstance().getServiceForFeature(FeatureType.CHAT) != ServiceType.PROXYAI) { 23 | return false 24 | } 25 | return tagManager.getTags().none { it is WebTagDetails } 26 | } 27 | 28 | override fun execute(project: Project, userInputPanel: UserInputPanel) { 29 | userInputPanel.addTag(WebTagDetails()) 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/actions/editor/OpenNewChatAction.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.actions.editor; 2 | 3 | import com.intellij.openapi.actionSystem.ActionUpdateThread; 4 | import com.intellij.openapi.actionSystem.AnAction; 5 | import com.intellij.openapi.actionSystem.AnActionEvent; 6 | import ee.carlrobert.codegpt.Icons; 7 | import ee.carlrobert.codegpt.conversations.ConversationsState; 8 | import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | public class OpenNewChatAction extends AnAction { 12 | 13 | public OpenNewChatAction() { 14 | super(Icons.OpenNewTab); 15 | } 16 | 17 | @Override 18 | public void update(@NotNull AnActionEvent event) { 19 | event.getPresentation().setEnabled(event.getProject() != null); 20 | } 21 | 22 | @Override 23 | public void actionPerformed(@NotNull AnActionEvent event) { 24 | var project = event.getProject(); 25 | if (project != null) { 26 | ConversationsState.getInstance().setCurrentConversation(null); 27 | var tabPanel = 28 | project.getService(ChatToolWindowContentManager.class).createNewTabPanel(); 29 | if (tabPanel != null) { 30 | tabPanel.displayLandingView(); 31 | } 32 | } 33 | } 34 | 35 | @Override 36 | public @NotNull ActionUpdateThread getActionUpdateThread() { 37 | return ActionUpdateThread.BGT; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/codecompletions/CodeCompletionSuggestionUpdateAdapter.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.codecompletions 2 | 3 | import com.intellij.codeInsight.inline.completion.InlineCompletionEvent 4 | import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionSuggestionUpdateManager 5 | import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionSuggestionUpdateManager.UpdateResult 6 | import com.intellij.codeInsight.inline.completion.suggestion.InlineCompletionVariant 7 | import com.intellij.openapi.editor.Editor 8 | import ee.carlrobert.codegpt.CodeGPTKeys.REMAINING_EDITOR_COMPLETION 9 | 10 | class CodeCompletionSuggestionUpdateAdapter : 11 | InlineCompletionSuggestionUpdateManager.Default() { 12 | 13 | override fun onDocumentChange( 14 | event: InlineCompletionEvent.DocumentChange, 15 | variant: InlineCompletionVariant.Snapshot 16 | ): UpdateResult { 17 | updateRemainingCompletion(event.editor, event.typing.typed) 18 | return super.onDocumentChange(event, variant) 19 | } 20 | 21 | private fun updateRemainingCompletion(editor: Editor, textToInsert: String) { 22 | val remainingCompletion = REMAINING_EDITOR_COMPLETION.get(editor) ?: "" 23 | if (remainingCompletion.isNotEmpty()) { 24 | REMAINING_EDITOR_COMPLETION.set(editor, remainingCompletion.removePrefix(textToInsert)) 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/mcp/form/McpFileProvider.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.mcp.form 2 | 3 | import com.fasterxml.jackson.databind.DeserializationFeature 4 | import com.fasterxml.jackson.databind.ObjectMapper 5 | import com.fasterxml.jackson.datatype.jdk8.Jdk8Module 6 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule 7 | import com.fasterxml.jackson.module.kotlin.KotlinModule 8 | import com.fasterxml.jackson.module.kotlin.readValue 9 | import ee.carlrobert.codegpt.settings.mcp.McpSettingsState 10 | import kotlinx.coroutines.Dispatchers 11 | import kotlinx.coroutines.withContext 12 | import java.io.File 13 | import java.io.FileWriter 14 | 15 | class McpFileProvider { 16 | 17 | private val objectMapper: ObjectMapper = ObjectMapper() 18 | .registerModule(Jdk8Module()) 19 | .registerModule(JavaTimeModule()) 20 | .registerModule(KotlinModule.Builder().build()) 21 | .apply { configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) } 22 | 23 | suspend fun writeSettings(path: String, data: McpSettingsState) = withContext(Dispatchers.IO) { 24 | val serializedData = objectMapper.writeValueAsString(data) 25 | FileWriter(path).use { 26 | it.write(serializedData) 27 | } 28 | } 29 | 30 | fun readFromFile(path: String): McpSettingsState = 31 | objectMapper.readValue(File(path)) 32 | } -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/nextedit/AcceptNextEditAction.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.nextedit 2 | 3 | import com.intellij.codeInsight.hint.HintManagerImpl 4 | import com.intellij.openapi.actionSystem.DataContext 5 | import com.intellij.openapi.editor.Caret 6 | import com.intellij.openapi.editor.Editor 7 | import com.intellij.openapi.editor.actionSystem.EditorAction 8 | import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler 9 | import ee.carlrobert.codegpt.CodeGPTKeys 10 | 11 | class AcceptNextEditAction : EditorAction(Handler()), HintManagerImpl.ActionToIgnore { 12 | 13 | companion object { 14 | const val ID = "codegpt.acceptNextEdit" 15 | } 16 | 17 | private class Handler : EditorWriteActionHandler() { 18 | 19 | override fun doExecute(editor: Editor, caret: Caret?, dataContext: DataContext?) { 20 | val diffViewer = CodeGPTKeys.EDITOR_PREDICTION_DIFF_VIEWER.get(editor) ?: return 21 | if (diffViewer.isVisible()) { 22 | diffViewer.applyChanges() 23 | } 24 | } 25 | 26 | override fun isEnabledForCaret( 27 | editor: Editor, 28 | caret: Caret, 29 | dataContext: DataContext 30 | ): Boolean { 31 | val diffViewer = CodeGPTKeys.EDITOR_PREDICTION_DIFF_VIEWER.get(editor) 32 | return diffViewer != null && diffViewer.isVisible() 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/toolwindow/chat/editor/actions/EditAction.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.toolwindow.chat.editor.actions; 2 | 3 | import com.intellij.icons.AllIcons.Actions; 4 | import com.intellij.icons.AllIcons.Diff; 5 | import com.intellij.openapi.editor.ex.EditorEx; 6 | import com.intellij.openapi.ui.JBMenuItem; 7 | import ee.carlrobert.codegpt.CodeGPTBundle; 8 | import java.awt.event.ActionEvent; 9 | import javax.swing.AbstractAction; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | public class EditAction extends AbstractAction { 13 | 14 | private final EditorEx editor; 15 | 16 | public EditAction(@NotNull EditorEx editor) { 17 | super("Edit Source", Actions.EditSource); 18 | this.editor = editor; 19 | } 20 | 21 | @Override 22 | public void actionPerformed(@NotNull ActionEvent event) { 23 | editor.setViewer(!editor.isViewer()); 24 | 25 | var viewer = editor.isViewer(); 26 | editor.setCaretVisible(!viewer); 27 | editor.setCaretEnabled(!viewer); 28 | 29 | var settings = editor.getSettings(); 30 | settings.setCaretRowShown(!viewer); 31 | 32 | var menuItem = (JBMenuItem) event.getSource(); 33 | menuItem.setText(viewer 34 | ? CodeGPTBundle.get("toolwindow.chat.editor.action.edit.title") 35 | : CodeGPTBundle.get("toolwindow.chat.editor.action.disableEditing.title")); 36 | menuItem.setIcon(viewer ? Actions.EditSource : Diff.Lock); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/ee/carlrobert/codegpt/settings/GeneralSettingsConfigurable.java: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings; 2 | 3 | import com.intellij.openapi.options.Configurable; 4 | import ee.carlrobert.codegpt.CodeGPTBundle; 5 | import javax.swing.JComponent; 6 | import org.jetbrains.annotations.Nls; 7 | import org.jetbrains.annotations.Nullable; 8 | 9 | public class GeneralSettingsConfigurable implements Configurable { 10 | 11 | private GeneralSettingsComponent component; 12 | 13 | @Override 14 | public String getDisplayName() { 15 | return CodeGPTBundle.get("settings.displayName"); 16 | } 17 | 18 | @Override 19 | public JComponent getPreferredFocusedComponent() { 20 | return component.getPreferredFocusedComponent(); 21 | } 22 | 23 | @Nullable 24 | @Override 25 | public JComponent createComponent() { 26 | component = new GeneralSettingsComponent(GeneralSettings.getInstance()); 27 | return component.getPanel(); 28 | } 29 | 30 | @Override 31 | public boolean isModified() { 32 | var settings = GeneralSettings.getCurrentState(); 33 | return !component.getDisplayName().equals(settings.getDisplayName()); 34 | } 35 | 36 | @Override 37 | public void apply() { 38 | GeneralSettings.getCurrentState().setDisplayName(component.getDisplayName()); 39 | } 40 | 41 | @Override 42 | public void reset() { 43 | component.setDisplayName(GeneralSettings.getCurrentState().getDisplayName()); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/kotlin/ee/carlrobert/codegpt/settings/models/ModelSettingsState.kt: -------------------------------------------------------------------------------- 1 | package ee.carlrobert.codegpt.settings.models 2 | 3 | import com.intellij.openapi.components.BaseState 4 | import ee.carlrobert.codegpt.settings.service.FeatureType 5 | import ee.carlrobert.codegpt.settings.service.ServiceType 6 | 7 | class ModelSettingsState : BaseState() { 8 | var modelSelections by map() 9 | 10 | init { 11 | if (modelSelections.isEmpty()) { 12 | initializeDefaults() 13 | } 14 | } 15 | 16 | private fun initializeDefaults() { 17 | val registry = ModelRegistry.getInstance() 18 | FeatureType.entries.forEach { featureType -> 19 | val defaultModel = registry.getDefaultModelForFeature(featureType) 20 | setModelSelection(featureType, defaultModel.model, defaultModel.provider) 21 | } 22 | } 23 | 24 | fun getModelSelection(featureType: FeatureType): ModelDetailsState? { 25 | return modelSelections[featureType.name] 26 | } 27 | 28 | fun setModelSelection(featureType: FeatureType, model: String?, provider: ServiceType) { 29 | modelSelections[featureType.name] = ModelDetailsState().apply { 30 | this.model = model 31 | this.provider = provider 32 | } 33 | } 34 | } 35 | 36 | class ModelDetailsState : BaseState() { 37 | var model by string() 38 | var provider by enum() 39 | } --------------------------------------------------------------------------------