├── .autodevignore ├── .cspell.json ├── .editorconfig ├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yml │ └── improvement_suggestion.yml └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .gitmodules ├── .hintrc ├── .node-version ├── .npmrc ├── .prettierrc ├── .vscode-test.js ├── .vscode ├── extensions.json ├── launch.json ├── settings.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── CONTRIBUTING.zh-cn.md ├── LICENSE ├── LICENSE.continue ├── README.md ├── autodev_tutorial.py ├── docs ├── CNAME ├── _config.yml ├── _sass │ └── custom │ │ └── custom.scss ├── catalyser │ ├── hyde-code-strategy.md │ ├── hyde-keywords-strategy.md │ ├── rag-strategy.md │ └── semantic.md ├── configuration.md ├── customize │ ├── context-providers.md │ ├── customize.md │ ├── prompt-override.md │ ├── team-prompts.md │ └── variables.md ├── development │ ├── design-princinple.md │ ├── dev-new-language.md │ ├── development.md │ ├── local-architecture.md │ └── prompt-example.md ├── devins │ └── devins.md ├── favicon.ico ├── features │ ├── auto-test.md │ ├── chat.md │ ├── code-completion.md │ ├── features.md │ ├── generate-document.md │ └── refactoring.md ├── images │ ├── settings.png │ └── sidepanel.png ├── index.md ├── quick-start.md ├── roadmap.md └── troubleshooting.md ├── examples └── ollama-chat-server │ ├── .env │ ├── .node-version │ ├── README.md │ ├── demo │ └── chat.mts │ ├── package.json │ ├── src │ ├── base │ │ ├── errors │ │ │ ├── notFound.mts │ │ │ └── serverError.mts │ │ ├── http │ │ │ ├── body.mts │ │ │ └── response.mts │ │ └── util.mts │ ├── environment.mts │ ├── main.mts │ ├── ollama │ │ └── chat.mts │ └── routes │ │ └── chat.mts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.mts ├── extension-manual-tests ├── ComprehensiveCSharpExample.cs ├── README.md ├── Sample.java ├── Sample.kt ├── Sample.rs └── typescript.ts ├── gui-sidebar ├── .gitignore ├── LICENSE ├── README.md ├── index.html ├── package.json ├── postcss.config.cjs ├── public │ ├── continue-dev-square.png │ ├── continue.gif │ ├── jetbrains_index.html │ ├── logos │ │ ├── anthropic.png │ │ ├── deepseek.png │ │ ├── flowiseai.png │ │ ├── gemini.png │ │ ├── google-palm.png │ │ ├── hf.png │ │ ├── llamacpp.png │ │ ├── llamafile.png │ │ ├── lmstudio.png │ │ ├── meta.png │ │ ├── mistral.png │ │ ├── ollama.png │ │ ├── openai.png │ │ ├── replicate.png │ │ ├── together.png │ │ └── wizardlm.png │ └── play_button.png ├── src │ ├── App.tsx │ ├── components │ │ ├── CheckDiv.tsx │ │ ├── FileIcon.tsx │ │ ├── HeaderButtonWithText.tsx │ │ ├── InfoHover.tsx │ │ ├── Layout.tsx │ │ ├── archive │ │ │ └── EditableDiv.tsx │ │ ├── dialogs │ │ │ ├── AddContextGroupDialog.tsx │ │ │ ├── AddDocsDialog.tsx │ │ │ ├── ConfirmationDialog.tsx │ │ │ ├── FTCDialog.tsx │ │ │ ├── KeyboardShortcuts.tsx │ │ │ ├── SelectContextGroupDialog.tsx │ │ │ └── index.tsx │ │ ├── gui │ │ │ ├── ErrorStepContainer.tsx │ │ │ ├── StepContainer.tsx │ │ │ └── TimelineItem.tsx │ │ ├── index.ts │ │ ├── loaders │ │ │ ├── IndexingProgressBar.tsx │ │ │ ├── Loader.tsx │ │ │ ├── ProgressBar.tsx │ │ │ └── RingLoader.tsx │ │ ├── mainInput │ │ │ ├── CodeBlockExtension.tsx │ │ │ ├── CommandsExtension.ts │ │ │ ├── ContextItemsPeek.tsx │ │ │ ├── ContinueButton.tsx │ │ │ ├── ContinueInputBox.tsx │ │ │ ├── InputToolbar.tsx │ │ │ ├── MentionExtension.ts │ │ │ ├── MentionList.tsx │ │ │ ├── TipTapEditor.css │ │ │ ├── TipTapEditor.tsx │ │ │ ├── getSuggestion.ts │ │ │ ├── resolveInput.ts │ │ │ └── types.d.ts │ │ ├── markdown │ │ │ ├── CodeBlockToolbar.tsx │ │ │ ├── CodeSnippetPreview.tsx │ │ │ ├── CopyButton.tsx │ │ │ ├── LinkableCode.tsx │ │ │ ├── MonacoCodeBlock.tsx │ │ │ ├── PreWithToolbar.tsx │ │ │ ├── StyledCode.tsx │ │ │ ├── StyledMarkdownPreview.tsx │ │ │ ├── SyntaxHighlightedPre.tsx │ │ │ ├── VSCodeFileLink.tsx │ │ │ ├── markdown.css │ │ │ └── monaco.css │ │ └── modelSelection │ │ │ ├── ModelCard.tsx │ │ │ ├── ModelSelect.tsx │ │ │ ├── ModelSettings.tsx │ │ │ └── Toggle.tsx │ ├── hooks │ │ ├── useAppendedString.ts │ │ ├── useArrayState.ts │ │ ├── useChatHandler.ts │ │ ├── useHistory.tsx │ │ ├── useNavigationListener.tsx │ │ ├── useSetup.ts │ │ ├── useSubmenuContextProviders.tsx │ │ ├── useUIConfig.ts │ │ ├── useUpdatingRef.tsx │ │ ├── useVscTheme.ts │ │ └── useWebviewListener.ts │ ├── index.css │ ├── main.tsx │ ├── pages │ │ ├── error.tsx │ │ ├── gui.tsx │ │ ├── help.tsx │ │ ├── history.tsx │ │ ├── migration.tsx │ │ ├── modelconfig.tsx │ │ ├── models.tsx │ │ ├── monaco.tsx │ │ ├── settings.tsx │ │ └── stats.tsx │ ├── redux │ │ ├── selectors │ │ │ ├── index.ts │ │ │ ├── modelSelectors.ts │ │ │ └── uiStateSelectors.ts │ │ ├── slices │ │ │ ├── configSlice.ts │ │ │ ├── miscSlice.ts │ │ │ ├── serverStateReducer.ts │ │ │ ├── stateSlice.ts │ │ │ └── uiStateSlice.ts │ │ └── store.ts │ ├── shims │ │ ├── ide.ts │ │ ├── llm-autodetect.ts │ │ ├── llm-constants.ts │ │ ├── llm-construct-messages.ts │ │ ├── messageIde.ts │ │ ├── protocol.ts │ │ ├── templates │ │ │ ├── chat.ts │ │ │ └── edit.ts │ │ ├── typings.d.ts │ │ ├── utils.ts │ │ ├── webviewIde.ts │ │ └── webviewProtocol.ts │ ├── util │ │ ├── ide.ts │ │ ├── index.ts │ │ ├── jetbrains.ts │ │ └── modelData.ts │ └── vite-env.d.ts ├── tailwind.config.cjs ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ├── l10n ├── bundle.l10n.json └── bundle.l10n.zh-cn.json ├── media ├── autodev-dark.svg ├── autodev.woff ├── icon.svg └── pluginIcon.png ├── package.json ├── package.nls.json ├── package.nls.zh-cn.json ├── pre-download-build.js ├── prompts ├── genius │ ├── en │ │ ├── cicd │ │ │ └── generate-github-action.vm │ │ ├── code │ │ │ ├── auto-doc.vm │ │ │ ├── auto-method.vm │ │ │ ├── code-complete.vm │ │ │ ├── gen-api-data.vm │ │ │ └── test-gen.vm │ │ ├── error │ │ │ └── fix-error.vm │ │ ├── hyde │ │ │ ├── code │ │ │ │ ├── evaluate.vm │ │ │ │ └── propose.vm │ │ │ └── keywords │ │ │ │ ├── evaluate.vm │ │ │ │ └── propose.vm │ │ ├── model │ │ │ └── reranker │ │ │ │ └── llm-reranker.vm │ │ ├── page │ │ │ ├── page-gen-clarify.vm │ │ │ └── page-gen-design.vm │ │ ├── practises │ │ │ ├── code-review.vm │ │ │ ├── gen-commit-msg.vm │ │ │ ├── refactoring.vm │ │ │ ├── rename.vm │ │ │ └── shell-suggest.vm │ │ ├── quick │ │ │ └── quick-action.vm │ │ ├── sql │ │ │ ├── sql-gen-clarify.vm │ │ │ └── sql-gen-design.vm │ │ └── sre │ │ │ └── generate-dockerfile.vm │ └── zh-cn │ │ ├── cicd │ │ └── generate-github-action.vm │ │ ├── code │ │ ├── auto-doc.vm │ │ ├── auto-method.vm │ │ ├── code-complete.vm │ │ └── test-gen.vm │ │ ├── error │ │ └── fix-error.vm │ │ ├── hyde │ │ ├── code │ │ │ ├── evaluate.vm │ │ │ └── propose.vm │ │ └── keywords │ │ │ ├── evaluate.vm │ │ │ └── propose.vm │ │ ├── model │ │ └── reranker │ │ │ └── llm-reranker.vm │ │ ├── page │ │ ├── page-gen-clarify.vm │ │ └── page-gen-design.vm │ │ ├── practises │ │ ├── code-review.vm │ │ ├── gen-commit-msg.vm │ │ ├── refactoring.vm │ │ ├── rename.vm │ │ └── shell-suggest.vm │ │ ├── quick │ │ └── quick-action.vm │ │ ├── sql │ │ ├── sql-gen-clarify.vm │ │ └── sql-gen-design.vm │ │ └── sre │ │ └── generate-dockerfile.vm └── team_terms.csv ├── schemas └── code-snippet-queries │ ├── tree-sitter-c-tags.scm │ ├── tree-sitter-c_sharp-tags.scm │ ├── tree-sitter-cpp-tags.scm │ ├── tree-sitter-elisp-tags.scm │ ├── tree-sitter-elixir-tags.scm │ ├── tree-sitter-elm-tags.scm │ ├── tree-sitter-go-tags.scm │ ├── tree-sitter-java-tags.scm │ ├── tree-sitter-javascript-tags.scm │ ├── tree-sitter-ocaml-tags.scm │ ├── tree-sitter-php-tags.scm │ ├── tree-sitter-python-tags.scm │ ├── tree-sitter-ql-tags.scm │ ├── tree-sitter-ruby-tags.scm │ ├── tree-sitter-rust-tags.scm │ └── tree-sitter-typescript-tags.scm ├── src ├── AutoDevExtension.ts ├── ProviderContainer.config.ts ├── ProviderLanguageProfile.config.ts ├── ProviderTypes.ts ├── action │ ├── ProviderRegister.ts │ ├── _base │ │ ├── ActionCreator.ts │ │ ├── ActionCreatorContext.ts │ │ ├── ActionExecutor.ts │ │ └── CodeActionCreator.ts │ ├── autoMethod │ │ ├── AutoMethodActionCreator.ts │ │ ├── AutoMethodActionExecutor.ts │ │ └── AutoMethodTemplateContext.ts │ ├── autodoc │ │ ├── AutoDocActionCreator.ts │ │ ├── AutoDocActionExecutor.ts │ │ └── AutoDocTemplateContext.ts │ ├── autotest │ │ ├── AutoTestActionCreator.ts │ │ └── AutoTestActionExecutor.ts │ ├── custom-action │ │ └── README.md │ ├── devops │ │ └── CommitMessageGenAction.ts │ ├── providers │ │ ├── AutoDevCodeActionProvider.ts │ │ ├── AutoDevCodeInlineCompletionProvider.ts │ │ ├── AutoDevCodeLensProvider.ts │ │ └── AutoDevQuickFixProvider.ts │ ├── refactor │ │ ├── refactor-this │ │ │ └── README.md │ │ └── rename │ │ │ ├── AutoDevRenameProvider.ts │ │ │ └── RenameLookupExecutor.ts │ ├── setting │ │ ├── SystemActionService.ts │ │ └── SystemActionType.ts │ └── test-data │ │ ├── GenApiDataActionCreator.ts │ │ └── GenApiDataExecutor.ts ├── agent │ ├── builtin │ │ ├── BuiltinFlow.ts │ │ └── autopage │ │ │ ├── AutoPage.ts │ │ │ ├── ReactAutoPage.ts │ │ │ └── UserProjectComponent.ts │ ├── catalyser │ │ └── Catalyser.ts │ └── custom │ │ ├── ConnectorConfig.ts │ │ ├── CustomAgentAuth.ts │ │ ├── CustomAgentConfig.ts │ │ ├── CustomAgentResponseAction.ts │ │ ├── CustomAgentState.ts │ │ └── CustomFlowTransition.ts ├── base │ ├── common │ │ ├── configuration │ │ │ ├── configuration.ts │ │ │ ├── configurationService.ts │ │ │ ├── context.ts │ │ │ └── contextState.ts │ │ ├── defer.ts │ │ ├── files │ │ │ ├── directory.ts │ │ │ └── files.ts │ │ ├── fs.ts │ │ ├── git.ts │ │ ├── instantiation │ │ │ ├── instantiation.ts │ │ │ └── instantiationService.ts │ │ ├── language-models │ │ │ ├── chat-models │ │ │ │ ├── qianfan.ts │ │ │ │ └── tongyi.ts │ │ │ ├── languageModels.ts │ │ │ ├── languageModelsService.ts │ │ │ └── providers │ │ │ │ ├── TongyiProvider.ts │ │ │ │ ├── WenxinProvider.ts │ │ │ │ ├── anthropicProvider.ts │ │ │ │ ├── hgTransformersProvider.ts │ │ │ │ ├── ollamaProvider.ts │ │ │ │ ├── openaiProvider.ts │ │ │ │ └── zhipuaiProvider.ts │ │ ├── languages │ │ │ ├── ParserUtil.ts │ │ │ ├── docstring.ts │ │ │ ├── languageService.ts │ │ │ └── languages.ts │ │ ├── lifecycle.ts │ │ ├── log │ │ │ └── log.ts │ │ ├── markdown │ │ │ ├── MarkdownClean.ts │ │ │ ├── MarkdownCodeBlock.ts │ │ │ ├── MarkdownTextProcessor.ts │ │ │ ├── PostCompletedCodeProcessor.ts │ │ │ └── StreamingMarkdownCodeBlock.ts │ │ ├── messages │ │ │ └── messages.ts │ │ ├── theme.ts │ │ ├── vscode.ts │ │ ├── webview │ │ │ ├── webview.ts │ │ │ └── webviewView.ts │ │ └── withCancellation.ts │ └── node │ │ ├── glob.ts │ │ ├── ignore.ts │ │ ├── merge.ts │ │ ├── timeout.ts │ │ └── tree-sitter │ │ └── treeSitterLoader.ts ├── code-context │ ├── CodeCorrectorProviderManage.ts │ ├── RelevantCodeProviderManager.ts │ ├── StructurerProviderManager.ts │ ├── TestGenProviderManager.ts │ ├── _base │ │ ├── CodeCorrector.ts │ │ ├── LanguageProfile.ts │ │ ├── RelevantCodeProvider.ts │ │ ├── StructurerProvider.ts │ │ └── test │ │ │ ├── AutoTestTemplateContext.ts │ │ │ └── TestGenProvider.ts │ ├── _indexing │ │ └── CodeContextProvider.ts │ ├── _lookup │ │ └── TestTemplateManager.ts │ ├── ast │ │ ├── TreeSitterFile.ts │ │ ├── TreeSitterUtil.ts │ │ └── TreeSitterWrapper.ts │ ├── csharp │ │ ├── CsharpCodeCorrector.ts │ │ ├── CsharpProfile.ts │ │ ├── CsharpRelevantCodeProvider.ts │ │ ├── CsharpStructurerProvider.ts │ │ ├── CsharpTestGenProvider.ts │ │ └── utils │ │ │ └── CsharpRelevantLookup.ts │ ├── go │ │ ├── GoStructurerProvider.ts │ │ ├── GoTestGenProvider.ts │ │ └── GolangProfile.ts │ ├── java │ │ ├── JavaCodeCorrector.ts │ │ ├── JavaProfile.ts │ │ ├── JavaRelevantCodeProvider.ts │ │ ├── JavaStructurerProvider.ts │ │ ├── JavaTestGenProvider.ts │ │ └── utils │ │ │ └── JavaRelevantLookup.ts │ ├── kotlin │ │ ├── KotlinProfile.ts │ │ └── KotlinStructurerProvider.ts │ ├── python │ │ ├── PythonProfile.ts │ │ └── PythonTestGenProvider.ts │ ├── rust │ │ └── RustProfile.ts │ └── typescript │ │ ├── TypeScriptProfile.ts │ │ ├── TypeScriptStructurer.ts │ │ └── TypeScriptTestGenProvider.ts ├── code-search │ ├── chunk │ │ ├── BasicChunker.ts │ │ ├── ChunkerManager.ts │ │ ├── ConstructCodeChunker.ts │ │ ├── LinePartitionChunker.ts │ │ ├── MarkdownChunker.ts │ │ ├── SymbolBasedCodeChunker.ts │ │ └── _base │ │ │ ├── Chunk.ts │ │ │ └── CollapsedCodeChunker.ts │ ├── database │ │ └── SqliteDb.ts │ ├── embedding │ │ ├── EmbeddingsProviderManager.ts │ │ ├── LocalEmbeddingsProvider.ts │ │ ├── OllamaEmbeddingsProvider.ts │ │ ├── OpenAIEmbeddingsProvider.ts │ │ ├── _base │ │ │ ├── AuthedEmbeddingsProvider.ts │ │ │ ├── BaseEmbeddingsProvider.ts │ │ │ ├── Embedding.ts │ │ │ ├── EmbeddingUtils.ts │ │ │ ├── EmbeddingsProvider.ts │ │ │ └── NamedChunk.ts │ │ └── utils │ │ │ └── withExponentialBackoff.ts │ ├── history │ │ ├── BugLooper.ts │ │ ├── TimeTravel.ts │ │ └── _base │ │ │ ├── HistoryAgent.ts │ │ │ ├── HistoryBuilder.ts │ │ │ └── TimeTravelDebugger.ts │ ├── indexing │ │ ├── ChunkCodebaseIndex.ts │ │ ├── CodeSnippetsCodebaseIndex.ts │ │ ├── CodebaseIndexer.ts │ │ ├── FullTextSearchCodebaseIndex.ts │ │ ├── GitVersionHistoryIndex.ts │ │ ├── GlobalCacheCodeBaseIndex.ts │ │ ├── LanceDbIndex.ts │ │ ├── _base │ │ │ └── CodebaseIndex.ts │ │ ├── docs │ │ │ ├── ArticleChunker.ts │ │ │ ├── ArticleCrawl.ts │ │ │ └── WebPage.ts │ │ ├── model │ │ │ └── CodebaseIndexType.ts │ │ └── third │ │ │ └── ElasticSearchIndexer.ts │ ├── refreshIndex.ts │ ├── reranker │ │ ├── LlmReranker.ts │ │ └── Reranker.ts │ ├── retrieval │ │ ├── DefaultRetrieval.ts │ │ ├── Retrieval.ts │ │ └── RetrievalQueryTerm.ts │ ├── schemas │ │ └── indexes │ │ │ ├── LICENSE │ │ │ ├── c.scm │ │ │ ├── c_sharp.scm │ │ │ ├── cpp.scm │ │ │ ├── go.scm │ │ │ ├── java.scm │ │ │ ├── javascript.scm │ │ │ ├── kotlin.scm │ │ │ ├── python.scm │ │ │ ├── rust.scm │ │ │ └── typescript.scm │ ├── scope-graph │ │ ├── ScopeBuilder.ts │ │ ├── ScopeGraph.ts │ │ ├── edge │ │ │ └── EdgeKind.ts │ │ ├── model │ │ │ ├── ImportWithRefs.ts │ │ │ ├── Namespace.ts │ │ │ ├── Symbol.ts │ │ │ ├── SymbolId.ts │ │ │ └── TextRange.ts │ │ └── node │ │ │ ├── LocalDef.ts │ │ │ ├── LocalImport.ts │ │ │ ├── LocalScope.ts │ │ │ ├── NodeKind.ts │ │ │ └── Reference.ts │ ├── search-strategy │ │ ├── HydeCodeStrategy.ts │ │ ├── HydeKeywordsStrategy.ts │ │ └── _base │ │ │ ├── HydeDocument.ts │ │ │ ├── HydeKeywords.ts │ │ │ ├── HydeStep.ts │ │ │ ├── HydeStrategy.ts │ │ │ └── StrategyFinalPrompt.ts │ ├── search │ │ ├── TfIdfChunkSearch.ts │ │ ├── _base │ │ │ ├── SearchOptions.ts │ │ │ └── SemanticSearch.ts │ │ └── tfidf │ │ │ ├── TermSplitter.ts │ │ │ └── Tfidf.ts │ ├── similar │ │ ├── SimilarChunk.ts │ │ ├── SimilarChunkSearcher.ts │ │ ├── SimilarSearchElementBuilder.ts │ │ └── algorithm │ │ │ ├── BM25Similarity.ts │ │ │ ├── JaccardSimilarity.ts │ │ │ ├── SimilarSearcher.ts │ │ │ └── TokenizedSimilarity.ts │ ├── token │ │ ├── LlmModelUtil.ts │ │ └── TokenCounter.ts │ ├── tokenizer │ │ ├── CodeTokenizer.ts │ │ ├── StopwordsBasedTokenizer.ts │ │ └── WhitespaceBasedTokenizer.ts │ └── utils │ │ ├── FileFilter.ts │ │ ├── IndexPathHelper.ts │ │ └── constants.ts ├── commands │ ├── commands.ts │ ├── commandsService.ts │ └── commandsUtils.ts ├── context-provider │ └── _base │ │ └── BaseContextProvider.ts ├── devins │ ├── DevInsLanguage.ts │ └── EmbeddMarkdown.ts ├── domain │ ├── QueryExpansion.ts │ ├── TeamTerm.ts │ └── TeamTermService.ts ├── editor │ ├── ast │ │ ├── NamedElement.ts │ │ ├── NamedElementBuilder.ts │ │ ├── PositionUtil.ts │ │ └── TextInRange.ts │ ├── cache │ │ ├── CodeFileCacheManager.ts │ │ ├── FileCacheManger.ts │ │ └── TreeSitterFileManager.ts │ ├── codemodel │ │ ├── CodeElement.ts │ │ ├── CodeElementType.ts │ │ ├── PositionElement.ts │ │ └── presenter │ │ │ ├── CommentedUmlPresenter.ts │ │ │ ├── PlantUMLPresenter.ts │ │ │ └── Presenter.ts │ ├── diff │ │ └── DiffManager.ts │ ├── editor-api │ │ ├── AutoDevStatusManager.ts │ │ ├── IdeAction.ts │ │ ├── QuickAction.ts │ │ └── VSCodeAction.ts │ └── views │ │ └── chat │ │ ├── chatViewService.ts │ │ └── continue │ │ ├── continueMessages.ts │ │ └── continueViewProvider.ts ├── extension.ts ├── git │ ├── GitAction.ts │ ├── log │ │ └── LogParser.ts │ ├── message │ │ └── IssueIdParser.ts │ ├── model │ │ └── GitCommit.ts │ └── parser │ │ └── SimpleGitLogParser.ts ├── migrations │ └── configurationMigrationHelper.ts ├── prompt-manage │ ├── ActionType.ts │ ├── InteractionType.ts │ ├── PromptManager.ts │ ├── custom-action │ │ ├── CustomActionContextBuilder.ts │ │ ├── CustomActionExecutePrompt.ts │ │ ├── CustomActionExecutor.ts │ │ ├── CustomActionPrompt.ts │ │ ├── CustomActionTemplateContext.ts │ │ └── CustomActionType.ts │ ├── executor │ │ └── FileGenerateTask.ts │ ├── loader │ │ ├── TemplateLoader.ts │ │ └── VSCodeTemplateLoader.ts │ ├── prompts-override │ │ └── PromptOverrider.ts │ ├── sample-code │ │ └── UnitTestSampleFinder.ts │ ├── team-prompts │ │ ├── TeamPromptAction.ts │ │ ├── TeamPromptExecTask.ts │ │ ├── TeamPromptsBuilder.ts │ │ └── TemplateRoleSplitter.ts │ └── template │ │ ├── TemplateContext.ts │ │ └── TemplateRender.ts ├── service │ └── Service.ts ├── test │ ├── CustomActionPrompt.test.ts │ ├── PlantUMLPresenter.test.ts │ ├── ScopeDebug.ts │ ├── ScopeTestUtil.ts │ ├── TemplateRoleSplitter.test.ts │ ├── TestLanguageService.ts │ ├── TestUtil.ts │ ├── codesearch │ │ ├── CodeChunker.test.ts │ │ ├── JaccardSimilarity.test.ts │ │ ├── LinePartitionChunker.test.ts │ │ ├── LocalInference.test.ts │ │ ├── MarkdownChunker.test.ts │ │ ├── SimilarChunkTokenizer.test.ts │ │ ├── SplitTerms.test.ts │ │ ├── TfIdfWithSemanticChunkSearch.test.ts │ │ ├── TransformersEmbeddingProvider.test.ts │ │ └── strategy │ │ │ └── RankedKeywords.test.ts │ ├── language │ │ ├── go │ │ │ ├── GoBuildToolProvider.test.ts │ │ │ ├── GoModDependencyInspector.test.ts │ │ │ ├── RelevantClassGo.test.ts │ │ │ └── ScopeBuilderGo.test.ts │ │ ├── java │ │ │ ├── BlockBuilder.test.ts │ │ │ ├── CommentUmlPresenter.test.ts │ │ │ ├── JavaStructure.test.ts │ │ │ ├── RelevantClassJava.test.ts │ │ │ ├── ScopeBuilderJava.test.ts │ │ │ └── tooling │ │ │ │ ├── GradleInfo.test.ts │ │ │ │ └── GradleVersionParser.test.ts │ │ ├── kotlin │ │ │ └── KotlinStructure.test.ts │ │ ├── markdown │ │ │ ├── MarkdownTextProcessor.test.ts │ │ │ ├── PostCodeProcessor.test.ts │ │ │ └── StreamingMarkdownCodeBlock.test.ts │ │ └── typescript │ │ │ ├── ScopeBuilderTypeScript.test.ts │ │ │ ├── TypeScriptLangConfig.test.ts │ │ │ └── TypeScriptStructure.test.ts │ └── scm │ │ └── parseGitLog.test.ts ├── toolchain-context │ ├── ToolchainContextManager.ts │ ├── ToolchainContextProvider.ts │ ├── buildtool │ │ ├── GoBuildToolProvider.ts │ │ ├── GradleBuildToolProvider.ts │ │ ├── NpmBuildToolProvider.ts │ │ ├── _base │ │ │ ├── BaseBuildToolProvider.ts │ │ │ ├── BuildToolProvider.ts │ │ │ ├── Dependence.ts │ │ │ ├── DependencyInspector.ts │ │ │ └── PackageManger.ts │ │ ├── go │ │ │ ├── GoModDependencyInspector.ts │ │ │ └── GoVersionParser.ts │ │ └── gradle │ │ │ ├── GradleDependencyInspector.ts │ │ │ └── GradleVersionInfo.ts │ ├── framework │ │ ├── cpp │ │ │ └── CppFramework.ts │ │ ├── go │ │ │ └── GoFrameworks.ts │ │ ├── javascript │ │ │ ├── JavaScriptContextProvider.ts │ │ │ ├── JavaScriptFrameworks.ts │ │ │ ├── JsDependenciesSnapshot.ts │ │ │ └── utils │ │ │ │ └── JavaScriptUtils.ts │ │ └── jvm │ │ │ ├── SpringContextProvider.ts │ │ │ ├── SpringLibrary.ts │ │ │ └── TechStack.ts │ └── version │ │ └── JavaVersionProvider.ts └── types │ └── git.d.ts ├── syntaxes ├── DevIns.tmLanguage.json └── language-configuration.json ├── tests └── vitest.setup.ts ├── tsconfig.json ├── tsconfig.node.json ├── vendors ├── bindings │ ├── LICENSE │ └── index.js └── onnxruntime-node │ ├── LICENSE │ ├── backend.cjs │ ├── binding.cjs │ ├── index.cjs │ └── version.cjs └── vite.config.mts /.autodevignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/.autodevignore -------------------------------------------------------------------------------- /.cspell.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json", 3 | "version": "0.2", 4 | "language": "en", 5 | "languageId": "typescript,javascript", 6 | "dictionaries": [ 7 | "powershell", 8 | "typescript", 9 | "node" 10 | ], 11 | "useGitignore": true, 12 | "ignorePaths": [], 13 | "words": [ 14 | "codeqwen", 15 | "identifer", 16 | "inversify", 17 | "lancedb", 18 | "ollama", 19 | "onnx", 20 | "openai", 21 | "phodal", 22 | "qianfan", 23 | "qwen", 24 | "tolist", 25 | "tongyi", 26 | "xenova" 27 | ], 28 | "allowCompoundWords": true, 29 | "overrides": [] 30 | } 31 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = tab 8 | indent_size = 2 9 | tab_width = 2 10 | continuation_indent_size = 4 # IntelliJ family IDEs 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | 17 | [Makefile] 18 | indent_size = 4 19 | indent_style = tab 20 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 6, 6 | "sourceType": "module" 7 | }, 8 | "plugins": ["@typescript-eslint"], 9 | "rules": { 10 | "@typescript-eslint/naming-convention": "warn", 11 | "@typescript-eslint/semi": "warn", 12 | "curly": "warn", 13 | "eqeqeq": "warn", 14 | "no-throw-literal": "warn", 15 | "semi": "off" 16 | }, 17 | "ignorePatterns": ["out", "dist", "**/*.d.ts"] 18 | } 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/improvement_suggestion.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: 💪 Improvement suggestion 3 | description: Share how you think AutoDev could be better 4 | labels: [enhancement] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to share your perspective! We are keen to hear how you think AutoDev could work better for you. 10 | - type: checkboxes 11 | id: checkboxes 12 | attributes: 13 | label: Validations 14 | description: Before submitting your suggested improvement 15 | options: 16 | - label: I'm not able to find an [open issue](https://github.com/unit-mesh/auto-dev-vscode/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement) that requests the same enhancement 17 | required: false 18 | - type: textarea 19 | attributes: 20 | label: Problem 21 | description: Please describe the problem you are aiming to solve with this suggested improvement. If applicable, add a screenshot, gif, or video to better convey your idea. 22 | placeholder: | 23 | Short description 24 | validations: 25 | required: false 26 | - type: textarea 27 | attributes: 28 | label: Solution 29 | description: Please describe what you might want to happen to address this issue. If applicable, add a screenshot, gif, or video to better convey your idea. 30 | placeholder: | 31 | Short description 32 | validations: 33 | required: false 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_store 2 | .history 3 | 4 | node_modules 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | # .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | 25 | # build artifacts 26 | dist 27 | dist-* 28 | temp/ 29 | out/ 30 | 31 | # package managers 32 | yarn.lock 33 | package-lock.json 34 | pnpm-lock.yaml 35 | 36 | # VSCode extension 37 | *.vsix 38 | .vscode-test 39 | coverage/ 40 | semantic/wasm 41 | 42 | vite.config.d.mts 43 | vite.config.mjs 44 | bin 45 | build/ 46 | examples/ollama-chat-server/demo/chat.mjs 47 | 48 | backup 49 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "models"] 2 | path = models 3 | url = https://github.com/unit-mesh/auto-dev-embeddings 4 | -------------------------------------------------------------------------------- /.hintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "development" 4 | ], 5 | "hints": { 6 | "axe/text-alternatives": [ 7 | "default", 8 | { 9 | "image-alt": "off" 10 | } 11 | ], 12 | "disown-opener": "off", 13 | "axe/forms": [ 14 | "default", 15 | { 16 | "label": "off" 17 | } 18 | ], 19 | "typescript-config/strict": "off" 20 | } 21 | } -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 16.x.x 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | enable-pre-post-scripts = true -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "printWidth": 120, 5 | "arrowParens": "avoid", 6 | "trailingComma": "all", 7 | "plugins": [ 8 | "@trivago/prettier-plugin-sort-imports" 9 | ], 10 | "importOrder": [ 11 | "^node:(.*)$", 12 | "", 13 | "^base/(.*)$", 14 | "^[./]" 15 | ], 16 | "importOrderParserPlugins": [ 17 | "decorators-legacy", 18 | "typescript", 19 | "explicitResourceManagement" 20 | ], 21 | "importOrderSeparation": true, 22 | "importOrderCaseInsensitive": true, 23 | "importOrderSortSpecifiers": true, 24 | "overrides": [ 25 | { 26 | "files": ".prettierrc", 27 | "options": { 28 | "parser": "json" 29 | } 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /.vscode-test.js: -------------------------------------------------------------------------------- 1 | // .vscode-test.js 2 | const { defineConfig } = require('@vscode/test-cli'); 3 | 4 | module.exports = defineConfig([ 5 | { 6 | label: 'integrationTest', 7 | files: 'out/integration-test/**/*.test.js', 8 | version: 'insiders', 9 | workspaceFolder: './sampleWorkspace' 10 | } 11 | // you can specify additional test configurations, too 12 | ]); 13 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": ["dbaeumer.vscode-eslint", "amodio.tsl-problem-matcher"] 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "cwd": "${workspaceFolder}/extensions/vscode", 13 | "args": ["--extensionDevelopmentPath=${workspaceFolder}"], 14 | "pauseForSourceMap": false, 15 | "outFiles": ["${workspaceFolder}/dist/**/*.js"], 16 | "preLaunchTask": "extension:build" 17 | }, 18 | { 19 | "name": "Extension Tests", 20 | "type": "extensionHost", 21 | "request": "launch", 22 | "args": [ 23 | "--extensionDevelopmentPath=${workspaceFolder}", 24 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 25 | ], 26 | "outFiles": [ 27 | "${workspaceFolder}/out/**/*.js", 28 | "${workspaceFolder}/dist/**/*.js" 29 | ], 30 | "preLaunchTask": "tasks: watch-tests" 31 | } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false, // set this to true to hide the "out" folder with the compiled JS files 5 | "dist": false // set this to true to hide the "dist" folder with the compiled JS files 6 | }, 7 | "search.exclude": { 8 | "out": true, // set this to false to include "out" folder in search results 9 | "dist": true // set this to false to include "dist" folder in search results 10 | }, 11 | // Turn off tsc task auto detection since we have the necessary tasks as npm scripts 12 | "typescript.tsc.autoDetect": "off", 13 | "cmake.configureOnOpen": true, 14 | "cSpell.words": [ 15 | "hoverable", 16 | "treesitter" 17 | ] 18 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .github 2 | .vscode/** 3 | .vscode-test/** 4 | out/** 5 | node_modules/** 6 | src/** 7 | .gitignore 8 | .yarnrc 9 | .cspell.json 10 | .node-version 11 | webpack.config.js 12 | vsc-extension-quickstart.md 13 | **/tsconfig.json 14 | **/.eslintrc.json 15 | **/*.map 16 | **/*.ts 17 | pnpm-lock.yaml 18 | !gui-sidebar/dist 19 | gui-sidebar/** 20 | semantic/** 21 | coverage/** 22 | extension-manual-tests/ 23 | 24 | examples/** 25 | vendors/** 26 | 27 | # ignore arm64 build for temporary 28 | dist/bin/napi-v3/linux/arm64 29 | dist/bin/napi-v3/win32/arm64 30 | dist/bin/napi-v3/linux/x64/libonnxruntime_providers_cuda.so 31 | 32 | dist/build/linux-arm64 33 | dist/build/win32-arm64 34 | #dist/build/node_sqlite3.node 35 | 36 | dist/node_modules/@lancedb/vectordb-linux-arm64-gnu 37 | 38 | # node_modules/sqlite3/node_modules 39 | # !node_modules/sqlite3 40 | # !node_modules/bindings 41 | # !node_modules/file-uri-to-path 42 | # !node_modules/web-tree-sitter 43 | 44 | # switch models for release 45 | !models/ 46 | dist/models 47 | 48 | vite.config.d.mts 49 | vite.config.mjs 50 | vite.config.mts 51 | CHANGELOG.md 52 | bin 53 | tsconfig.node.json 54 | pre-download-build.js 55 | docs 56 | bin/**/build.tar.gz 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Unit Mesh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | vscode.unitmesh.cc -------------------------------------------------------------------------------- /docs/_sass/custom/custom.scss: -------------------------------------------------------------------------------- 1 | .site-title { 2 | font-size: 14px !important; 3 | } 4 | -------------------------------------------------------------------------------- /docs/catalyser/hyde-code-strategy.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Hyde Code Strategy 4 | nav_order: 3 5 | parent: Catalyser 6 | --- 7 | 8 | Code file: HydeCodeStrategy.ts 9 | 10 | 1. generate hyde doc code from the user query 11 | 2. retrieve code snippets by hyde code from the codebase 12 | 3. summarize the code snippets and return the result 13 | 14 | ```typescript 15 | channel.appendLine("=".repeat(80)); 16 | channel.appendLine(`= Hyde Keywords Strategy: ${this.constructor.name} =`); 17 | channel.appendLine("=".repeat(80)); 18 | 19 | this.step = HydeStep.Propose; 20 | let documents = await this.generateDocument(); 21 | let hydeCode = documents.content; 22 | 23 | this.step = HydeStep.Retrieve; 24 | let chunks = await this.retrieveChunks(hydeCode); 25 | 26 | this.step = HydeStep.Evaluate; 27 | let evaluateContext: KeywordEvaluateContext = { 28 | step: this.step, 29 | question: this.query, 30 | code: chunks.map(item => item.text).join("\n"), 31 | language: "" 32 | }; 33 | 34 | if (chunks.length === 0) { 35 | channel.appendLine("No code snippets found."); 36 | return new StrategyOutput("", []); 37 | } 38 | 39 | channel.appendLine("\n"); 40 | channel.appendLine(" --- Summary --- "); 41 | let evaluateIns = await PromptManager.getInstance().renderHydeTemplate(this.step, this.documentType, evaluateContext); 42 | return new StrategyOutput(await executeIns(evaluateIns), chunks); 43 | ``` 44 | -------------------------------------------------------------------------------- /docs/catalyser/hyde-keywords-strategy.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Hyde Keywords Strategy 4 | nav_order: 2 5 | parent: Catalyser 6 | --- 7 | 8 | Code file: HydeKeywordsStrategy.ts 9 | 10 | 1. generate keywords from the user query 11 | 2. retrieve code snippets by query from the codebase 12 | 3. summarize the code snippets and return the result 13 | 14 | ```typescript 15 | this.step = HydeStep.Propose; 16 | let documents = await this.generateDocument(); 17 | let keywords = documents.content; 18 | 19 | this.step = HydeStep.Retrieve; 20 | let queryTerm = this.createQueryTerm(keywords); 21 | let chunkItems = await this.retrieveChunks(queryTerm); 22 | 23 | this.step = HydeStep.Evaluate; 24 | let evaluateContext: KeywordEvaluateContext = { 25 | step: this.step, 26 | question: keywords.question, 27 | code: chunkItems.map(item => item.text).join("\n"), 28 | language: "" 29 | }; 30 | 31 | if (chunkItems.length === 0) { 32 | channel.appendLine("No code snippets found."); 33 | return new StrategyOutput("", []); 34 | } 35 | 36 | channel.appendLine("\n"); 37 | channel.appendLine(" --- Summary --- "); 38 | let evaluateIns = await PromptManager.getInstance().renderHydeTemplate(this.step, this.documentType, evaluateContext); 39 | return new StrategyOutput(await executeIns(evaluateIns), chunkItems); 40 | ``` 41 | -------------------------------------------------------------------------------- /docs/catalyser/rag-strategy.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: RAG Strategy 4 | nav_order: 1 5 | parent: Semantic 6 | --- 7 | 8 | 9 | ### Our Strategy 10 | 11 | Key Starting Points: 12 | 13 | - HydeCodeStrategy reference to Bloop: HydeDoc 14 | - Expand `query` with domain-specific knowledge 15 | - Generate HydeDoc from `query` 16 | - use HydeDoc to semantic search 17 | - summarize the search results 18 | - HydeKeywordsStrategy reference to GitHub Copilot 19 | - Expand `query` with domain-specific knowledge 20 | - Generate keywords from `query` 21 | - use Keywords to semantic search and full-text search 22 | - summarize the search results -------------------------------------------------------------------------------- /docs/catalyser/semantic.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Catalyser 4 | nav_order: 4 5 | has_children: true 6 | permalink: /catalyser 7 | --- 8 | 9 | Related resources: 10 | 11 | - [Code Splitter](https://framework.unitmesh.cc/docs/code-splitter) 12 | 13 | 14 | ## Semantic Search RAG Strategy 15 | 16 | ### Tech Trends in Overview 17 | 18 | - GitHub Copilot Chat 19 | - TfIDF 20 | - Bloop: HydeDoc 21 | - Semantic Search 22 | - Continue.Dev: Multiple Strategy 23 | - Full Text Search 24 | - Snippet Search 25 | - Semantic Search 26 | -------------------------------------------------------------------------------- /docs/customize/context-providers.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Context Providers 4 | parent: Customize Features 5 | nav_order: 3 6 | --- -------------------------------------------------------------------------------- /docs/customize/customize.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Customize Features 4 | nav_order: 4 5 | has_children: true 6 | permalink: /customize 7 | --- 8 | 9 | {: .no_toc } 10 | -------------------------------------------------------------------------------- /docs/customize/prompt-override.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Prompt Override 4 | parent: Customize Features 5 | nav_order: 2 6 | --- 7 | 8 | Prompt Override ([#54](https://github.com/unit-mesh/auto-dev/issues/54)) will override the AutoDev prompt with your own 9 | prompt. 10 | 11 | ## How to use 12 | 13 | create a folder named `prompt/genius` in your project root directory, then create the prompt file which defined in 14 | Supported Action. 15 | 16 | For example, create a file named `prompts/genius/sql/sql-gen-clarify.vm`, will override the clarify prompt of AutoSQL/GenSQL 17 | 18 | ## Supported Action 19 | -------------------------------------------------------------------------------- /docs/customize/variables.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Variables 4 | parent: Customize Features 5 | nav_order: 999 6 | permalink: /customize/variables 7 | --- 8 | 9 | # Variables 10 | 11 | ## English version 12 | 13 | - selection: Used to get the currently selected text. 14 | - commentSymbol: Used to get the comment symbol of the current language, for example: `//`, `#`, `--`, `/* */`, etc. 15 | - beforeCursor: Used to get the text before the current cursor. 16 | - afterCursor: Used to get the text after the current cursor. 17 | - language: Used to get the language of the current file, for example: `kotlin`, `java`, `python`, `javascript`, etc. 18 | - fileName: Used to get the file name of the current file. 19 | - filePath: Used to get the file path of the current file. 20 | - methodName: Used to get the method name of the current method. 21 | - frameworkContext: Used to get the framework context of the current file, for example: `spring`, `junit`, `mockito`, 22 | etc. 23 | 24 | ## 中文版本(Chinese version) 25 | 26 | - selection: 用于获取当前选中的文本。 27 | - commentSymbol: 用于获取当前语言的注释符号,例如:`//`、`#`、`--`、`/* */` 等。 28 | - beforeCursor: 用于获取当前光标前的文本。 29 | - afterCursor: 用于获取当前光标后的文本。 30 | - language: 用于获取当前文件的语言,例如:`kotlin`、`java`、`python`、`javascript` 等。 31 | - fileName: 用于获取当前文件的文件名。 32 | - filePath: 用于获取当前文件的文件路径。 33 | - methodName: 用于获取当前方法的方法名。 34 | - frameworkContext: 用于获取当前文件的框架上下文,例如:`spring`、`junit`、`mockito` 等。 35 | -------------------------------------------------------------------------------- /docs/development/local-architecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Local Architecture 4 | nav_order: 2 5 | parent: Development 6 | --- 7 | 8 | AutoDev for Local Architecture 9 | 10 | Here is the architecture of AutoDev for Intellij IDEA and VSCode. 11 | 12 | ![AutoDev for Local](https://unitmesh.cc/auto-dev/autodev-for-local.png) 13 | -------------------------------------------------------------------------------- /docs/development/prompt-example.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Unit Test Prompt Example 4 | nav_order: 999 5 | parent: Development 6 | --- 7 | 8 | ```devin 9 | Write unit test for following java code. 10 | You are working on a project that uses Spring Boot,Spring Core,Spring MVC,JDBC,JPA to build business logic. 11 | - lang.java.prompt.basicTestTemplate 12 | // @startuml 13 | // 'package cc.unitmesh.untitled.demo.entity 14 | // 'javax.persistence.Entity 15 | // 'javax.persistence.GeneratedValue 16 | // 'javax.persistence.GenerationType 17 | // 'javax.persistence.Id 18 | // class BlogPost { 19 | // id: Long 20 | // title: String 21 | // content: String 22 | // author: String 23 | // +setId(): void 24 | // +getId(): Long 25 | // +getTitle(): String 26 | // +setTitle(): void 27 | // +getContent(): String 28 | // +setContent(): void 29 | // +getAuthor(): String 30 | // +setAuthor(): void 31 | // } 32 | // enduml 33 | // 34 | Here is the source code to be tested: 35 | 36 | ```java 37 | // imports: [] 38 | public BlogPost getBlogById(Long id) { 39 | return blogRepository.findById(id).orElse(null); 40 | } 41 | ``` 42 | 43 | Start getBlogById test code with Markdown code block here: 44 | ``` -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/docs/favicon.ico -------------------------------------------------------------------------------- /docs/features/auto-test.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Auto Testing 4 | parent: Basic Features 5 | nav_order: 2 6 | --- 7 | 8 | # Auto Testing 9 | 10 | Auto Testing is a feature that can help you test your code automatically. You can use this feature to test your 11 | code and see the result in the console. 12 | 13 | ## How to use 14 | 15 | Click `AutoTest` or `生成测试` to generate test for function. 16 | -------------------------------------------------------------------------------- /docs/features/features.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Basic Features 4 | nav_order: 3 5 | has_children: true 6 | permalink: /features 7 | --- 8 | 9 | AutoDev Overview: 10 | 11 |

12 | Overview 13 |

14 | 15 | Here is how you can work with AutoDev: 16 | 17 | {: .no_toc } 18 | -------------------------------------------------------------------------------- /docs/features/generate-document.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Generate Doc 4 | parent: Basic Features 5 | nav_order: 4 6 | --- 7 | 8 | 1. Select a code fragment and right-click to open the context menu. 9 | 2. Select AI actions and then `Generate documentation`. 10 | -------------------------------------------------------------------------------- /docs/features/refactoring.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Refactoring 4 | parent: Basic Features 5 | nav_order: 5 6 | --- 7 | 8 | In IDEA's version, we provided a refactoring feature that can help you refactor your code, see in [Refactoring](https://ide.unitmesh.cc/features/refactoring) 9 | 10 | ## Rename 11 | 12 | manual enable feature 13 | {: .label .label-yellow } 14 | 15 | Required action: You need to `Enable rename suggestion` in the settings. 16 | 17 | For more see in: RenameLookupExecutor.ts 18 | 19 | ## Others 20 | 21 | todo 22 | 23 | -------------------------------------------------------------------------------- /docs/images/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/docs/images/settings.png -------------------------------------------------------------------------------- /docs/images/sidepanel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/docs/images/sidepanel.png -------------------------------------------------------------------------------- /docs/quick-start.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Quick Start 4 | nav_order: 2 5 | permalink: /quick-start 6 | --- 7 | 8 | # Quick Start 9 | 10 | ![Extension Settings](./images/settings.png) 11 | 12 | In the vscode configuration, search for `autodev`, or click the ⚙️ button in the lower right footer of the dialog panel 13 | 14 | 在当前的设计里,由于精力不足,在 UI 设计上我们基于 Continue 的设计,因此会出现一些不符合直觉的地方,我们会在后续的版本中逐渐优化。诸如于: 15 | **Chat UI 和代码中的 LLM 模型需要分开配置。 16 | 17 | > [!IMPORTANT] 18 | > You must configure at least one big model for the plugin to work, see [Configuration](./configuration.md) for details. 19 | 20 | ## Usage 21 | 22 | Config OpenAI example: 23 | 24 | 1. open `settings.json` in vscode 25 | 2. add the following configuration 26 | 27 | ``` 28 | { 29 | "autodev.openai.apiKey": "sk-xxxxx", 30 | } 31 | ``` 32 | 33 | ### DeekSeek Example 34 | 35 | ```json 36 | "autodev.openaiCompatibleConfig": { 37 | "apiType": "openai", 38 | "model": "deepseek-chat", 39 | "apiBase": "https://api.deepseek.com/v1", 40 | "apiKey": "sk-ii" 41 | }, 42 | "autodev.openai.baseURL": "https://api.deepseek.com/v1", 43 | "autodev.openai.apiKey": "sk-ii", 44 | "autodev.chat.models": [ 45 | { 46 | "title": "DeepSeek Chat", 47 | "provider": "openai", 48 | "model": "deepseek-chat" 49 | } 50 | ], 51 | ``` 52 | 53 | ## Next 54 | 55 | - [Enable Code-completion](./features/code-completion.md) 56 | -------------------------------------------------------------------------------- /docs/troubleshooting.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Troubleshooting 4 | nav_order: 99 5 | permalink: /troubleshooting 6 | --- 7 | 8 | For debugging purposes, you can open the developer tools by clicking on `Help -> Toggle Developer Tools` in the main 9 | menu. 10 | 11 | For example: 12 | 13 | ```bash 14 | An error occurred during model execution: "TypeError: Tensor.data must be a typed array for numeric tensor.". 15 | ``` 16 | 17 | This error occurs when the model is not loaded properly. 18 | 19 | Then you can copy the error message and paste it into 20 | the [GitHub issue](https://github.com/unit-mesh/auto-dev-vscode/issues/new/choose) to get help from the AutoDev team. 21 | 22 | 23 | ## LLM Config error 24 | 25 | ### 400 status code (no body) 26 | 27 | -------------------------------------------------------------------------------- /examples/ollama-chat-server/.env: -------------------------------------------------------------------------------- 1 | # Server listening port 2 | PORT=1243 3 | 4 | # See https://github.com/ollama/ollama/blob/main/docs/api.md 5 | OLLAMA_BASE_URL=http://127.0.0.1:11434 6 | 7 | # Multiple with commas separated 8 | OLLAMA_CHAT_MODELS=llama3 9 | -------------------------------------------------------------------------------- /examples/ollama-chat-server/.node-version: -------------------------------------------------------------------------------- 1 | 18.x.x -------------------------------------------------------------------------------- /examples/ollama-chat-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ollama-chat-server", 3 | "private": true, 4 | "version": "1.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "tsx -r dotenv/config --no-warnings --watch ./src/main.mts", 8 | "build": "vite build", 9 | "preview": "node ./dist/main.mjs", 10 | "chat": "tsx -r dotenv/config ./demo/chat.mts" 11 | }, 12 | "dependencies": {}, 13 | "devDependencies": { 14 | "ansi-colors": "^4.1.3", 15 | "dotenv": "^16.4.5", 16 | "enquirer": "^2.4.1", 17 | "on-exit": "^1.0.1", 18 | "openai": "^4.47.1", 19 | "ora": "^8.0.1", 20 | "tsx": "^4.10.2", 21 | "vite": "^5.2.11", 22 | "vite-plugin-externalize-deps": "^0.8.0" 23 | }, 24 | "engines": { 25 | "node": ">=18.0.0" 26 | }, 27 | "author": "zhengxs2018", 28 | "license": "MIT" 29 | } 30 | -------------------------------------------------------------------------------- /examples/ollama-chat-server/src/base/errors/notFound.mts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/naming-convention */ 2 | import { IncomingMessage, ServerResponse } from "node:http"; 3 | 4 | export function notFound( 5 | _: IncomingMessage, 6 | res: ServerResponse 7 | ) { 8 | res.writeHead(404, { 9 | "Content-Type": "text/plain", 10 | }); 11 | res.write("Not Found", "utf8"); 12 | res.end(); 13 | } 14 | -------------------------------------------------------------------------------- /examples/ollama-chat-server/src/base/errors/serverError.mts: -------------------------------------------------------------------------------- 1 | /* eslint-disable curly */ 2 | /* eslint-disable @typescript-eslint/naming-convention */ 3 | import { STATUS_CODES, IncomingMessage, ServerResponse } from "node:http"; 4 | import { format } from "node:util"; 5 | import { Buffer } from "node:buffer"; 6 | 7 | import { canWritable } from "../http/response.mjs"; 8 | 9 | function formatErrorMessage(err?: unknown) { 10 | let message: string | undefined; 11 | 12 | if (process.env.NODE_ENV === "development") { 13 | message = 14 | err instanceof Error ? err.stack : format("non-error thrown: %j", err); 15 | } 16 | 17 | if (!message) { 18 | message = STATUS_CODES["500"] || "server error"; 19 | } 20 | 21 | return message; 22 | } 23 | 24 | export function errorHandler( 25 | _: IncomingMessage, 26 | res: ServerResponse, 27 | error?: unknown 28 | ) { 29 | if (!canWritable(res)) return; 30 | 31 | const isHeadersNoSent = !res.headersSent; 32 | const noType = res.hasHeader("Content-Type") !== true; 33 | 34 | const message = formatErrorMessage(error); 35 | 36 | if (isHeadersNoSent) { 37 | if (noType) { 38 | res.setHeader("Content-Type", "text/plan"); 39 | } 40 | 41 | res.setHeader("Content-Length", Buffer.byteLength(message as string)); 42 | } 43 | 44 | res.statusCode = 500; 45 | res.end(message, "utf8"); 46 | } 47 | -------------------------------------------------------------------------------- /examples/ollama-chat-server/src/base/http/body.mts: -------------------------------------------------------------------------------- 1 | import assert from "node:assert"; 2 | import { IncomingMessage } from "http"; 3 | 4 | export function json(req: IncomingMessage) { 5 | assert.ok( 6 | req.headers["content-type"] === "application/json", 7 | "Invalid content type" 8 | ); 9 | 10 | return new Promise((resolve, reject) => { 11 | let body = ""; 12 | 13 | req.on("data", (chunk) => { 14 | body += chunk.toString(); 15 | }); 16 | 17 | req.on("end", () => { 18 | try { 19 | resolve(JSON.parse(body)); 20 | } catch (error) { 21 | reject(error); 22 | } 23 | }); 24 | }); 25 | } 26 | 27 | export default { 28 | json, 29 | }; 30 | -------------------------------------------------------------------------------- /examples/ollama-chat-server/src/base/http/response.mts: -------------------------------------------------------------------------------- 1 | import { ServerResponse } from "http"; 2 | 3 | export function isFinished(res: ServerResponse) { 4 | return res.writableFinished || res.finished; 5 | } 6 | 7 | export function canWritable(res: ServerResponse) { 8 | if (res.writableEnded || isFinished(res)) { 9 | return false; 10 | } 11 | 12 | const socket = res.socket; 13 | 14 | // There are already pending outgoing res, but still writable 15 | // https://github.com/nodejs/node/blob/v4.4.7/lib/_http_server.js#L486 16 | return !socket || socket.writable; 17 | } 18 | -------------------------------------------------------------------------------- /examples/ollama-chat-server/src/environment.mts: -------------------------------------------------------------------------------- 1 | import { 2 | defaultsArray, 3 | getEnv, 4 | safeInteger, 5 | stringToArray, 6 | } from "./base/util.mjs"; 7 | 8 | export const PORT = safeInteger(getEnv("PORT"), 1234); 9 | 10 | export const HOST = getEnv("HOST", "localhost"); 11 | 12 | export const DEFAULT_BASE_URL = `http://${HOST}:${PORT}`; 13 | 14 | // See https://github.com/ollama/ollama/blob/main/docs/api.md 15 | export const OLLAMA_BASE_URL = getEnv( 16 | "OLLAMA_BASE_URL", 17 | "http://127.0.0.1:11434" 18 | ); 19 | 20 | export const OLLAMA_CHAT_MODELS = defaultsArray( 21 | stringToArray(getEnv("OLLAMA_CHAT_MODELS")), 22 | ["llama3"] 23 | ); 24 | 25 | export const OLLAMA_CHAT_MODEL = OLLAMA_CHAT_MODELS[0]; 26 | -------------------------------------------------------------------------------- /examples/ollama-chat-server/src/routes/chat.mts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/naming-convention */ 2 | import type { IncomingMessage, ServerResponse } from "node:http"; 3 | import { Readable } from "node:stream"; 4 | import { ReadableStream } from "node:stream/web"; 5 | 6 | import type { OpenAI } from "openai"; 7 | 8 | import body from "../base/http/body.mjs"; 9 | import { sendChatRequest } from "../ollama/chat.mjs"; 10 | 11 | export const POST = async function ( 12 | req: IncomingMessage, 13 | res: ServerResponse 14 | ) { 15 | const params = await body.json(req); 16 | const response = await sendChatRequest(params); 17 | 18 | if (params.stream) { 19 | res.writeHead(200, { 20 | "Content-Type": "text/event-stream; charset=utf-8", 21 | "Cache-Control": "no-cache", 22 | Connection: "keep-alive", 23 | "Transfer-Encoding": "chunked", 24 | }); 25 | Readable.fromWeb(response as ReadableStream).pipe(res); 26 | } else { 27 | res.writeHead(200, { 28 | "Content-Type": "application/json", 29 | }); 30 | res.end(response); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /examples/ollama-chat-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2021", 4 | "lib": ["ES2021"], 5 | "useDefineForClassFields": true, 6 | "skipLibCheck": true, 7 | 8 | /* Bundler mode */ 9 | "module": "NodeNext", 10 | "moduleResolution": "NodeNext", 11 | "esModuleInterop": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "noEmit": true, 16 | 17 | /* Linting */ 18 | "strict": true, 19 | "noUnusedLocals": false, 20 | "noUnusedParameters": false, 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": ["src"] 24 | } 25 | -------------------------------------------------------------------------------- /examples/ollama-chat-server/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "NodeNext", 6 | "moduleResolution": "NodeNext", 7 | "forceConsistentCasingInFileNames": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true 10 | }, 11 | "include": ["vite.config.mts"], 12 | "references": [ 13 | { "path": "./tsconfig.node.json" } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /examples/ollama-chat-server/vite.config.mts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import { externalizeDeps as external } from "vite-plugin-externalize-deps"; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [ 7 | external() 8 | ], 9 | build: { 10 | copyPublicDir: false, 11 | lib: { 12 | entry: "src/main.mts", 13 | formats: ["es"], 14 | fileName: "server", 15 | } 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /extension-manual-tests/README.md: -------------------------------------------------------------------------------- 1 | This folder is solely for manual testing of the extension. It contains every language feature that the extension supports. The purpose of this folder is to ensure that the extension works as expected and to provide a reference for the supported features. -------------------------------------------------------------------------------- /extension-manual-tests/Sample.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class Sample { 7 | // sample filed 8 | private String name; 9 | 10 | // sample constructor 11 | public Sample(String name) { 12 | this.name = name; 13 | } 14 | 15 | // sample method 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | //gettter and setter 21 | 22 | public void setName(String name) { 23 | this.name = name; 24 | } 25 | 26 | public static void main(String[] args) { 27 | List list = new ArrayList<>(); 28 | list.add(new Sample("A")); 29 | list.add(new Sample("B")); 30 | list.add(new Sample("C")); 31 | 32 | for (Sample sample : list) { 33 | System.out.println(sample.getName()); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /extension-manual-tests/typescript.ts: -------------------------------------------------------------------------------- 1 | console.log("hello from typescript.ts"); 2 | 3 | export class SampleClass { 4 | field: string; 5 | 6 | constructor() { 7 | console.log("SampleClass constructor"); 8 | this.field = "SampleClass field"; 9 | } 10 | 11 | setField(value: string) { 12 | this.field = value; 13 | } 14 | 15 | getField() { 16 | return this.field; 17 | } 18 | 19 | public sampleMethod() { 20 | console.log("SampleClass sampleMethod"); 21 | } 22 | } -------------------------------------------------------------------------------- /gui-sidebar/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /gui-sidebar/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE.continue -------------------------------------------------------------------------------- /gui-sidebar/README.md: -------------------------------------------------------------------------------- 1 | Shamelessly taken from [continuedev/continue](https://github.com/continuedev/continue/tree/main/gui) 2 | 3 | LICENSE is [here](../LICENSE.continue) -------------------------------------------------------------------------------- /gui-sidebar/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Continue 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /gui-sidebar/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /gui-sidebar/public/continue-dev-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/continue-dev-square.png -------------------------------------------------------------------------------- /gui-sidebar/public/continue.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/continue.gif -------------------------------------------------------------------------------- /gui-sidebar/public/jetbrains_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Continue 9 | 10 | 11 |
12 | 13 | 20 | 21 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /gui-sidebar/public/logos/anthropic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/anthropic.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/deepseek.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/deepseek.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/flowiseai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/flowiseai.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/gemini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/gemini.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/google-palm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/google-palm.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/hf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/hf.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/llamacpp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/llamacpp.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/llamafile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/llamafile.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/lmstudio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/lmstudio.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/meta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/meta.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/mistral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/mistral.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/ollama.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/ollama.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/openai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/openai.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/replicate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/replicate.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/together.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/together.png -------------------------------------------------------------------------------- /gui-sidebar/public/logos/wizardlm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/logos/wizardlm.png -------------------------------------------------------------------------------- /gui-sidebar/public/play_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/gui-sidebar/public/play_button.png -------------------------------------------------------------------------------- /gui-sidebar/src/components/CheckDiv.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | import styled from "styled-components"; 3 | import { defaultBorderRadius, vscBackground, vscForeground } from "."; 4 | import { CheckIcon } from "@heroicons/react/24/outline"; 5 | 6 | interface CheckDivProps { 7 | title: string; 8 | checked: boolean; 9 | onClick: () => void; 10 | } 11 | 12 | const StyledDiv = styled.div<{ checked: boolean }>` 13 | display: flex; 14 | flex-direction: row; 15 | align-items: center; 16 | justify-content: center; 17 | padding: 0.5rem; 18 | border-radius: ${defaultBorderRadius}; 19 | cursor: pointer; 20 | border: 1px solid ${vscForeground}; 21 | 22 | color: ${vscForeground}; 23 | background-color: ${vscBackground}; 24 | 25 | &:hover { 26 | background-color: ${vscForeground}; 27 | color: ${vscBackground}; 28 | } 29 | width: fit-content; 30 | 31 | margin: 0.5rem; 32 | height: 1.4em; 33 | 34 | overflow: hidden; 35 | text-overflow: ellipsis; 36 | `; 37 | 38 | function CheckDiv(props: CheckDivProps) { 39 | const { title, checked, onClick } = props; 40 | 41 | return ( 42 | 43 | {checked && } 44 | {title} 45 | 46 | ); 47 | } 48 | 49 | export default CheckDiv; 50 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/FileIcon.tsx: -------------------------------------------------------------------------------- 1 | import DOMPurify from "dompurify"; 2 | import { themeIcons } from "seti-file-icons"; 3 | 4 | const FileIcon = ({ filename, height, width }) => { 5 | const filenameParts = filename.includes(" (") 6 | ? filename.split(" ") 7 | : [filename, ""]; 8 | filenameParts.pop(); 9 | const getIcon = themeIcons({ 10 | blue: "#268bd2", 11 | grey: "#657b83", 12 | "grey-light": "#839496", 13 | green: "#859900", 14 | orange: "#cb4b16", 15 | pink: "#d33682", 16 | purple: "#6c71c4", 17 | red: "#dc322f", 18 | white: "#fdf6e3", 19 | yellow: "#b58900", 20 | ignore: "#586e75", 21 | }); 22 | // Sanitize the SVG string before rendering it 23 | const { svg, color } = getIcon(filenameParts.join(" ")); 24 | const sanitizedSVG = DOMPurify.sanitize(svg); 25 | 26 | return ( 27 |
31 | ); 32 | }; 33 | 34 | export default FileIcon; 35 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/InfoHover.tsx: -------------------------------------------------------------------------------- 1 | import { InformationCircleIcon } from "@heroicons/react/24/outline"; 2 | import ReactDOM from "react-dom"; 3 | import { StyledTooltip } from "."; 4 | 5 | const InfoHover = ({ msg }: { msg: string }) => { 6 | const id = `info-hover-${encodeURIComponent(msg)}`; 7 | 8 | const tooltipPortalDiv = document.getElementById("tooltip-portal-div"); 9 | 10 | return ( 11 | <> 12 | 16 | {tooltipPortalDiv && 17 | ReactDOM.createPortal( 18 | 19 | {msg} 20 | , 21 | tooltipPortalDiv 22 | )} 23 | 24 | ); 25 | }; 26 | 27 | export default InfoHover; 28 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/dialogs/AddContextGroupDialog.tsx: -------------------------------------------------------------------------------- 1 | import { ContextItemWithId } from "../../shims/typings"; 2 | import { useDispatch } from "react-redux"; 3 | import { Button, Input } from ".."; 4 | import { 5 | setDialogMessage, 6 | setShowDialog, 7 | } from "../../redux/slices/uiStateSlice"; 8 | 9 | function AddContextGroupDialog({ 10 | selectedContextItems, 11 | }: { 12 | selectedContextItems: ContextItemWithId[]; 13 | }) { 14 | const dispatch = useDispatch(); 15 | 16 | let inputElement: HTMLInputElement | null = null; 17 | 18 | const handleCreate = () => { 19 | dispatch(setDialogMessage(undefined)); 20 | dispatch(setShowDialog(false)); 21 | const title = inputElement ? inputElement.value : "My Context Group"; 22 | // TODO 23 | }; 24 | 25 | return ( 26 |
27 | { 31 | inputElement = input; 32 | }} 33 | onKeyDown={(e) => { 34 | if (e.key === "Enter") { 35 | handleCreate(); 36 | } 37 | }} 38 | /> 39 |
40 | 43 |
44 | ); 45 | } 46 | 47 | export default AddContextGroupDialog; 48 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/dialogs/ConfirmationDialog.tsx: -------------------------------------------------------------------------------- 1 | import { useDispatch } from "react-redux"; 2 | import styled from "styled-components"; 3 | import { Button } from ".."; 4 | import { 5 | setDialogMessage, 6 | setShowDialog, 7 | } from "../../redux/slices/uiStateSlice"; 8 | 9 | const GridDiv = styled.div` 10 | display: grid; 11 | grid-template-columns: 1fr 1fr; 12 | grid-gap: 8px; 13 | align-items: center; 14 | `; 15 | 16 | interface ConfirmationDialogProps { 17 | onConfirm: () => void; 18 | onCancel?: () => void; 19 | text: string; 20 | } 21 | 22 | function ConfirmationDialog(props: ConfirmationDialogProps) { 23 | const dispatch = useDispatch(); 24 | 25 | return ( 26 |
27 |

Confirmation

28 |

{props.text}

29 | 30 | 31 | 40 | 49 | 50 |
51 | ); 52 | } 53 | 54 | export default ConfirmationDialog; 55 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/loaders/Loader.tsx: -------------------------------------------------------------------------------- 1 | import { useSelector } from "react-redux"; 2 | import { RootState } from "../../redux/store"; 3 | import styled from "styled-components"; 4 | import { PlayIcon } from "@heroicons/react/24/outline"; 5 | 6 | const DEFAULT_SIZE = "28px"; 7 | 8 | const FlashingDiv = styled.div` 9 | margin-top: 16px; 10 | margin: auto; 11 | width: ${DEFAULT_SIZE}; 12 | animation: flash 1.2s infinite ease-in-out; 13 | @keyframes flash { 14 | 0% { 15 | opacity: 0.4; 16 | } 17 | 50% { 18 | opacity: 1; 19 | } 20 | 100% { 21 | opacity: 0.4; 22 | } 23 | } 24 | `; 25 | 26 | function Loader(props: { size?: string }) { 27 | const vscMediaUrl = window.vscMediaUrl; 28 | return ( 29 | 30 | {vscMediaUrl ? ( 31 | 32 | ) : ( 33 | 34 | )} 35 | 36 | ); 37 | } 38 | 39 | export default Loader; 40 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/mainInput/TipTapEditor.css: -------------------------------------------------------------------------------- 1 | .mention { 2 | background-color: var(--vscode-badge-background, #bfe2b6); 3 | color: var(--vscode-badge-foreground, --vscode-foreground, #000); 4 | border-radius: 3px; 5 | font-size: 0.9em; 6 | padding: 0.05em 0.15em; 7 | transition: background-color 0.2s ease-in-out; 8 | } 9 | 10 | .command-suggestion { 11 | background-color: var(--vscode-badge-background, #bfe2b6); 12 | color: var(--vscode-badge-foreground, --vscode-foreground, #000); 13 | border-radius: 3px; 14 | font-size: 0.9em; 15 | padding: 0.05em 0.15em; 16 | transition: background-color 0.2s ease-in-out; 17 | } 18 | 19 | .tiptap p.is-editor-empty:first-child::before { 20 | color: #646464; /* lightGray */ 21 | content: attr(data-placeholder); 22 | float: left; 23 | height: 0; 24 | pointer-events: none; 25 | } 26 | 27 | .gap-cursor { 28 | border-top: 1px solid white; 29 | } 30 | 31 | .tiptap img { 32 | height: auto; 33 | max-width: 96%; 34 | border: 1px solid transparent; 35 | } 36 | 37 | .tiptap img.ProseMirror-selectednode { 38 | border: 1px solid var(--vscode-badge-background, #bfe2b6); 39 | } 40 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/mainInput/types.d.ts: -------------------------------------------------------------------------------- 1 | import { ContextProviderDescription } from "core"; 2 | 3 | export type ComboBoxItemType = 4 | | "contextProvider" 5 | | "slashCommand" 6 | | "file" 7 | | "query" 8 | | "folder" 9 | | "action"; 10 | 11 | export interface ComboBoxItem { 12 | title: string; 13 | description: string; 14 | id?: string; 15 | content?: string; 16 | type: ComboBoxItemType; 17 | contextProvider?: ContextProviderDescription; 18 | query?: string; 19 | label?: string; 20 | action?: () => void; 21 | } 22 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/markdown/CopyButton.tsx: -------------------------------------------------------------------------------- 1 | import { CheckIcon, ClipboardIcon } from "@heroicons/react/24/outline"; 2 | import { useState } from "react"; 3 | import { vscEditorBackground } from ".."; 4 | import HeaderButtonWithText from "../HeaderButtonWithText"; 5 | 6 | interface CopyButtonProps { 7 | text: string | (() => string); 8 | } 9 | 10 | export function CopyButton(props: CopyButtonProps) { 11 | const [copied, setCopied] = useState(false); 12 | 13 | return ( 14 | <> 15 | { 19 | navigator.clipboard.writeText( 20 | typeof props.text === "string" ? props.text : props.text(), 21 | ); 22 | setCopied(true); 23 | setTimeout(() => setCopied(false), 2000); 24 | }} 25 | > 26 | {copied ? ( 27 | 28 | ) : ( 29 | 30 | )} 31 | 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/markdown/StyledCode.tsx: -------------------------------------------------------------------------------- 1 | import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; 2 | import { vscDarkPlus as highlightStyle } from "react-syntax-highlighter/dist/esm/styles/prism"; 3 | 4 | interface StyledCodeProps { 5 | children: string; 6 | language?: string; 7 | } 8 | 9 | const StyledCode = (props: StyledCodeProps) => ( 10 | 15 | {props.children} 16 | 17 | ); 18 | 19 | export default StyledCode; 20 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/markdown/SyntaxHighlightedPre.tsx: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | import styled from "styled-components"; 3 | import { vscForeground } from ".."; 4 | import { VscThemeContext } from "../../App"; 5 | 6 | const StyledPre = styled.pre<{ theme: any }>` 7 | & .hljs { 8 | color: ${vscForeground}; 9 | } 10 | 11 | ${(props) => 12 | Object.keys(props.theme) 13 | .map((key, index) => { 14 | return ` 15 | & ${key} { 16 | color: ${props.theme[key]}; 17 | } 18 | `; 19 | }) 20 | .join("")} 21 | `; 22 | 23 | export const SyntaxHighlightedPre = (props: any) => { 24 | const currentTheme = useContext(VscThemeContext); 25 | 26 | return ; 27 | }; 28 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/markdown/VSCodeFileLink.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { postToIde } from "../../util/ide"; 3 | 4 | function VSCodeFileLink(props: { path: string; text?: string }) { 5 | return ( 6 | { 9 | postToIde("openFile", { path: props.path }); 10 | }} 11 | > 12 | {props.text || props.path} 13 | 14 | ); 15 | } 16 | 17 | export default VSCodeFileLink; 18 | -------------------------------------------------------------------------------- /gui-sidebar/src/components/markdown/monaco.css: -------------------------------------------------------------------------------- 1 | .monaco-editor .margin { 2 | padding-top: 4px; 3 | } 4 | -------------------------------------------------------------------------------- /gui-sidebar/src/hooks/useAppendedString.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from "react"; 2 | 3 | export function useAppendedString( 4 | fullString: string, 5 | append: (chunk: string, lineCount: number) => void 6 | ) { 7 | // Queue of fullString updated versions to be processed atomically 8 | const [updateQueue, setUpdateQueue] = useState([]); 9 | const lastString = useRef(""); 10 | const processing = useRef(false); 11 | 12 | useEffect(() => { 13 | setUpdateQueue((prev) => [...prev, fullString]); 14 | }, [fullString]); 15 | 16 | useEffect(() => { 17 | if (updateQueue.length === 0 || processing.current) return; 18 | 19 | processing.current = true; 20 | setUpdateQueue((currentQueue) => { 21 | while (currentQueue.length > 0) { 22 | const nextString = currentQueue.shift()!; 23 | if (!nextString.startsWith(lastString.current)) { 24 | // Invalid 25 | continue; 26 | } 27 | const appendedPart = nextString.slice(lastString.current.length); 28 | lastString.current = nextString; 29 | append(appendedPart, lastString.current.split("\n").length); 30 | } 31 | return currentQueue; 32 | }); 33 | processing.current = false; 34 | }, [updateQueue]); 35 | } 36 | -------------------------------------------------------------------------------- /gui-sidebar/src/hooks/useArrayState.ts: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | function useArrayState(initialValue: T[]) { 4 | const [value, setValue] = useState(initialValue); 5 | 6 | function add(item: any) { 7 | setValue((prev) => [...prev, item]); 8 | } 9 | 10 | function remove(index: number) { 11 | setValue((prev) => prev.filter((_, i) => i !== index)); 12 | } 13 | 14 | function edit(editFn: (prev: T[]) => T[]) { 15 | setValue((prev) => editFn(prev)); 16 | } 17 | 18 | function replace(atIndex: number, withItem: T) { 19 | setValue((prev) => { 20 | let updated = [...prev]; 21 | updated[atIndex] = withItem; 22 | return updated; 23 | }); 24 | } 25 | 26 | return { value, add, remove, edit, replace }; 27 | } 28 | 29 | export default useArrayState; 30 | -------------------------------------------------------------------------------- /gui-sidebar/src/hooks/useNavigationListener.tsx: -------------------------------------------------------------------------------- 1 | import { ReverseWebviewProtocol } from "../shims/webviewProtocol"; 2 | import { useLocation, useNavigate } from "react-router-dom"; 3 | import { v4 as uuidv4 } from "uuid"; 4 | import { useWebviewListener } from "./useWebviewListener"; 5 | 6 | const openGUITypes: (keyof ReverseWebviewProtocol)[] = [ 7 | "highlightedCode", 8 | "newSessionWithPrompt", 9 | "focusAutoDevInput", 10 | "focusAutoDevInputWithoutClear", 11 | "newSession", 12 | ]; 13 | 14 | export const useNavigationListener = () => { 15 | const navigate = useNavigate(); 16 | const location = useLocation(); 17 | 18 | for (const messageType of openGUITypes) { 19 | useWebviewListener( 20 | messageType, 21 | async (data) => { 22 | navigate("/"); 23 | setTimeout(() => { 24 | window.postMessage( 25 | { 26 | messageType, 27 | data, 28 | messageId: uuidv4(), 29 | }, 30 | "*" 31 | ); 32 | }, 200); 33 | }, 34 | [navigate] 35 | ); 36 | } 37 | 38 | useWebviewListener( 39 | "viewHistory", 40 | async () => { 41 | // Toggle the history page / main page 42 | if (location.pathname === "/history") { 43 | navigate("/"); 44 | } else { 45 | navigate("/history"); 46 | } 47 | }, 48 | [location, navigate] 49 | ); 50 | }; 51 | -------------------------------------------------------------------------------- /gui-sidebar/src/hooks/useUIConfig.ts: -------------------------------------------------------------------------------- 1 | import { useSelector } from 'react-redux'; 2 | import { RootState } from '../redux/store'; 3 | 4 | function useUIConfig() { 5 | return useSelector((store: RootState) => store.state.config.ui); 6 | } 7 | 8 | export default useUIConfig; 9 | -------------------------------------------------------------------------------- /gui-sidebar/src/hooks/useUpdatingRef.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | 3 | function useUpdatingRef(value: T, deps: any[] = []) { 4 | const ref = useRef(value); 5 | 6 | useEffect(() => { 7 | ref.current = value; 8 | }, [value, ...deps]); 9 | 10 | return ref; 11 | } 12 | 13 | export default useUpdatingRef; 14 | -------------------------------------------------------------------------------- /gui-sidebar/src/hooks/useWebviewListener.ts: -------------------------------------------------------------------------------- 1 | import { Message } from "../shims/typings"; 2 | import { ReverseWebviewProtocol } from "../shims/webviewProtocol"; 3 | import { useEffect } from "react"; 4 | import { respondToIde } from "../util/ide"; 5 | 6 | export function useWebviewListener( 7 | messageType: T, 8 | handler: ( 9 | data: ReverseWebviewProtocol[T][0] 10 | ) => Promise, 11 | dependencies?: any[] 12 | ) { 13 | useEffect(() => { 14 | const listener = async (event: { data: Message }) => { 15 | if (event.data.messageType === messageType) { 16 | const result = await handler(event.data.data); 17 | respondToIde(messageType, result, event.data.messageId); 18 | } 19 | }; 20 | window.addEventListener("message", listener); 21 | return () => { 22 | window.removeEventListener("message", listener); 23 | }; 24 | }, dependencies ?? []); 25 | } 26 | -------------------------------------------------------------------------------- /gui-sidebar/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | :root { 6 | --secondary-dark: rgb(37, 37, 38); 7 | --vsc-background: rgb(30, 30, 30); 8 | --button-color: rgb(113, 28, 59); 9 | --button-color-hover: rgba(113, 28, 59, 0.667); 10 | --def-border-radius: 5px; 11 | 12 | --vscode-editor-background: rgb(30, 30, 30); 13 | --vscode-editor-foreground: rgb(197, 200, 198); 14 | --vscode-textBlockQuote-background: rgba(255, 255, 255, 1); 15 | } 16 | 17 | html, 18 | body, 19 | #root { 20 | height: 100%; 21 | background-color: var(--vscode-editor-background); 22 | font-family: 23 | system-ui, 24 | -apple-system, 25 | BlinkMacSystemFont, 26 | "Segoe UI", 27 | Roboto, 28 | Oxygen, 29 | Ubuntu, 30 | Cantarell, 31 | "Open Sans", 32 | "Helvetica Neue", 33 | sans-serif; 34 | } 35 | 36 | body { 37 | padding: 0; 38 | color: var(--vscode-editor-foreground); 39 | padding: 0px; 40 | margin: 0px; 41 | height: 100%; 42 | } 43 | 44 | a:focus { 45 | outline: none; 46 | } 47 | 48 | @keyframes fadeIn { 49 | from { 50 | opacity: 0; 51 | } 52 | to { 53 | opacity: 1; 54 | } 55 | } 56 | 57 | .fade-in-span { 58 | animation: fadeIn 0.3s ease-in-out; 59 | } 60 | -------------------------------------------------------------------------------- /gui-sidebar/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import { Provider } from "react-redux"; 4 | import { PersistGate } from "redux-persist/integration/react"; 5 | import App from "./App"; 6 | import "./index.css"; 7 | import { persistor, store } from "./redux/store"; 8 | 9 | (async () => { 10 | ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( 11 | 12 | 13 | 14 | 15 | 16 | 17 | , 18 | ); 19 | })(); 20 | -------------------------------------------------------------------------------- /gui-sidebar/src/pages/error.tsx: -------------------------------------------------------------------------------- 1 | import { useDispatch } from "react-redux"; 2 | import { useNavigate, useRouteError } from "react-router-dom"; 3 | import { newSession } from "../redux/slices/stateSlice"; 4 | import ContinueButton from "../components/mainInput/ContinueButton"; 5 | import { vscBackground } from "../components"; 6 | 7 | export default function ErrorPage() { 8 | const error: any = useRouteError(); 9 | console.error(error); 10 | const dispatch = useDispatch(); 11 | const navigate = useNavigate(); 12 | 13 | return ( 14 |
19 |

Error in AutoDev Debug page

20 |

21 | {error.statusText || error.message} 22 |

23 |
24 |

Click below to continue

25 |
26 | { 30 | dispatch(newSession()); 31 | localStorage.removeItem("persist:root"); 32 | navigate("/"); 33 | }} 34 | > 35 |
36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /gui-sidebar/src/redux/selectors/index.ts: -------------------------------------------------------------------------------- 1 | import { createSelector } from "@reduxjs/toolkit"; 2 | import { ComboBoxItemType } from "../../components/mainInput/types"; 3 | import { RootState } from "../store"; 4 | 5 | export const selectSlashCommands = createSelector( 6 | [(store: RootState) => store.state.config.slashCommands], 7 | (slashCommands) => { 8 | return ( 9 | slashCommands?.map((cmd) => { 10 | return { 11 | title: `/${cmd.name}`, 12 | description: cmd.description, 13 | type: "slashCommand" as ComboBoxItemType, 14 | }; 15 | }) || [] 16 | ); 17 | } 18 | ); 19 | 20 | export const selectContextProviderDescriptions = createSelector( 21 | [(store: RootState) => store.state.config.contextProviders], 22 | (providers) => { 23 | return providers.filter((desc) => desc.type === "submenu") || []; 24 | } 25 | ); 26 | -------------------------------------------------------------------------------- /gui-sidebar/src/redux/selectors/modelSelectors.ts: -------------------------------------------------------------------------------- 1 | import { DEFAULT_MAX_TOKENS } from "../../shims/llm-constants"; 2 | import { RootState } from "../store"; 3 | import { ModelDescription } from "../../shims/typings"; 4 | 5 | export const defaultModelSelector = (state: RootState) => { 6 | const title = state.state.defaultModelTitle ?? ""; 7 | return state.state.config.models.find((model: ModelDescription) => model.title === title) 8 | }; 9 | 10 | export const contextLengthSelector = (state: RootState) => { 11 | return defaultModelSelector(state)?.contextLength || DEFAULT_MAX_TOKENS; 12 | }; 13 | -------------------------------------------------------------------------------- /gui-sidebar/src/redux/selectors/uiStateSelectors.ts: -------------------------------------------------------------------------------- 1 | import { RootState } from "../store"; 2 | 3 | const selectBottomMessage = (state: RootState) => state.uiState.bottomMessage; 4 | 5 | export { selectBottomMessage }; 6 | -------------------------------------------------------------------------------- /gui-sidebar/src/redux/slices/configSlice.ts: -------------------------------------------------------------------------------- 1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit"; 2 | 3 | export const configSlice = createSlice({ 4 | name: "config", 5 | initialState: { 6 | vscMachineId: window.vscMachineId, 7 | }, 8 | reducers: { 9 | setVscMachineId: (state, action: PayloadAction) => { 10 | state.vscMachineId = action.payload; 11 | }, 12 | }, 13 | }); 14 | 15 | export const { setVscMachineId } = configSlice.actions; 16 | export default configSlice.reducer; 17 | -------------------------------------------------------------------------------- /gui-sidebar/src/redux/slices/miscSlice.ts: -------------------------------------------------------------------------------- 1 | import { PayloadAction, createSlice } from "@reduxjs/toolkit"; 2 | 3 | export const miscSlice = createSlice({ 4 | name: "misc", 5 | initialState: { 6 | takenAction: false, 7 | serverStatusMessage: "Continue Server Starting", 8 | }, 9 | reducers: { 10 | setTakenActionTrue: (state) => { 11 | state.takenAction = true; 12 | }, 13 | setServerStatusMessage: (state, action: PayloadAction) => { 14 | state.serverStatusMessage = action.payload; 15 | }, 16 | }, 17 | }); 18 | 19 | export const { setTakenActionTrue, setServerStatusMessage } = miscSlice.actions; 20 | export default miscSlice.reducer; 21 | -------------------------------------------------------------------------------- /gui-sidebar/src/shims/llm-constants.ts: -------------------------------------------------------------------------------- 1 | const DEFAULT_MAX_TOKENS = 1024; 2 | const DEFAULT_CONTEXT_LENGTH = 4096; 3 | const DEFAULT_TEMPERATURE = 0.5; 4 | 5 | const DEFAULT_ARGS = { 6 | maxTokens: DEFAULT_MAX_TOKENS, 7 | temperature: DEFAULT_TEMPERATURE, 8 | }; 9 | 10 | const CONTEXT_LENGTH_FOR_MODEL: { [name: string]: number } = { 11 | "gpt-4": 8192, 12 | "gpt-4-32k": 32_768, 13 | "gpt-4-turbo-preview": 128_000, 14 | "gpt-4-vision": 128_000, 15 | "gpt-4-0125-preview": 128_000, 16 | "gpt-4-1106-preview": 128_000, 17 | "gpt-4o-mini": 4096, 18 | }; 19 | 20 | const TOKEN_BUFFER_FOR_SAFETY = 350; 21 | const PROXY_URL = "http://localhost:65433"; 22 | 23 | const MAX_CHUNK_SIZE = 500; // 512 - buffer for safety (in case of differing tokenizers) 24 | 25 | export { 26 | CONTEXT_LENGTH_FOR_MODEL, 27 | DEFAULT_ARGS, 28 | DEFAULT_CONTEXT_LENGTH, 29 | DEFAULT_MAX_TOKENS, 30 | MAX_CHUNK_SIZE, 31 | PROXY_URL, 32 | TOKEN_BUFFER_FOR_SAFETY, 33 | }; 34 | -------------------------------------------------------------------------------- /gui-sidebar/src/shims/llm-construct-messages.ts: -------------------------------------------------------------------------------- 1 | import { ChatHistory, ChatMessage, MessagePart } from "./typings"; 2 | 3 | export function constructMessages(history: ChatHistory): ChatMessage[] { 4 | const msgs = []; 5 | 6 | for (let i = 0; i < history.length; i++) { 7 | const historyItem = history[i]; 8 | 9 | let content = Array.isArray(historyItem.message.content) 10 | ? historyItem.message.content 11 | : [{ type: "text", text: historyItem.message.content } as MessagePart]; 12 | 13 | const ctxItems = historyItem.contextItems.map((ctxItem) => { 14 | return { type: "text", text: ctxItem.content + "\n" } as MessagePart; 15 | }); 16 | 17 | content = [...ctxItems, ...content]; 18 | 19 | msgs.push({ 20 | role: historyItem.message.role, 21 | content, 22 | }); 23 | } 24 | 25 | return msgs; 26 | } 27 | -------------------------------------------------------------------------------- /gui-sidebar/src/shims/webviewIde.ts: -------------------------------------------------------------------------------- 1 | import { MessageIde } from "./messageIde"; 2 | import { WebviewProtocol } from "./webviewProtocol"; 3 | import { ideRequest } from "./ide"; 4 | function r( 5 | messageType: T, 6 | data: WebviewProtocol[T][0] 7 | ): Promise { 8 | return ideRequest(messageType, data); 9 | } 10 | 11 | export class WebviewIde extends MessageIde { 12 | constructor() { 13 | super(r); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /gui-sidebar/src/util/index.ts: -------------------------------------------------------------------------------- 1 | type Platform = "mac" | "linux" | "windows" | "unknown"; 2 | 3 | export function getPlatform(): Platform { 4 | const platform = window.navigator.platform.toUpperCase(); 5 | if (platform.indexOf("MAC") >= 0) { 6 | return "mac"; 7 | } else if (platform.indexOf("LINUX") >= 0) { 8 | return "linux"; 9 | } else if (platform.indexOf("WIN") >= 0) { 10 | return "windows"; 11 | } else { 12 | return "unknown"; 13 | } 14 | } 15 | 16 | export function isMetaEquivalentKeyPressed(event: { 17 | metaKey: boolean; 18 | ctrlKey: boolean; 19 | }): boolean { 20 | const platform = getPlatform(); 21 | switch (platform) { 22 | case "mac": 23 | return event.metaKey; 24 | case "linux": 25 | case "windows": 26 | return event.ctrlKey; 27 | default: 28 | return event.metaKey; 29 | } 30 | } 31 | 32 | export function getMetaKeyLabel(): string { 33 | const platform = getPlatform(); 34 | switch (platform) { 35 | case "mac": 36 | return "⌘"; 37 | case "linux": 38 | case "windows": 39 | return "^"; 40 | default: 41 | return "^"; 42 | } 43 | } 44 | 45 | export function getFontSize(): number { 46 | const fontSize = localStorage.getItem("fontSize"); 47 | return fontSize ? parseInt(fontSize) : 14; 48 | } 49 | -------------------------------------------------------------------------------- /gui-sidebar/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /gui-sidebar/tailwind.config.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | const colors = require("tailwindcss/colors"); 3 | 4 | module.exports = { 5 | content: [ 6 | "./index.html", 7 | "./src/**/*.{js,ts,jsx,tsx}", 8 | "./src/*.{js,ts,jsx,tsx}", 9 | ], 10 | theme: { 11 | extend: {}, 12 | colors: { 13 | "vsc-background": "rgb(var(--vsc-background) / )", 14 | "secondary-dark": "rgb(var(--secondary-dark) / )", 15 | ...colors, 16 | }, 17 | }, 18 | plugins: [], 19 | corePlugins: { 20 | preflight: false, 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /gui-sidebar/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": false, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx", 18 | "noEmitOnError": false 19 | }, 20 | "include": ["src", "../src/util/messenger.ts"], 21 | "references": [{ "path": "./tsconfig.node.json" }] 22 | } 23 | -------------------------------------------------------------------------------- /gui-sidebar/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /gui-sidebar/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from "@vitejs/plugin-react-swc"; 2 | import tailwindcss from "tailwindcss"; 3 | import { defineConfig } from "vite"; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [react(), tailwindcss()], 8 | build: { 9 | // Change the output .js filename to not include a hash 10 | rollupOptions: { 11 | // external: ["vscode-webview"], 12 | output: { 13 | entryFileNames: `assets/[name].js`, 14 | chunkFileNames: `assets/[name].js`, 15 | assetFileNames: `assets/[name].[ext]`, 16 | }, 17 | }, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /l10n/bundle.l10n.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang.java.prompt.basicTestTemplate": "You MUST use should_xx_xx style for test method name, You MUST use given-when-then style.\nTest file should be complete and compilable, without need for further actions.\nEnsure that each test focuses on a single use case to maintain clarity and readability.\nInstead of using `@BeforeEach` methods for setup, include all necessary code initialization within each individual test method, do not write parameterized tests.", 3 | "lang.java.prompt.testForController": "Use appropriate Spring test annotations such as `@MockBean`, `@Autowired`, `@WebMvcTest`, `@DataJpaTest`, `@AutoConfigureTestDatabase`, `@AutoConfigureMockMvc`, `@SpringBootTest` etc", 4 | "lang.java.prompt.testForService": "Follow the common Spring code style by using the AssertJ library.\nAssume that the database is empty before each test and create valid entities with consideration for data constraints (jakarta.validation.constraints).", 5 | "lang.java.prompt.useJunit4": "This project uses JUnit 4, you should import `org.junit.Test` and use `@Test` annotation.", 6 | "lang.java.prompt.useJunit5": "This project uses JUnit 5, you should import `org.junit.jupiter.api.Test` and use `@Test` annotation." 7 | } 8 | -------------------------------------------------------------------------------- /l10n/bundle.l10n.zh-cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "AutoTest": "生成测试", 3 | "AutoComment": "生成注释", 4 | "Custom Action": "自定义动作", 5 | "Explain Code": "解释代码", 6 | "Optimize Code": "优化代码", 7 | "Fix Code": "修复代码", 8 | "Quick Chat": "快速聊天", 9 | "AutoMethod": "填充当前方法", 10 | "Optimize the code": "请优化下面的代码", 11 | "How do I fix this problem in the above code?": "请帮我修复下面代码中的问题:", 12 | "I got the following error, can you please help explain how to fix it?": "我遇到了以下错误,请帮我解释如何修复它?", 13 | "Explain this code": "请解释如下代码", 14 | "Show Logs": "显示日志", 15 | "The contents of the current codebase will be used to Autodev build the index stored on your computer, this information is only used by us to improve the quality of the code generated by the current codebase and will not be used for any other purpose.": "当前代码库的内容将被用于 Autodev 构建索引并存于你的电脑上,此信息我们仅用于提升当前代码库生成代码的质量,不会用于其他用途。", 16 | "Authorize": "授权" 17 | } 18 | -------------------------------------------------------------------------------- /media/autodev.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/media/autodev.woff -------------------------------------------------------------------------------- /media/pluginIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/media/pluginIcon.png -------------------------------------------------------------------------------- /prompts/genius/en/cicd/generate-github-action.vm: -------------------------------------------------------------------------------- 1 | Create build.yml YAML file for GitHub Action for build project and runs tests 2 | 3 | - ${context.buildContext} 4 | - OS: latest ubuntu version 5 | -------------------------------------------------------------------------------- /prompts/genius/en/code/auto-doc.vm: -------------------------------------------------------------------------------- 1 | Write documentation for user's given ${context.language} code. 2 | #if($context.chatContext.length > 0 ) 3 | ${context.chatContext} 4 | #end 5 | #if($context.forbiddenRules.length > 0) 6 | ${context.forbiddenRules} 7 | #end 8 | - Start your documentation with ${context.startSymbol} here, and ends with `${context.endSymbol}`. 9 | Here is User's code: 10 | ```${context.language} 11 | ${context.code} 12 | ``` 13 | #if($context.originalComments.length > 0) 14 | Here is code Origin comment: ${context.originalComments} 15 | Please according to the code to update documentation. 16 | #end 17 | Please write documentation for user's code inside the Markdown code block. 18 | -------------------------------------------------------------------------------- /prompts/genius/en/code/auto-method.vm: -------------------------------------------------------------------------------- 1 | Write documentation for user's given ${context.language} code. 2 | #if($context.chatContext.length > 0 ) 3 | ${context.chatContext} 4 | #end 5 | #if($context.forbiddenRules.length > 0) 6 | ${context.forbiddenRules} 7 | #end 8 | - Start your documentation with ${context.startSymbol} here, and ends with `${context.endSymbol}`. 9 | Here is User's code: 10 | ```${context.language} 11 | ${context.code} 12 | ``` 13 | #if($context.originalComments.length > 0) 14 | Here is code Origin comment: ${context.originalComments} 15 | Please according to the code to update documentation. 16 | #end 17 | Please write documentation for user's code inside the Markdown code block. 18 | -------------------------------------------------------------------------------- /prompts/genius/en/code/code-complete.vm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/prompts/genius/en/code/code-complete.vm -------------------------------------------------------------------------------- /prompts/genius/en/code/gen-api-data.vm: -------------------------------------------------------------------------------- 1 | Generate JSON data (with markdown code block) based on given ${context.language} code and request/response info. 2 | So that we can use it to test for APIs. 3 | 4 | Use the following template to generate the JSON data: 5 | 6 | action: // request method, url: // the request url 7 | request: 8 | // the request body in json 9 | response: 10 | // the response body in json 11 | 12 | For example: 13 | 14 | ``` 15 | GET /api/v1/users 16 | request: 17 | { 18 | "body": "hello" 19 | } 20 | ``` 21 | Here is code information: 22 | #if($context.baseUrl.length > 0) 23 | // base URL route: 24 | #end 25 | // compare this request body relate info: ${context.requestStructure} 26 | // compare this response body relate info: ${context.responseStructure} 27 | Here is the user's code: 28 | ```${context.language} 29 | ${context.selectedText} 30 | ``` 31 | 32 | Please generate the JSON data. 33 | -------------------------------------------------------------------------------- /prompts/genius/en/code/test-gen.vm: -------------------------------------------------------------------------------- 1 | Write unit test for following ${context.language} code. 2 | ${context.chatContext} 3 | #if( $context.relatedClasses.length > 0 ) 4 | ${context.relatedClasses} 5 | #end 6 | #if( $context.currentClass.length > 0 ) 7 | Here is current class information: 8 | ${context.currentClass} 9 | #end 10 | // here is the user used libraries 11 | // ${context.imports} 12 | 13 | // Here is the source code to be tested: 14 | ```$context.language 15 | ${context.sourceCode} 16 | ``` 17 | 18 | ## if newFile 19 | #if( $context.isNewFile ) 20 | Start method test code with ${context.language} Markdown code block here: 21 | #else 22 | Start ${context.underTestClassName} test code with ${context.language} Markdown code block here: 23 | #end 24 | -------------------------------------------------------------------------------- /prompts/genius/en/hyde/code/evaluate.vm: -------------------------------------------------------------------------------- 1 | Your job is to answer a query about a codebase using the information above. 2 | 3 | You must use the following formatting rules at all times: 4 | - Provide only as much information and code as is necessary to answer the query and be concise 5 | - If you do not have enough information needed to answer the query, do not make up an answer 6 | - When referring to code, you must provide an example in a code block 7 | - Keep number of quoted lines of code to a minimum when possible 8 | - ${context.chatContext} 9 | - Basic markdown is allowed 10 | - If you have enough information, try your best to answer more details. 11 | - You MUST provide key process of your thinking, 12 | 13 | Code: 14 | 15 | ```${context.language} 16 | ${context.code} 17 | ``` 18 | 19 | Take a deep breath, and start to answer the question. 20 | 21 | User's Question:${context.question} 22 | -------------------------------------------------------------------------------- /prompts/genius/en/hyde/code/propose.vm: -------------------------------------------------------------------------------- 1 | Write a code snippet that could hypothetically be returned by a code search engine as the answer to the query: {query} 2 | 3 | - Write the snippets in a programming or markup language that is likely given the query 4 | - The snippet should be between 5 and 10 lines long 5 | - Surround the snippet in triple backticks 6 | 7 | **Examples** 8 | User: What's the Qdrant threshold? 9 | Response: 10 | ```rust 11 | SearchPoints { 12 | limit, 13 | vector: vectors.get(idx).unwrap().clone(), 14 | collection_name: COLLECTION_NAME.to_string(), 15 | offset: Some(offset), 16 | score_threshold: Some(0.3), 17 | with_payload: Some(WithPayloadSelector { 18 | selector_options: Some(with_payload_selector::SelectorOptions::Enable(true)), 19 | }), 20 | } 21 | ``` 22 | 23 | ```user``` 24 | User: ${context.question} 25 | Response: 26 | 27 | -------------------------------------------------------------------------------- /prompts/genius/en/hyde/keywords/evaluate.vm: -------------------------------------------------------------------------------- 1 | ```system``` 2 | Use the above code to answer the following question. You should not reference any files outside of what is shown, 3 | unless they are commonly known files, like a .gitignore or package.json. Reference the filenames whenever possible. 4 | If there isn't enough information to answer the question, suggest where the user might look to learn more. 5 | 6 | - ${context.chatContext} 7 | 8 | ```user``` 9 | User's Question: What is the output of the code? 10 | 11 | code: 12 | 13 | ```${context.language} 14 | ${context.code} 15 | ``` 16 | 17 | User's Question: ${context.question} 18 | -------------------------------------------------------------------------------- /prompts/genius/en/model/reranker/llm-reranker.vm: -------------------------------------------------------------------------------- 1 | You are an expert software developer responsible for helping detect whether the retrieved snippet of code is relevant to the query. For a given input, you need to output a single word: "Yes" or "No" indicating the retrieved snippet is relevant to the query. 2 | 3 | Query: Where is the FastAPI server? 4 | Snippet: 5 | ```/Users/andrew/Desktop/server/main.py 6 | from fastapi import FastAPI 7 | 8 | app = FastAPI() 9 | 10 | @app.get("/") 11 | def read_root(): 12 | return {{"Hello": "World"}} 13 | ``` 14 | Relevant: Yes 15 | 16 | Query: Where in the documentation does it talk about the UI? 17 | Snippet: 18 | ```/Users/andrew/Projects/bubble_sort/src/lib.ts 19 | function bubbleSort(arr: number[]): number[] { 20 | for (let i = 0; i < arr.length; i++) { 21 | for (let j = 0; j < arr.length - 1 - i; j++) { 22 | if (arr[j] > arr[j + 1]) { 23 | [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; 24 | } 25 | } 26 | } 27 | return arr; 28 | } 29 | ``` 30 | Relevant: No 31 | 32 | Query: ${context.query} 33 | Snippet: 34 | ```${context.documentId} 35 | ${context.document} 36 | ``` 37 | Relevant: 38 | -------------------------------------------------------------------------------- /prompts/genius/en/page/page-gen-clarify.vm: -------------------------------------------------------------------------------- 1 | You are a professional Frontend developer. 2 | According to the user's requirements, you should choose the best components for the user in List. 3 | 4 | - Framework: ${context.frameworks} 5 | - Language: ${context.language} 6 | - User component: ${context.componentNames}, ${context.pageNames} 7 | 8 | For example: 9 | 10 | - Question(requirements): Build a form for user to fill in their information. 11 | - You should anwser: [Input, Select, Radio, Checkbox, Button, Form] 12 | 13 | ---- 14 | 15 | Here are the User requirements: 16 | 17 | ```markdown 18 | ${context.requirement} 19 | ``` 20 | 21 | Please choose the best Components for the user, just return the components names in a list, no explain. 22 | -------------------------------------------------------------------------------- /prompts/genius/en/page/page-gen-design.vm: -------------------------------------------------------------------------------- 1 | You are a professional Frontend developer. 2 | According to the user's requirements, and Components info, write Component for the user. 3 | 4 | - User Components Infos: ${context.components} 5 | 6 | For example: 7 | 8 | - Question(requirements): Build a form for user to fill in their information. 9 | // componentName: Form, props: { fields: [{name: 'name', type: 'text'}, {name: 'age', type: 'number'}] } 10 | // componentName: Input, props: { name: 'name', type: 'text' } 11 | // componentName: Input, props: { name: 'age', type: 'number' } 12 | - Answer: 13 | ```react 14 |
15 | 16 | 17 |
18 | ``` 19 | 20 | ---- 21 | 22 | Here are the requirements: 23 | 24 | ```markdown 25 | ${context.requirement} 26 | ``` 27 | 28 | Please write your code with Markdown syntax, no explanation is needed: 29 | 30 | -------------------------------------------------------------------------------- /prompts/genius/en/practises/code-review.vm: -------------------------------------------------------------------------------- 1 | You are a seasoned software developer, and I'm seeking your expertise to review the following code: 2 | 3 | - Focus on critical algorithms, logical flow, and design decisions within the code. Discuss how these changes impact the core functionality and the overall structure of the code. 4 | - Identify and highlight any potential issues or risks introduced by these code changes. This will help reviewers pay special attention to areas that may require improvement or further analysis. 5 | - Emphasize the importance of compatibility and consistency with the existing codebase. Ensure that the code adheres to the established standards and practices for code uniformity and long-term maintainability. 6 | 7 | ${context.frameworkContext} 8 | 9 | #if($context.stories.isNotEmpty()) 10 | The following user stories are related to these changes: 11 | ${context.stories.joinToString("\n")} 12 | #end 13 | 14 | ${context.diffContext} 15 | 16 | As your Tech lead, I am only concerned with key code review issues. Please provide me with a critical summary. 17 | Submit your key insights under 5 sentences in here: 18 | -------------------------------------------------------------------------------- /prompts/genius/en/practises/gen-commit-msg.vm: -------------------------------------------------------------------------------- 1 | Given the below code differences (diffs), please generate a concise, clear, and straight-to-the-point commit message. 2 | 3 | - Make sure to prioritize the main action. 4 | - Avoid overly verbose descriptions or unnecessary details. 5 | - Start with a short sentence in imperative form, no more than 50 characters long. 6 | - Then leave an empty line and continue with a more detailed explanation, if necessary. 7 | 8 | Follow the Conventional Commits specification, examples: 9 | 10 | - fix(authentication): fix password regex pattern case 11 | - feat(storage): add support for S3 storage 12 | - test(java): fix test case for user controller 13 | - docs(architecture): add architecture diagram to home page 14 | 15 | #if( $context.historyExamples.length > 0 ) 16 | Here are the user's historical commit habits: 17 | $context.historyExamples 18 | #end 19 | 20 | Diff: 21 | 22 | ```diff 23 | ${context.diffContent} 24 | ``` 25 | -------------------------------------------------------------------------------- /prompts/genius/en/practises/refactoring.vm: -------------------------------------------------------------------------------- 1 | You should suggest appropriate refactorings for the code. Improve code readability, code quality, make the code more organized and understandable. 2 | Answer should contain refactoring description and ONE code snippet with resulting refactoring. 3 | Use well-known refactorings, such as one from this list: 4 | - Renaming 5 | - Change signature, declaration 6 | - Extract or Introduce variable, function, constant, parameter, type parameter 7 | - Extract class, interface, superclass 8 | - Inline class, function, variable, etc 9 | - Move field, function, statements, etc 10 | - Pull up constructor, field, method 11 | - Push down field, method. 12 | Do not generate more than one code snippet, try to incorporate all changes in one code snippet. 13 | Do not generate mock surrounding classes, methods. Do not mock missing dependencies. 14 | Provided code is incorporated into correct and compilable code, don't surround it with additional classes. 15 | Refactor the following code: 16 | -------------------------------------------------------------------------------- /prompts/genius/en/practises/rename.vm: -------------------------------------------------------------------------------- 1 | ${context.originName} is a badname. Please provide 1 better options name for follow code: 2 | ```${context.language} 3 | ${context.code} 4 | ``` 5 | 6 | just return the better name: -------------------------------------------------------------------------------- /prompts/genius/en/practises/shell-suggest.vm: -------------------------------------------------------------------------------- 1 | Return only the command to be executed as a raw string, no string delimiters 2 | wrapping it, no yapping, no markdown, no fenced code blocks, what you return 3 | will be passed to subprocess.check_output() directly. 4 | 5 | - Today is: ${context.today}, user system is: ${context.os}, 6 | - User current directory is: ${context.cwd}, user use is: ${context.shellPath}, according the tool to create the command. 7 | 8 | For example, if the user asks: undo last git commit 9 | 10 | You return only line command: git reset --soft HEAD~1 11 | 12 | User asks: ${context.question} 13 | -------------------------------------------------------------------------------- /prompts/genius/en/quick/quick-action.vm: -------------------------------------------------------------------------------- 1 | Generate a concise code snippet with no extra text, description, or comments. 2 | 3 | The code should achieve the following task: 4 | 5 | ${context.task} 6 | -------------------------------------------------------------------------------- /prompts/genius/en/sql/sql-gen-clarify.vm: -------------------------------------------------------------------------------- 1 | You are a professional Database Administrator. 2 | According to the user's requirements, you should choose the best Tables for the user in List. 3 | 4 | — User use database: ${context.databaseVersion} 5 | - User schema name: ${context.schemaName} 6 | - User tables: ${context.tableNames} 7 | 8 | For example: 9 | 10 | - Question(requirements): calculate the average trip length by subscriber type.// User tables: trips, users, subscriber_type 11 | - You should anwser: [trips, subscriber_type] 12 | 13 | ---- 14 | 15 | Here are the User requirements: 16 | 17 | ```markdown 18 | ${context.requirement} 19 | ``` 20 | 21 | Please choose the best Tables for the user, just return the table names in a list, no explain. 22 | -------------------------------------------------------------------------------- /prompts/genius/en/sql/sql-gen-design.vm: -------------------------------------------------------------------------------- 1 | You are a professional Database Administrator. 2 | According to the user's requirements, and Tables info, write SQL for the user. 3 | 4 | — User use database: ${context.databaseVersion} 5 | - User schema name: ${context.schemaName} 6 | - User tableInfos: ${context.tableInfos} 7 | 8 | For example: 9 | 10 | - Question(requirements): calculate the average trip length by subscriber type. 11 | // table `subscriber_type`: average_trip_length: int, subscriber_type: string 12 | - Answer: 13 | ```sql 14 | select average_trip_length from subscriber_type where subscriber_type = 'subscriber' 15 | ``` 16 | 17 | ---- 18 | 19 | Here are the requirements: 20 | 21 | ```markdown 22 | ${context.requirement} 23 | ``` 24 | 25 | Please write your SQL with Markdown syntax, no explanation is needed. : 26 | 27 | -------------------------------------------------------------------------------- /prompts/genius/en/sre/generate-dockerfile.vm: -------------------------------------------------------------------------------- 1 | Please write a Dockerfile with minimal steps. 2 | 3 | ${context.buildContext} 4 | - I need the building to be done in separate base image than running the build 5 | - I need the application port to be 3000 6 | 7 | Output only the Dockerfile content without any explanation. 8 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/cicd/generate-github-action.vm: -------------------------------------------------------------------------------- 1 | 创建 build.yml 文件,用于 GitHub Action 构建项目并运行测试。 2 | 3 | - ${context.buildContext} 4 | - OS: 最新版本的ubuntu 5 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/code/auto-doc.vm: -------------------------------------------------------------------------------- 1 | Write documentation for user's given ${context.language} code. 2 | #if($context.chatContext.length > 0 ) 3 | ${context.chatContext} 4 | #end 5 | #if($context.forbiddenRules.length > 0) 6 | ${context.forbiddenRules} 7 | #end 8 | - Start your documentation with ${context.startSymbol} here, and ends with `${context.endSymbol}`. 9 | Here is User's code: 10 | ```${context.language} 11 | ${context.code} 12 | ``` 13 | Please write documentation for this code inside the Markdown code block. 14 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/code/auto-method.vm: -------------------------------------------------------------------------------- 1 | Write documentation for user's given ${context.language} code. 2 | #if($context.chatContext.length > 0 ) 3 | ${context.chatContext} 4 | #end 5 | #if($context.forbiddenRules.length > 0) 6 | ${context.forbiddenRules} 7 | #end 8 | - Start your documentation with ${context.startSymbol} here, and ends with `${context.endSymbol}`. 9 | Here is User's code: 10 | ```${context.language} 11 | ${context.code} 12 | ``` 13 | 14 | Please write documentation for this code inside the Markdown code block. 15 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/code/code-complete.vm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unit-mesh/autodev-vscode/1ee121e9ff74d2ab1fbadfcbfe290ca07c791acc/prompts/genius/zh-cn/code/code-complete.vm -------------------------------------------------------------------------------- /prompts/genius/zh-cn/code/test-gen.vm: -------------------------------------------------------------------------------- 1 | Write unit test for following ${context.language} code. 2 | ${context.chatContext} 3 | #if( $context.relatedClasses.length > 0 ) 4 | ${context.relatedClasses} 5 | #end 6 | #if( $context.currentClass.length > 0 ) 7 | Here is current class information: 8 | ${context.currentClass} 9 | #end 10 | 11 | // here is the user used libraries 12 | // ${context.imports} 13 | 14 | // Here is the source code to be tested: 15 | ```$context.language 16 | ${context.sourceCode} 17 | ``` 18 | 19 | ## if newFile 20 | #if( $context.isNewFile ) 21 | Start method test code with ${context.language} Markdown code block here: 22 | #else 23 | Start ${context.underTestClassName} test code with Markdown ${context.language} code block here: 24 | #end 25 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/error/fix-error.vm: -------------------------------------------------------------------------------- 1 | 作为具有代码调试专业知识的有益助手,您的目标是通过分析控制台日志并提供一般解决方案来识别运行时问题的根源。在协助用户时,请遵循以下规则: 2 | 3 | 1. 始终友善和专业。 4 | 2. 利用您在代码调试方面的精通,通过查看控制台日志确定运行时问题的原因。 5 | 3. 在给定代码的情况下,提供修复导致运行时问题的错误的解决方案。 6 | 4. 确保您的解决方案不是临时的"临时性补丁",而是提供长期的解决方案。 7 | 5. 如果用户发送给您一个单文件程序,请在您的回复末尾以markdown格式附上修复后的代码。此代码将使用re.findall(r"{{3}}(\w*)\n([\S\s]+?)\n{{3}}",model_response)提取,因此严格遵循此格式。 8 | 6. 如果可以通过修改代码严格地修复问题,请这样做。例如,如果缺少库,则最好重新编写代码而不建议安装该库。 9 | 7. 始终遵循这些规则,以确保为用户提供最佳的帮助。 10 | 11 | 现在,考虑这个用户请求: 12 | 13 | "请帮助我理解问题所在,并尝试修复代码。这是控制台输出和程序文本: 14 | 15 | 控制台输出: 16 | %s 17 | 程序文本: 18 | %s 19 | 提供一个有益的回复,解决用户的问题,遵循规则,并为运行时问题提供解决方案。 20 | 21 | ``` 22 | ${context.errorText} 23 | ``` 24 | 25 | ``` 26 | ${context.soureCode} 27 | ``` 28 | 29 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/hyde/code/evaluate.vm: -------------------------------------------------------------------------------- 1 | Your job is to answer a query about a codebase using the information above. 2 | 3 | You must use the following formatting rules at all times: 4 | - Provide only as much information and code as is necessary to answer the query and be concise 5 | - If you do not have enough information needed to answer the query, do not make up an answer 6 | - When referring to code, you must provide an example in a code block 7 | - Keep number of quoted lines of code to a minimum when possible 8 | - ${context.chatContext} 9 | - Basic markdown is allowed 10 | - If you have enough information, try your best to answer more details. 11 | - You MUST provide key process of your thinking, 12 | 13 | Code: 14 | 15 | ```${context.language} 16 | ${context.code} 17 | ``` 18 | 19 | Take a deep breath, and start to answer the question. 20 | 21 | User's Question:${context.question} 22 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/hyde/code/propose.vm: -------------------------------------------------------------------------------- 1 | Write a code snippet that could hypothetically be returned by a code search engine as the answer to the query: {query} 2 | 3 | - Write the snippets in a programming or markup language that is likely given the query 4 | - The snippet should be between 5 and 10 lines long 5 | - Surround the snippet in triple backticks 6 | 7 | **Examples** 8 | User: What's the Qdrant threshold? 9 | Response: 10 | ```rust 11 | SearchPoints { 12 | limit, 13 | vector: vectors.get(idx).unwrap().clone(), 14 | collection_name: COLLECTION_NAME.to_string(), 15 | offset: Some(offset), 16 | score_threshold: Some(0.3), 17 | with_payload: Some(WithPayloadSelector { 18 | selector_options: Some(with_payload_selector::SelectorOptions::Enable(true)), 19 | }), 20 | } 21 | ``` 22 | 23 | ```user``` 24 | User: ${context.question} 25 | Response: 26 | 27 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/hyde/keywords/evaluate.vm: -------------------------------------------------------------------------------- 1 | ```system``` 2 | 使用上述代码回答以下问题。你不应该引用任何未展示的文件,除非它们是常见文件,如 .gitignore 或 package.json。请尽量引用文件名。 3 | - ${context.chatContext} 4 | 如果没有足够的信息来回答问题,请建议用户可以在哪里查找更多信息。 5 | 6 | 请使用中文回答问题。 7 | 8 | ```user``` 9 | 用户的问题: ${context.question} 10 | 11 | 相关代码: 12 | ```${context.language} 13 | ${context.code} 14 | ``` 15 | 16 | 请输出你的回答: 17 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/model/reranker/llm-reranker.vm: -------------------------------------------------------------------------------- 1 | You are an expert software developer responsible for helping detect whether the retrieved snippet of code is relevant to the query. For a given input, you need to output a single word: "Yes" or "No" indicating the retrieved snippet is relevant to the query. 2 | 3 | Query: Where is the FastAPI server? 4 | Snippet: 5 | ```/Users/andrew/Desktop/server/main.py 6 | from fastapi import FastAPI 7 | 8 | app = FastAPI() 9 | 10 | @app.get("/") 11 | def read_root(): 12 | return {{"Hello": "World"}} 13 | ``` 14 | Relevant: Yes 15 | 16 | Query: Where in the documentation does it talk about the UI? 17 | Snippet: 18 | ```/Users/andrew/Projects/bubble_sort/src/lib.ts 19 | function bubbleSort(arr: number[]): number[] { 20 | for (let i = 0; i < arr.length; i++) { 21 | for (let j = 0; j < arr.length - 1 - i; j++) { 22 | if (arr[j] > arr[j + 1]) { 23 | [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; 24 | } 25 | } 26 | } 27 | return arr; 28 | } 29 | ``` 30 | Relevant: No 31 | 32 | Query: ${context.query} 33 | Snippet: 34 | ```${context.documentId} 35 | ${context.document} 36 | ``` 37 | Relevant: 38 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/page/page-gen-clarify.vm: -------------------------------------------------------------------------------- 1 | 你是一位专业的前端开发者。根据用户的需求,在列表中为用户选择最佳组件。 2 | 3 | 框架:${context.frameworks} 4 | 语言:${context.language} 5 | 用户组件:${context.componentNames},${context.pageNames} 6 | 例如: 7 | 8 | 问题(需求):为用户构建一个填写个人信息的表单。 9 | 你应该回答:[Input, Select, Radio, Checkbox, Button, Form] 10 | 11 | ---- 12 | 13 | 以下是用户需求: 14 | 15 | ```markdown 16 | ${context.requirement} 17 | ``` 18 | 19 | 请为用户选择最佳组件,只返回组件名称列表,不解释。 20 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/page/page-gen-design.vm: -------------------------------------------------------------------------------- 1 | 你是一位专业的前端开发者。 2 | 根据用户的需求和组件信息,为用户编写组件。 3 | 4 | - 用户组件信息:${context.components} 5 | 6 | 例如: 7 | 8 | - 问题(需求):为用户构建一个填写个人信息的表单。 9 | // 组件名称: Form, props: { fields: [{name: 'name', type: 'text'}, {name: 'age', type: 'number'}] } 10 | // 组件名称: Input, props: { name: 'name', type: 'text' } 11 | // : Input, props: { name: 'age', type: 'number' } 12 | - 回答: 13 | ```react 14 |
15 | 16 | 17 |
18 | ``` 19 | 20 | ---- 21 | 22 | 以下是需求: 23 | 24 | ```markdown 25 | ${context.requirement} 26 | ``` 27 | 28 | 请使用 Markdown 语法编写您的代码,无需解释。 29 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/practises/code-review.vm: -------------------------------------------------------------------------------- 1 | 你是一位经验丰富的软件开发者,我寻求您的专业知识来审查以下代码: 2 | 3 | - 专注于代码中的关键算法、逻辑流程和设计决策。讨论这些变化如何影响核心功能和代码的整体结构。 4 | - 确定并突出显示这些代码变化可能引入的任何潜在问题或风险。这将帮助审阅人员特别关注可能需要改进或进一步分析的领域。 5 | - 强调与现有代码库的兼容性和一致性的重要性。确保代码符合已建立的标准和实践,以确保代码的统一性和长期可维护性。 6 | 7 | ${context.frameworkContext} 8 | 9 | #if($context.stories.isNotEmpty()) 10 | 以下用户故事与这些变化相关: 11 | ${context.stories.joinToString("\n")} 12 | #end 13 | 14 | ${context.diffContext} 15 | 16 | 作为您的技术负责人,我只关注关键的代码审查问题。请在此提供关键总结。 17 | 在此处以不超过 5 句话提交您的关键见解: -------------------------------------------------------------------------------- /prompts/genius/zh-cn/practises/gen-commit-msg.vm: -------------------------------------------------------------------------------- 1 | 为给定的变更(Diff)编写一个连贯但具有描述性的提交信息。 2 | 3 | - 确保包含修改了什么以及为什么。 4 | - 以不超过 50 个字符的祈使句形式开头。 5 | - 然后留下一个空行,如有必要,继续详细说明。 6 | - 说明应该少于 200 个字符。 7 | 8 | 遵循常规提交规范,例如: 9 | 10 | - fix(authentication): 修复密码正则表达式模式问题 11 | - feat(storage): 添加对S3存储的支持 12 | - test(java): 修复用户控制器的测试用例 13 | - docs(architecture): 在主页添加架构图 14 | 15 | #if( $context.historyExamples.length > 0 ) 16 | 以下是用户的历史提交习惯: 17 | $context.historyExamples 18 | #end 19 | 20 | #if( $context.originText.length > 0 ) 21 | 用户想表达的是: $context.originText 22 | #end 23 | 24 | Diff: 25 | 26 | ```diff 27 | ${context.diffContent} 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/practises/refactoring.vm: -------------------------------------------------------------------------------- 1 | 请你这段代码建议适当的重构。提高代码的可读性、质量,使代码更加有组织和易懂。答案应包含重构描述和一个代码片段,展示重构后的结果。 2 | 使用一些众所周知的重构技巧,比如以下列表中的一个: 3 | - 重命名 4 | - 修改签名、声明 5 | - 提取或引入变量、函数、常量、参数、类型参数 6 | - 提取类、接口、超类 7 | - 内联类、函数、变量等 8 | - 移动字段、函数、语句等 9 | - 上移构造函数、字段、方法 10 | - 下移字段、方法 11 | 12 | 请勿生成多个代码片段,尝试将所有更改都整合到一个代码片段中。 13 | 请勿生成包含虚构周围类、方法的代码。不要模拟缺失的依赖项。 14 | 提供的代码已经整合到正确且可编译的代码中,不要在其周围添加额外的类。 15 | 16 | 重构以下代码: 17 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/practises/rename.vm: -------------------------------------------------------------------------------- 1 | ${context.originName} is a badname. Please provide 1 better options name for follow code: 2 | ```${context.language} 3 | ${context.code} 4 | ``` 5 | 6 | just return the better name: -------------------------------------------------------------------------------- /prompts/genius/zh-cn/practises/shell-suggest.vm: -------------------------------------------------------------------------------- 1 | Return only the command to be executed as a raw string, no string delimiters 2 | wrapping it, no yapping, no markdown, no fenced code blocks, what you return 3 | will be passed to subprocess.check_output() directly. 4 | 5 | - Today is: ${context.today}, user system is: ${context.os}, 6 | - User current directory is: ${context.cwd}, user use is: ${context.shellPath}, according the tool to create the command. 7 | 8 | For example, if the user asks: undo last git commit 9 | 10 | You return only line command: git reset --soft HEAD~1 11 | 12 | User asks: ${context.question} 13 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/quick/quick-action.vm: -------------------------------------------------------------------------------- 1 | 生成一个简洁的代码片段,不包含额外的文本、描述或注释。该代码应实现以下任务: 2 | 3 | ${context.task} 4 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/sql/sql-gen-clarify.vm: -------------------------------------------------------------------------------- 1 | 你是一名专业的数据库管理员。根据用户的要求,在列表中为用户选择最佳的表。 2 | 3 | - 用户使用的数据库版本:${context.databaseVersion} 4 | - 用户 schema 名称:${context.schemaName} 5 | - 用户表信息:${context.tableNames} 6 | 7 | 例如: 8 | 9 | - 问题(要求):计算按订阅者类型划分的平均行程长度。// 用户表:trips、users、subscriber_type 10 | - 你应该回答:[trips, subscriber_type] 11 | 12 | ---- 13 | 14 | 以下是用户的需求: 15 | 16 | ```markdown 17 | ${context.requirement} 18 | ``` 19 | 20 | 请为用户选择最佳的表,只需返回表名的列表,无需解释。 -------------------------------------------------------------------------------- /prompts/genius/zh-cn/sql/sql-gen-design.vm: -------------------------------------------------------------------------------- 1 | 你是一名专业的数据库管理员。 2 | 根据用户的需求和表信息,为用户编写 SQL。 3 | 4 | - 用户使用的数据库版本:${context.databaseVersion} 5 | - 用户架构名称:${context.schemaName} 6 | - 用户表信息:${context.tableInfos} 7 | 8 | 例如: 9 | 10 | - 问题(需求):按订阅者类型计算平均行程长度。 11 | // table `subscriber_type`: average_trip_length: int, subscriber_type: string 12 | - 回答: 13 | ```sql 14 | select average_trip_length from subscriber_type where subscriber_type = 'subscriber' 15 | ``` 16 | 17 | ---- 18 | 19 | 以下是需求: 20 | 21 | ```markdown 22 | ${context.requirement} 23 | ``` 24 | 请使用 Markdown 语法编写您的 SQL,无需解释。 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /prompts/genius/zh-cn/sre/generate-dockerfile.vm: -------------------------------------------------------------------------------- 1 | 请编写一个最小步骤的 Dockerfile。 2 | 3 | ${context.buildContext} 4 | 5 | - 我需要在与运行构建不同的基础镜像中进行构建 6 | - 我需要应用程序端口为 3000 7 | 8 | 仅输出 Dockerfile 内容,不要附带任何解释。 -------------------------------------------------------------------------------- /prompts/team_terms.csv: -------------------------------------------------------------------------------- 1 | id, term, localized 2 | yyds, YYDS, 永远的神 3 | embedding, embedding, 向量化 4 | model, model, 模型 5 | team-prompts,Team Prompts, 团队 AI 提示词 6 | prompt-override, Prompt Override, AI 提示词覆盖 -------------------------------------------------------------------------------- /schemas/code-snippet-queries/tree-sitter-c-tags.scm: -------------------------------------------------------------------------------- 1 | (struct_specifier name: (type_identifier) @name.definition.class body:(_)) @definition.class 2 | 3 | (declaration type: (union_specifier name: (type_identifier) @name.definition.class)) @definition.class 4 | 5 | (function_declarator declarator: (identifier) @name.definition.function) @definition.function 6 | 7 | (type_definition declarator: (type_identifier) @name.definition.type) @definition.type 8 | 9 | (enum_specifier name: (type_identifier) @name.definition.type) @definition.type 10 | -------------------------------------------------------------------------------- /schemas/code-snippet-queries/tree-sitter-c_sharp-tags.scm: -------------------------------------------------------------------------------- 1 | (class_declaration 2 | name: (identifier) @name.definition.class 3 | ) @definition.class 4 | 5 | (class_declaration 6 | bases: (base_list (_) @name.reference.class) 7 | ) @reference.class 8 | 9 | (interface_declaration 10 | name: (identifier) @name.definition.interface 11 | ) @definition.interface 12 | 13 | (interface_declaration 14 | bases: (base_list (_) @name.reference.interface) 15 | ) @reference.interface 16 | 17 | (method_declaration 18 | name: (identifier) @name.definition.method 19 | ) @definition.method 20 | 21 | (object_creation_expression 22 | type: (identifier) @name.reference.class 23 | ) @reference.class 24 | 25 | (type_parameter_constraints_clause 26 | target: (identifier) @name.reference.class 27 | ) @reference.class 28 | 29 | (type_constraint 30 | type: (identifier) @name.reference.class 31 | ) @reference.class 32 | 33 | (variable_declaration 34 | type: (identifier) @name.reference.class 35 | ) @reference.class 36 | 37 | (invocation_expression 38 | function: 39 | (member_access_expression 40 | name: (identifier) @name.reference.send 41 | ) 42 | ) @reference.send 43 | 44 | (namespace_declaration 45 | name: (identifier) @name.definition.module 46 | ) @definition.module 47 | -------------------------------------------------------------------------------- /schemas/code-snippet-queries/tree-sitter-cpp-tags.scm: -------------------------------------------------------------------------------- 1 | (struct_specifier name: (type_identifier) @name.definition.class body:(_)) @definition.class 2 | 3 | (declaration type: (union_specifier name: (type_identifier) @name.definition.class)) @definition.class 4 | 5 | (function_declarator declarator: (identifier) @name.definition.function) @definition.function 6 | 7 | (function_declarator declarator: (field_identifier) @name.definition.function) @definition.function 8 | 9 | (function_declarator declarator: (qualified_identifier scope: (namespace_identifier) @scope name: (identifier) @name.definition.method)) @definition.method 10 | 11 | (type_definition declarator: (type_identifier) @name.definition.type) @definition.type 12 | 13 | (enum_specifier name: (type_identifier) @name.definition.type) @definition.type 14 | 15 | (class_specifier name: (type_identifier) @name.definition.class) @definition.class 16 | -------------------------------------------------------------------------------- /schemas/code-snippet-queries/tree-sitter-elisp-tags.scm: -------------------------------------------------------------------------------- 1 | ;; defun/defsubst 2 | (function_definition name: (symbol) @name.definition.function) @definition.function 3 | 4 | ;; Treat macros as function definitions for the sake of TAGS. 5 | (macro_definition name: (symbol) @name.definition.function) @definition.function 6 | 7 | ;; Match function calls 8 | (list (symbol) @name.reference.function) @reference.function 9 | -------------------------------------------------------------------------------- /schemas/code-snippet-queries/tree-sitter-elm-tags.scm: -------------------------------------------------------------------------------- 1 | (value_declaration (function_declaration_left (lower_case_identifier) @name.definition.function)) @definition.function 2 | 3 | (function_call_expr (value_expr (value_qid) @name.reference.function)) @reference.function 4 | (exposed_value (lower_case_identifier) @name.reference.function)) @reference.function 5 | (type_annotation ((lower_case_identifier) @name.reference.function) (colon)) @reference.function 6 | 7 | (type_declaration ((upper_case_identifier) @name.definition.type) ) @definition.type 8 | 9 | (type_ref (upper_case_qid (upper_case_identifier) @name.reference.type)) @reference.type 10 | (exposed_type (upper_case_identifier) @name.reference.type)) @reference.type 11 | 12 | (type_declaration (union_variant (upper_case_identifier) @name.definition.union)) @definition.union 13 | 14 | (value_expr (upper_case_qid (upper_case_identifier) @name.reference.union)) @reference.union 15 | 16 | 17 | (module_declaration 18 | (upper_case_qid (upper_case_identifier)) @name.definition.module 19 | ) @definition.module 20 | -------------------------------------------------------------------------------- /schemas/code-snippet-queries/tree-sitter-go-tags.scm: -------------------------------------------------------------------------------- 1 | ( 2 | (comment)* @doc 3 | . 4 | (function_declaration 5 | name: (identifier) @name.definition.function) @definition.function 6 | (#strip! @doc "^//\\s*") 7 | (#set-adjacent! @doc @definition.function) 8 | ) 9 | 10 | ( 11 | (comment)* @doc 12 | . 13 | (method_declaration 14 | name: (field_identifier) @name.definition.method) @definition.method 15 | (#strip! @doc "^//\\s*") 16 | (#set-adjacent! @doc @definition.method) 17 | ) 18 | 19 | (call_expression 20 | function: [ 21 | (identifier) @name.reference.call 22 | (parenthesized_expression (identifier) @name.reference.call) 23 | (selector_expression field: (field_identifier) @name.reference.call) 24 | (parenthesized_expression (selector_expression field: (field_identifier) @name.reference.call)) 25 | ]) @reference.call 26 | 27 | (type_spec 28 | name: (type_identifier) @name.definition.type) @definition.type 29 | 30 | (type_identifier) @name.reference.type @reference.type 31 | -------------------------------------------------------------------------------- /schemas/code-snippet-queries/tree-sitter-java-tags.scm: -------------------------------------------------------------------------------- 1 | (class_declaration 2 | name: (identifier) @name.definition.class) @definition.class 3 | 4 | (method_declaration 5 | name: (identifier) @name.definition.method) @definition.method 6 | 7 | (method_invocation 8 | name: (identifier) @name.reference.call 9 | arguments: (argument_list) @reference.call) 10 | 11 | (interface_declaration 12 | name: (identifier) @name.definition.interface) @definition.interface 13 | 14 | (type_list 15 | (type_identifier) @name.reference.implementation) @reference.implementation 16 | 17 | (object_creation_expression 18 | type: (type_identifier) @name.reference.class) @reference.class 19 | 20 | (superclass (type_identifier) @name.reference.class) @reference.class 21 | -------------------------------------------------------------------------------- /schemas/code-snippet-queries/tree-sitter-php-tags.scm: -------------------------------------------------------------------------------- 1 | (class_declaration 2 | name: (name) @name.definition.class) @definition.class 3 | 4 | (function_definition 5 | name: (name) @name.definition.function) @definition.function 6 | 7 | (method_declaration 8 | name: (name) @name.definition.function) @definition.function 9 | 10 | (object_creation_expression 11 | [ 12 | (qualified_name (name) @name.reference.class) 13 | (variable_name (name) @name.reference.class) 14 | ]) @reference.class 15 | 16 | (function_call_expression 17 | function: [ 18 | (qualified_name (name) @name.reference.call) 19 | (variable_name (name)) @name.reference.call 20 | ]) @reference.call 21 | 22 | (scoped_call_expression 23 | name: (name) @name.reference.call) @reference.call 24 | 25 | (member_call_expression 26 | name: (name) @name.reference.call) @reference.call 27 | -------------------------------------------------------------------------------- /schemas/code-snippet-queries/tree-sitter-python-tags.scm: -------------------------------------------------------------------------------- 1 | (class_definition 2 | name: (identifier) @name.definition.class) @definition.class 3 | 4 | (function_definition 5 | name: (identifier) @name.definition.function) @definition.function 6 | 7 | (call 8 | function: [ 9 | (identifier) @name.reference.call 10 | (attribute 11 | attribute: (identifier) @name.reference.call) 12 | ]) @reference.call 13 | -------------------------------------------------------------------------------- /schemas/code-snippet-queries/tree-sitter-ql-tags.scm: -------------------------------------------------------------------------------- 1 | (classlessPredicate 2 | name: (predicateName) @name.definition.function) @definition.function 3 | 4 | (memberPredicate 5 | name: (predicateName) @name.definition.method) @definition.method 6 | 7 | (aritylessPredicateExpr 8 | name: (literalId) @name.reference.call) @reference.call 9 | 10 | (module 11 | name: (moduleName) @name.definition.module) @definition.module 12 | 13 | (dataclass 14 | name: (className) @name.definition.class) @definition.class 15 | 16 | (datatype 17 | name: (className) @name.definition.class) @definition.class 18 | 19 | (datatypeBranch 20 | name: (className) @name.definition.class) @definition.class 21 | 22 | (qualifiedRhs 23 | name: (predicateName) @name.reference.call) @reference.call 24 | 25 | (typeExpr 26 | name: (className) @name.reference.type) @reference.type 27 | -------------------------------------------------------------------------------- /schemas/code-snippet-queries/tree-sitter-typescript-tags.scm: -------------------------------------------------------------------------------- 1 | (function_signature 2 | name: (identifier) @name.definition.function) @definition.function 3 | 4 | (method_signature 5 | name: (property_identifier) @name.definition.method) @definition.method 6 | 7 | (abstract_method_signature 8 | name: (property_identifier) @name.definition.method) @definition.method 9 | 10 | (abstract_class_declaration 11 | name: (type_identifier) @name.definition.class) @definition.class 12 | 13 | (module 14 | name: (identifier) @name.definition.module) @definition.module 15 | 16 | (interface_declaration 17 | name: (type_identifier) @name.definition.interface) @definition.interface 18 | 19 | (type_annotation 20 | (type_identifier) @name.reference.type) @reference.type 21 | 22 | (new_expression 23 | constructor: (identifier) @name.reference.class) @reference.class 24 | -------------------------------------------------------------------------------- /src/ProviderLanguageProfile.config.ts: -------------------------------------------------------------------------------- 1 | import { Container } from 'inversify'; 2 | 3 | import { GolangProfile } from './code-context/go/GolangProfile'; 4 | import { JavaProfile } from './code-context/java/JavaProfile'; 5 | import { PythonProfile } from './code-context/python/PythonProfile'; 6 | import { RustProfile } from './code-context/rust/RustProfile'; 7 | import { TypeScriptProfile } from './code-context/typescript/TypeScriptProfile'; 8 | import { ILanguageProfile } from './ProviderTypes'; 9 | import { CsharpProfile } from './code-context/csharp/CsharpProfile'; 10 | import { KotlinProfile } from './code-context/kotlin/KotlinProfile'; 11 | 12 | const languageContainer = new Container(); 13 | 14 | languageContainer.bind(ILanguageProfile).to(JavaProfile); 15 | languageContainer.bind(ILanguageProfile).to(TypeScriptProfile); 16 | languageContainer.bind(ILanguageProfile).to(GolangProfile); 17 | languageContainer.bind(ILanguageProfile).to(PythonProfile); 18 | languageContainer.bind(ILanguageProfile).to(CsharpProfile); 19 | languageContainer.bind(ILanguageProfile).to(RustProfile); 20 | languageContainer.bind(ILanguageProfile).to(KotlinProfile); 21 | 22 | export { languageContainer }; 23 | -------------------------------------------------------------------------------- /src/action/_base/ActionCreator.ts: -------------------------------------------------------------------------------- 1 | import vscode from 'vscode'; 2 | 3 | import { ActionCreatorContext } from './ActionCreatorContext'; 4 | 5 | export interface ActionCreator { 6 | isApplicable(creatorContext: ActionCreatorContext): boolean; 7 | 8 | buildActions(context: ActionCreatorContext): Promise; 9 | } 10 | -------------------------------------------------------------------------------- /src/action/_base/ActionCreatorContext.ts: -------------------------------------------------------------------------------- 1 | import vscode from 'vscode'; 2 | 3 | import { NamedElement } from '../../editor/ast/NamedElement'; 4 | 5 | export interface ActionCreatorContext { 6 | namedElementBlocks: NamedElement[]; 7 | range: vscode.Range | vscode.Selection; 8 | document: vscode.TextDocument; 9 | lang: string; 10 | } 11 | -------------------------------------------------------------------------------- /src/action/_base/ActionExecutor.ts: -------------------------------------------------------------------------------- 1 | import { TextDocument } from 'vscode'; 2 | import { ActionType } from '../../prompt-manage/ActionType'; 3 | 4 | export interface ActionExecutor { 5 | type: ActionType; 6 | 7 | execute(document: TextDocument): Promise; 8 | } 9 | -------------------------------------------------------------------------------- /src/action/autoMethod/AutoMethodTemplateContext.ts: -------------------------------------------------------------------------------- 1 | import { TemplateContext } from '../../prompt-manage/template/TemplateContext'; 2 | 3 | export interface AutoMethodTemplateContext extends TemplateContext { 4 | startSymbol: string; 5 | endSymbol: string; 6 | code: string; 7 | forbiddenRules: string[]; 8 | originalMethodCodes: string[]; 9 | customFrameworkCodeFileContext?:string; 10 | } 11 | -------------------------------------------------------------------------------- /src/action/autodoc/AutoDocTemplateContext.ts: -------------------------------------------------------------------------------- 1 | import { TemplateContext } from '../../prompt-manage/template/TemplateContext'; 2 | 3 | export interface AutoDocTemplateContext extends TemplateContext { 4 | startSymbol: string; 5 | endSymbol: string; 6 | code: string; 7 | forbiddenRules: string[]; 8 | originalComments: string[]; 9 | } 10 | -------------------------------------------------------------------------------- /src/action/custom-action/README.md: -------------------------------------------------------------------------------- 1 | see in [prompt-manage/custom-action](src/prompt-manage/custom-action) 2 | -------------------------------------------------------------------------------- /src/action/refactor/refactor-this/README.md: -------------------------------------------------------------------------------- 1 | # Refactor this 2 | 3 | TODO load error warning from code smell. 4 | -------------------------------------------------------------------------------- /src/action/setting/SystemActionType.ts: -------------------------------------------------------------------------------- 1 | export enum SystemActionType { 2 | Indexing = 'Indexing codebase', 3 | SemanticSearchKeyword = 'Natural language search (Hyde Keyword strategy)', 4 | SemanticSearchCode = 'Natural language search (Hyde Code strategy)', 5 | SimilarCodeSearch = 'Search for similar code (Recently + TF-IDF)', 6 | OpenSettings = 'Open settings', 7 | } 8 | 9 | export type SystemActionHandler = (type: SystemActionType) => void; 10 | -------------------------------------------------------------------------------- /src/action/test-data/GenApiDataExecutor.ts: -------------------------------------------------------------------------------- 1 | import vscode from 'vscode'; 2 | 3 | import { NamedElement } from '../../editor/ast/NamedElement'; 4 | import { ActionType } from '../../prompt-manage/ActionType'; 5 | import { TemplateContext } from '../../prompt-manage/template/TemplateContext'; 6 | import { ActionExecutor } from '../_base/ActionExecutor'; 7 | 8 | export interface TestDataTemplateContext extends TemplateContext { 9 | baseUrl?: string; 10 | requestStructure: string; 11 | responseStructure: string; 12 | selectedText: string; 13 | } 14 | 15 | export class GenApiDataActionExecutor implements ActionExecutor { 16 | type: ActionType = ActionType.GenApiData; 17 | 18 | private document: vscode.TextDocument; 19 | private range: NamedElement; 20 | private edit: vscode.WorkspaceEdit; 21 | private language: string; 22 | 23 | constructor(document: vscode.TextDocument, range: NamedElement, edit: vscode.WorkspaceEdit) { 24 | this.document = document; 25 | this.range = range; 26 | this.edit = edit; 27 | this.language = document.languageId; 28 | } 29 | 30 | async execute() { 31 | // getTreePathAtCursor() 32 | const context: TestDataTemplateContext = { 33 | language: this.language, 34 | baseUrl: '', 35 | requestStructure: '', 36 | responseStructure: '', 37 | selectedText: '', 38 | }; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/agent/builtin/autopage/ReactAutoPage.ts: -------------------------------------------------------------------------------- 1 | import { AutoDevExtension } from '../../../AutoDevExtension'; 2 | import { AutoPage } from './AutoPage'; 3 | import { UserProjectComponent } from './UserProjectComponent'; 4 | 5 | export class ReactAutoPage implements AutoPage { 6 | userTask: string; 7 | extension: AutoDevExtension; 8 | 9 | constructor(userTask: string, extension: AutoDevExtension) { 10 | this.userTask = userTask; 11 | this.extension = extension; 12 | } 13 | 14 | clarify(): string { 15 | return ''; 16 | } 17 | 18 | design(context: any): string[] { 19 | return []; 20 | } 21 | 22 | execute(context: any): string { 23 | return ''; 24 | } 25 | 26 | fix(errors: string): string { 27 | return ''; 28 | } 29 | 30 | getComponents(): UserProjectComponent[] { 31 | return []; 32 | } 33 | 34 | getDesignSystemComponents(): UserProjectComponent[] { 35 | return []; 36 | } 37 | 38 | getPages(): UserProjectComponent[] { 39 | return []; 40 | } 41 | 42 | getRoutes(): Map { 43 | return new Map(); 44 | } 45 | 46 | sampleRemoteCall(): string { 47 | return ''; 48 | } 49 | 50 | sampleStateManagement(): string | null { 51 | return null; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/agent/builtin/autopage/UserProjectComponent.ts: -------------------------------------------------------------------------------- 1 | export class UserProjectComponent { 2 | name: string; 3 | path: string; 4 | signature?: string; 5 | props?: string[]; 6 | 7 | constructor(name: string, path: string, signature: string = '', props: string[] = []) { 8 | this.name = name; 9 | this.path = path; 10 | this.signature = signature; 11 | this.props = props; 12 | } 13 | 14 | format(): string { 15 | let based = `component name: ${this.name}\ncomponent path: ${this.path}\ninput signature: ${this.signature}`; 16 | if (this.props) { 17 | based += `component props: ${this.props.join(', ')}`; 18 | } 19 | 20 | return based; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/agent/custom/ConnectorConfig.ts: -------------------------------------------------------------------------------- 1 | export class ConnectorConfig { 2 | /** 3 | * will be Json Config 4 | */ 5 | requestFormat: string; 6 | /** 7 | * will be JsonPath 8 | */ 9 | responseFormat: string; 10 | 11 | constructor(requestFormat: string = '', responseFormat: string = '') { 12 | this.requestFormat = requestFormat; 13 | this.responseFormat = responseFormat; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/agent/custom/CustomAgentAuth.ts: -------------------------------------------------------------------------------- 1 | export class CustomAgentAuth { 2 | type: AuthType; 3 | token: string; 4 | 5 | constructor(type: AuthType = AuthType.Bearer, token: string = '') { 6 | this.type = type; 7 | this.token = token; 8 | } 9 | } 10 | 11 | export enum AuthType { 12 | Bearer = 'Bearer', 13 | } 14 | -------------------------------------------------------------------------------- /src/agent/custom/CustomAgentResponseAction.ts: -------------------------------------------------------------------------------- 1 | export enum CustomAgentResponseAction { 2 | Direct = 'Direct', 3 | Stream = 'Stream', 4 | TextChunk = 'TextChunk', 5 | Flow = 'Flow', 6 | WebView = 'WebView', 7 | DevIns = 'DevIns', 8 | } 9 | -------------------------------------------------------------------------------- /src/agent/custom/CustomAgentState.ts: -------------------------------------------------------------------------------- 1 | export enum CustomAgentState { 2 | START = 'START', 3 | HANDLING = 'HANDLING', 4 | FINISHED = 'FINISHED', 5 | } 6 | -------------------------------------------------------------------------------- /src/agent/custom/CustomFlowTransition.ts: -------------------------------------------------------------------------------- 1 | export class CustomFlowTransition { 2 | /** 3 | * will be JsonPath 4 | */ 5 | source: string; 6 | /** 7 | * will be JsonPath too 8 | */ 9 | target: string; 10 | 11 | constructor(source: string, target: string) { 12 | this.source = source; 13 | this.target = target; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/base/common/configuration/context.ts: -------------------------------------------------------------------------------- 1 | import { type interfaces } from 'inversify'; 2 | import * as vscode from 'vscode'; 3 | 4 | export type IExtensionContext = vscode.ExtensionContext; 5 | 6 | export const IExtensionContext: interfaces.ServiceIdentifier = Symbol('ExtensionContext'); 7 | 8 | export const IExtensionUri: interfaces.ServiceIdentifier = Symbol('ExtensionUri'); 9 | 10 | export type IExtensionUri = vscode.Uri; 11 | -------------------------------------------------------------------------------- /src/base/common/defer.ts: -------------------------------------------------------------------------------- 1 | interface Deferred { 2 | abort: () => void; 3 | resolve: (value: T) => void; 4 | reject: (reason?: unknown) => void; 5 | promise: Promise; 6 | } 7 | 8 | export function defer(signal?: AbortSignal): Deferred { 9 | const ac = new AbortController(); 10 | const dtd = {} as Deferred; 11 | 12 | dtd.promise = new Promise((resolve, reject) => { 13 | dtd.resolve = resolve; 14 | dtd.reject = reject; 15 | }); 16 | 17 | function onDidAbort() { 18 | dtd.reject(new Error('user aborted')); 19 | } 20 | 21 | ac.signal.addEventListener('abort', onDidAbort); 22 | 23 | if (signal) { 24 | signal.addEventListener('abort', onDidAbort); 25 | } 26 | 27 | dtd.abort = function () { 28 | ac.abort(); 29 | }; 30 | 31 | return dtd; 32 | } -------------------------------------------------------------------------------- /src/base/common/files/files.ts: -------------------------------------------------------------------------------- 1 | import { type TextDocument } from 'vscode'; 2 | 3 | export function isFileTooLarge(doc: TextDocument) { 4 | if (doc.lineCount > 6000) { 5 | return true; 6 | } 7 | 8 | return isLargerThan500kb(doc.getText()); 9 | } 10 | 11 | export function isLargerThan500kb(content: string) { 12 | return content.length > 500000; 13 | } 14 | -------------------------------------------------------------------------------- /src/base/common/fs.ts: -------------------------------------------------------------------------------- 1 | import { inject, injectable } from 'inversify'; 2 | import { Uri, workspace } from 'vscode'; 3 | 4 | import { IExtensionUri } from './configuration/context'; 5 | 6 | @injectable() 7 | export class WorkspaceFileSystem { 8 | constructor( 9 | @inject(IExtensionUri) 10 | private extensionUri: Uri, 11 | ) {} 12 | 13 | readFile(path: string | Uri) { 14 | return workspace.fs.readFile(this.filePathToURI(path)) as Promise; 15 | } 16 | 17 | stat(path: string | Uri) { 18 | return workspace.fs.stat(this.filePathToURI(path)); 19 | } 20 | 21 | filePathToURI(path: string | Uri) { 22 | if (typeof path === 'string') { 23 | return this.joinPath(path); 24 | } 25 | 26 | return path; 27 | } 28 | 29 | joinPath(...pathSegments: string[]) { 30 | return Uri.joinPath(this.extensionUri, ...pathSegments); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/base/common/git.ts: -------------------------------------------------------------------------------- 1 | import { extensions, Uri } from 'vscode'; 2 | 3 | import { GitExtension } from '../../types/git'; 4 | 5 | export function getGitExtensionAPI() { 6 | // See https://github.com/microsoft/vscode/blob/main/extensions/git/README.md 7 | const gitExtension = extensions.getExtension('vscode.git')?.exports; 8 | 9 | if (!gitExtension) { 10 | return; 11 | } 12 | 13 | const git = gitExtension.getAPI(1); 14 | 15 | if (0 === git.repositories.length) { 16 | return; 17 | } 18 | 19 | return git; 20 | } 21 | 22 | export function getRepository(uri: Uri) { 23 | const api = getGitExtensionAPI(); 24 | return api?.getRepository(uri); 25 | } 26 | -------------------------------------------------------------------------------- /src/base/common/languages/ParserUtil.ts: -------------------------------------------------------------------------------- 1 | import Parser from 'web-tree-sitter'; 2 | 3 | export async function getTreePathAtCursor( 4 | ast: Parser.Tree, 5 | cursorIndex: number, 6 | ): Promise { 7 | const path = [ast.rootNode]; 8 | while (path[path.length - 1].childCount > 0) { 9 | let foundChild = false; 10 | for (let child of path[path.length - 1].children) { 11 | if (child.startIndex <= cursorIndex && child.endIndex >= cursorIndex) { 12 | path.push(child); 13 | foundChild = true; 14 | break; 15 | } 16 | } 17 | 18 | if (!foundChild) { 19 | break; 20 | } 21 | } 22 | 23 | return path; 24 | } 25 | -------------------------------------------------------------------------------- /src/base/common/languages/docstring.ts: -------------------------------------------------------------------------------- 1 | import { type LanguageIdentifier } from './languages'; 2 | 3 | export const LANGUAGE_LINE_COMMENT_MAP: Partial> = { 4 | c: '//', 5 | cpp: '//', 6 | csharp: '//', 7 | go: '//', 8 | java: '//', 9 | python: '#', 10 | rust: '//', 11 | javascript: '//', 12 | typescript: '//', 13 | typescriptreact: '//', 14 | }; 15 | 16 | export const LANGUAGE_BLOCK_COMMENT_MAP: Partial> = { 17 | c: { start: '/*', end: '*/' }, 18 | cpp: { start: '/*', end: '*/' }, 19 | csharp: { start: '/*', end: '*/' }, 20 | go: { start: '/*', end: '*/' }, 21 | java: { start: '/*', end: '*/' }, 22 | python: { start: '"""', end: '"""' }, 23 | rust: { start: '/*', end: '*/' }, 24 | javascript: { start: '/*', end: '*/' }, 25 | typescript: { start: '/*', end: '*/' }, 26 | typescriptreact: { start: '/*', end: '*/' }, 27 | }; 28 | 29 | export const LANGUAGE_COMMENT_RULE: Partial> = { 30 | java: [`use @param tag`, `use @return tag`, `do not return example code`, `do not use @author and @version tags`], 31 | }; 32 | -------------------------------------------------------------------------------- /src/base/common/lifecycle.ts: -------------------------------------------------------------------------------- 1 | export interface IDisposable { 2 | dispose(): void; 3 | } 4 | 5 | /** 6 | * Check if `thing` is {@link IDisposable disposable}. 7 | */ 8 | export function isDisposable(thing: E): thing is E & IDisposable { 9 | return ( 10 | typeof thing === 'object' && 11 | thing !== null && 12 | typeof ((thing)).dispose === 'function' && 13 | ((thing)).dispose.length === 0 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/base/common/log/log.ts: -------------------------------------------------------------------------------- 1 | import { l10n, window } from 'vscode'; 2 | 3 | export const logger = window.createOutputChannel(l10n.t('AutoDev'), { 4 | log: true, 5 | }); 6 | 7 | export function log(message: string, ...args: unknown[]) { 8 | if (process.env.NODE_ENV === 'development') { 9 | return logger.info(message, ...args); 10 | } 11 | 12 | return logger.debug(message, ...args); 13 | } 14 | 15 | export function debugLog(name: string) { 16 | return (messsage: string, ...args: unknown[]) => { 17 | logger.debug('(%s): %s', name, messsage, ...args); 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /src/base/common/markdown/MarkdownCodeBlock.ts: -------------------------------------------------------------------------------- 1 | export class MarkdownCodeBlock { 2 | language: string; 3 | startLine: number; 4 | endLine: number; 5 | code: string; 6 | 7 | constructor(language: string, startLine: number, endLine: number, code: string) { 8 | this.language = language; 9 | this.startLine = startLine; 10 | this.endLine = endLine; 11 | this.code = code; 12 | } 13 | 14 | static from(markdown: string): MarkdownCodeBlock[] { 15 | const regex = /```(\w+)?\s([\s\S]*?)```/gm; 16 | const blocks: MarkdownCodeBlock[] = []; 17 | let match; 18 | 19 | while ((match = regex.exec(markdown)) !== null) { 20 | const startLine = markdown.substring(0, match.index).split('\n').length; 21 | const endLine = startLine + match[0].split('\n').length - 1; 22 | blocks.push(new MarkdownCodeBlock(match[1] || 'plaintext', startLine, endLine, match[2])); 23 | } 24 | 25 | return blocks; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/base/common/markdown/MarkdownTextProcessor.ts: -------------------------------------------------------------------------------- 1 | export class MarkdownTextProcessor { 2 | static buildDocFromSuggestion(suggestDoc: string, commentStart: string, commentEnd: string): string { 3 | const startIndex = suggestDoc.indexOf(commentStart); 4 | if (startIndex < 0) { 5 | return ''; 6 | } 7 | 8 | const docComment = suggestDoc.substring(startIndex); 9 | const endIndex = docComment.indexOf(commentEnd, commentStart.length); 10 | if (endIndex < 0) { 11 | return docComment + commentEnd; 12 | } 13 | 14 | const substring = docComment.substring(0, endIndex + commentEnd.length); 15 | return substring; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/base/common/messages/messages.ts: -------------------------------------------------------------------------------- 1 | import { l10n, window } from 'vscode'; 2 | 3 | import { logger } from '../log/log'; 4 | 5 | const ERROR_ACTION_LABEL = l10n.t('Show Logs'); 6 | 7 | export function showErrorMessage(message: string) { 8 | window.showErrorMessage(message, ERROR_ACTION_LABEL).then(selection => { 9 | if (selection === ERROR_ACTION_LABEL) { 10 | logger.show(false); 11 | } 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /src/base/common/webview/webview.ts: -------------------------------------------------------------------------------- 1 | import { Uri, type Webview } from 'vscode'; 2 | 3 | export function getNonce() { 4 | let text = ''; 5 | const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; 6 | for (let i = 0; i < 32; i++) { 7 | text += possible.charAt(Math.floor(Math.random() * possible.length)); 8 | } 9 | return text; 10 | } 11 | 12 | export function getWebviewContent(webview: Webview, scriptsUri: Uri, stylesUri: Uri): string { 13 | const nonce = getNonce(); 14 | // 15 | 16 | return ` 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | `; 28 | } 29 | -------------------------------------------------------------------------------- /src/base/common/withCancellation.ts: -------------------------------------------------------------------------------- 1 | import { CancellationToken } from 'vscode'; 2 | 3 | export function withCancellation(promise: Promise, cancellationToken: CancellationToken, result: T): Promise { 4 | return new Promise((resolve, reject) => { 5 | const cancellationListener = cancellationToken.onCancellationRequested(() => { 6 | cancellationListener.dispose(); 7 | resolve(result); 8 | }); 9 | promise.then(resolve, reject).finally(() => cancellationListener.dispose()); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /src/base/node/glob.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Given glob pattern, returns first non-wildcard path, rest of glob, and whether there was a leading wildcard 3 | */ 4 | export function splitGlob(glob: string): [string | undefined, string, boolean] { 5 | const segs = glob.split('/'); 6 | 7 | let wildcards = 0; 8 | 9 | while (segs[0] === '**') { 10 | segs.shift(); 11 | wildcards++; 12 | } 13 | 14 | return [segs.shift(), segs.join('/'), wildcards > 0]; 15 | } 16 | -------------------------------------------------------------------------------- /src/base/node/timeout.ts: -------------------------------------------------------------------------------- 1 | export const TIMEOUT_ERROR = Symbol('timeout'); 2 | 3 | export async function timeout(thenable: Promise, ms?: number | undefined): Promise { 4 | let timer: NodeJS.Timeout | null = null; 5 | 6 | const timeout = new Promise((_, reject) => { 7 | timer = setTimeout(reject, ms, TIMEOUT_ERROR); 8 | }); 9 | 10 | return Promise.race([thenable, timeout]).finally(() => { 11 | timer && clearTimeout(timer); 12 | }); 13 | } 14 | 15 | export async function timeoutSafe(thenable: Promise): Promise; 16 | 17 | export async function timeoutSafe(thenable: Promise, ms: number | undefined, fallback: T): Promise; 18 | 19 | export async function timeoutSafe( 20 | thenable: Promise, 21 | ms?: number | undefined, 22 | fallback?: T, 23 | ): Promise { 24 | return timeout(thenable, ms).catch(error => { 25 | if (error === TIMEOUT_ERROR) return fallback; 26 | throw error; 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /src/code-context/CodeCorrectorProviderManage.ts: -------------------------------------------------------------------------------- 1 | export class CodeCorrectorProviderManage { 2 | private static instance: CodeCorrectorProviderManage; 3 | 4 | static getInstance(): CodeCorrectorProviderManage { 5 | if (!CodeCorrectorProviderManage.instance) { 6 | CodeCorrectorProviderManage.instance = new CodeCorrectorProviderManage(); 7 | } 8 | return CodeCorrectorProviderManage.instance; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/code-context/StructurerProviderManager.ts: -------------------------------------------------------------------------------- 1 | 2 | import { LanguageIdentifier } from 'base/common/languages/languages'; 3 | import { providerContainer } from '../ProviderContainer.config'; 4 | import { StructurerProvider } from './_base/StructurerProvider'; 5 | import { IStructurerProvider } from 'src/ProviderTypes'; 6 | 7 | export class StructurerProviderManager { 8 | private static instance: StructurerProviderManager; 9 | 10 | private constructor() {} 11 | 12 | static getInstance(): StructurerProviderManager { 13 | if (!StructurerProviderManager.instance) { 14 | StructurerProviderManager.instance = new StructurerProviderManager(); 15 | } 16 | return StructurerProviderManager.instance; 17 | } 18 | 19 | getStructurer(lang: LanguageIdentifier): StructurerProvider | undefined { 20 | let testProviders = providerContainer.getAll(IStructurerProvider); 21 | let provider = testProviders.find(provider => { 22 | return provider.isApplicable(lang); 23 | }); 24 | 25 | if (!provider) { 26 | return undefined; 27 | } 28 | 29 | return provider; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/code-context/TestGenProviderManager.ts: -------------------------------------------------------------------------------- 1 | import { LanguageIdentifier } from 'base/common/languages/languages'; 2 | import { ILanguageServiceProvider } from 'base/common/languages/languageService'; 3 | 4 | import { providerContainer } from '../ProviderContainer.config'; 5 | import { ITestGenProvider } from '../ProviderTypes'; 6 | 7 | export class TestGenProviderManager { 8 | constructor(private langService: ILanguageServiceProvider) {} 9 | 10 | async provide(lang: LanguageIdentifier) { 11 | let testProviders = providerContainer.getAll(ITestGenProvider); 12 | let provider = testProviders.find(provider => { 13 | return provider.isApplicable(lang); 14 | }); 15 | 16 | if (!provider) { 17 | return undefined; 18 | } 19 | 20 | await provider.setupLanguage(this.langService); 21 | 22 | return provider; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/code-context/_base/CodeCorrector.ts: -------------------------------------------------------------------------------- 1 | import vscode from 'vscode'; 2 | 3 | export interface CorrectorContext { 4 | document: vscode.TextDocument; 5 | sourcecode: string; 6 | packageName: string; 7 | targetClassName: string; 8 | } 9 | 10 | export interface CodeCorrector { 11 | /** 12 | * Corrects the generate AI code. 13 | * @param code The code to correct. 14 | * @returns The corrected code. 15 | */ 16 | correct(code: string): Promise; 17 | } 18 | -------------------------------------------------------------------------------- /src/code-context/_base/test/AutoTestTemplateContext.ts: -------------------------------------------------------------------------------- 1 | import { TemplateContext } from '../../../prompt-manage/template/TemplateContext'; 2 | import { ToolchainContextItem } from '../../../toolchain-context/ToolchainContextProvider'; 3 | 4 | export interface AutoTestTemplateContext extends TemplateContext { 5 | filename: string; 6 | isNewFile?: boolean; 7 | relatedClasses: string; 8 | /// means the class which you want to test 9 | currentClass?: string; 10 | underTestClassName: string; 11 | /// the generated test class name 12 | targetTestClassName?: string; 13 | targetPath?: string; 14 | imports?: string[]; 15 | sourceCode?: string; 16 | extraItems?: ToolchainContextItem[]; 17 | } 18 | -------------------------------------------------------------------------------- /src/code-context/_indexing/CodeContextProvider.ts: -------------------------------------------------------------------------------- 1 | // todo 2 | export class CodeContextProvider {} 3 | -------------------------------------------------------------------------------- /src/code-context/ast/TreeSitterWrapper.ts: -------------------------------------------------------------------------------- 1 | import vscode from 'vscode'; 2 | 3 | import { ILanguageServiceProvider } from 'base/common/languages/languageService'; 4 | 5 | import { NamedElementBuilder } from '../../editor/ast/NamedElementBuilder'; 6 | import { TreeSitterFileManager } from '../../editor/cache/TreeSitterFileManager'; 7 | import { TreeSitterFile } from './TreeSitterFile'; 8 | 9 | /** 10 | * For fix generate code 11 | */ 12 | export async function textToTreeSitterFile(src: string, langId: string, languageService: ILanguageServiceProvider 13 | 14 | ) { 15 | return TreeSitterFile.create(src, langId, languageService); 16 | } 17 | 18 | // TODO move to AutoDevExtension? 19 | export async function createNamedElement( 20 | treeSitterFileManager: TreeSitterFileManager, 21 | document: vscode.TextDocument, 22 | ): Promise { 23 | const file = await treeSitterFileManager.create(document); 24 | return new NamedElementBuilder(file); 25 | } 26 | 27 | // TODO move to AutoDevExtension? 28 | export async function createTreeSitterFile( 29 | treeSitterFileManager: TreeSitterFileManager, 30 | document: vscode.TextDocument, 31 | ): Promise { 32 | return treeSitterFileManager.create(document); 33 | } 34 | -------------------------------------------------------------------------------- /src/code-search/chunk/BasicChunker.ts: -------------------------------------------------------------------------------- 1 | import { countTokens } from '../token/TokenCounter'; 2 | import { ChunkWithoutID } from './_base/Chunk'; 3 | 4 | export function* basicChunker(contents: string, maxChunkSize: number, language: string): Generator { 5 | let chunkContent = ''; 6 | let chunkTokens = 0; 7 | let startLine = 0; 8 | let currLine = 0; 9 | 10 | for (const line of contents.split('\n')) { 11 | const lineTokens = countTokens(line); 12 | if (chunkTokens + lineTokens > maxChunkSize - 5) { 13 | yield { language, content: chunkContent, startLine, endLine: currLine - 1 }; 14 | chunkContent = ''; 15 | chunkTokens = 0; 16 | startLine = currLine; 17 | } 18 | 19 | if (lineTokens < maxChunkSize) { 20 | chunkContent += line + '\n'; 21 | chunkTokens += lineTokens + 1; 22 | } 23 | 24 | currLine++; 25 | } 26 | 27 | yield { 28 | language, 29 | content: chunkContent, 30 | startLine, 31 | endLine: currLine - 1, 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /src/code-search/chunk/ConstructCodeChunker.ts: -------------------------------------------------------------------------------- 1 | import { inferLanguage } from 'base/common/languages/languages'; 2 | import { ILanguageServiceProvider } from 'base/common/languages/languageService'; 3 | 4 | import { Chunker, ChunkWithoutID } from './_base/Chunk'; 5 | import { CollapsedCodeChunker } from './_base/CollapsedCodeChunker'; 6 | 7 | export class ConstructCodeChunker extends CollapsedCodeChunker implements Chunker { 8 | constructor(private lsp: ILanguageServiceProvider) { 9 | super(); 10 | } 11 | 12 | chunk(filepath: string, contents: string, maxChunkSize: number): AsyncGenerator { 13 | return this.codeChunker(filepath, contents, maxChunkSize); 14 | } 15 | 16 | async *codeChunker(filepath: string, contents: string, maxChunkSize: number): AsyncGenerator { 17 | if (contents.trim().length === 0) { 18 | return; 19 | } 20 | 21 | const language = inferLanguage(filepath); 22 | 23 | const parser = await this.lsp.getParser(language); 24 | if (parser === undefined) { 25 | console.warn(`Failed to load parser for file ${filepath}: `); 26 | return; 27 | } 28 | 29 | yield* this.parsedCodeChunker(parser, contents, maxChunkSize, language); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/code-search/chunk/SymbolBasedCodeChunker.ts: -------------------------------------------------------------------------------- 1 | import { Chunker, ChunkWithoutID } from './_base/Chunk'; 2 | import { ConstructCodeChunker } from './ConstructCodeChunker'; 3 | 4 | /** 5 | * SymbolChunker will build with symbol information, the symbol information will be used to build the [ScopeGraph] 6 | * 7 | * For example, in javascript, the symbol information will be the: 8 | * - package name 9 | * - class name 10 | * - method name 11 | */ 12 | export class SymbolBasedCodeChunker extends ConstructCodeChunker implements Chunker { 13 | // todo: add parsed for cannocical name 14 | chunk(filepath: string, contents: string, maxChunkSize: number): AsyncGenerator { 15 | return this.codeChunker(filepath, contents, maxChunkSize); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/code-search/chunk/_base/Chunk.ts: -------------------------------------------------------------------------------- 1 | export interface ChunkWithoutID { 2 | content: string; 3 | startLine: number; 4 | endLine: number; 5 | language: string; 6 | otherMetadata?: { [key: string]: any }; 7 | } 8 | 9 | export interface Chunk extends ChunkWithoutID { 10 | digest: string; 11 | filepath: string; 12 | index: number; // Index of the chunk in the document at filepath 13 | } 14 | 15 | export interface Chunker { 16 | chunk(filepath: string, contents: string, maxChunkSize: number): AsyncGenerator; 17 | } 18 | -------------------------------------------------------------------------------- /src/code-search/embedding/EmbeddingsProviderManager.ts: -------------------------------------------------------------------------------- 1 | import vscode from 'vscode'; 2 | 3 | import { EmbeddingsProvider } from './_base/EmbeddingsProvider'; 4 | import { LocalEmbeddingsProvider } from './LocalEmbeddingsProvider'; 5 | 6 | /** 7 | * @deprecated Please use {@link LanguageModelsService} instead. 8 | */ 9 | export namespace EmbeddingsProviderManager { 10 | export function init(context: vscode.ExtensionContext) { 11 | LocalEmbeddingsProvider.getInstance().init(context.extensionPath); 12 | } 13 | 14 | export function create(): EmbeddingsProvider { 15 | // todo: add more provider by settings 16 | return LocalEmbeddingsProvider.getInstance(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/code-search/embedding/_base/AuthedEmbeddingsProvider.ts: -------------------------------------------------------------------------------- 1 | import { Embedding } from './Embedding'; 2 | import { EmbeddingsProvider } from './EmbeddingsProvider'; 3 | 4 | export interface AuthedEmbedOptions { 5 | apiBase?: string; 6 | apiKey?: string; 7 | model?: string; 8 | requestOptions?: RequestOptions; 9 | } 10 | 11 | export interface RequestOptions { 12 | timeout?: number; 13 | verifySsl?: boolean; 14 | caBundlePath?: string | string[]; 15 | proxy?: string; 16 | headers?: { [key: string]: string }; 17 | extraBodyProperties?: { [key: string]: any }; 18 | } 19 | 20 | export type FetchFunction = (url: string | URL, init?: any) => Promise; 21 | 22 | export class AuthedEmbeddingsProvider implements EmbeddingsProvider { 23 | options: AuthedEmbedOptions; 24 | fetch: FetchFunction; 25 | static defaultOptions: Partial | undefined = undefined; 26 | 27 | get id(): string { 28 | throw new Error('Method not implemented.'); 29 | } 30 | 31 | constructor(options: AuthedEmbedOptions, fetch: FetchFunction) { 32 | this.options = { 33 | ...(this.constructor as typeof AuthedEmbeddingsProvider).defaultOptions, 34 | ...options, 35 | }; 36 | 37 | this.fetch = fetch; 38 | } 39 | 40 | embed(chunks: string[]): Promise { 41 | throw new Error('Method not implemented.'); 42 | } 43 | } 44 | 45 | export default AuthedEmbeddingsProvider; 46 | -------------------------------------------------------------------------------- /src/code-search/embedding/_base/BaseEmbeddingsProvider.ts: -------------------------------------------------------------------------------- 1 | import { Embedding } from './Embedding'; 2 | import { EmbeddingsProvider } from './EmbeddingsProvider'; 3 | 4 | export class BaseEmbeddingsProvider implements EmbeddingsProvider { 5 | id: string; 6 | 7 | constructor(id: string) { 8 | this.id = id; 9 | } 10 | 11 | async embed(chunks: string[]): Promise { 12 | throw new Error('Method not implemented.'); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/code-search/embedding/_base/Embedding.ts: -------------------------------------------------------------------------------- 1 | import { TextRange } from '../../scope-graph/model/TextRange'; 2 | 3 | export type Embedding = number[]; 4 | 5 | export interface ScoredItem { 6 | score: number; 7 | item: T; 8 | } 9 | 10 | export interface ChunkItem { 11 | /// file name with range 12 | name: string; 13 | /// path 14 | path: string; 15 | text: string; 16 | range: TextRange; 17 | embedding: Embedding; 18 | score?: number; 19 | } 20 | -------------------------------------------------------------------------------- /src/code-search/embedding/_base/EmbeddingsProvider.ts: -------------------------------------------------------------------------------- 1 | import { Embedding } from './Embedding'; 2 | 3 | export interface EmbeddingsProvider { 4 | /** 5 | * Unique identifier for the provider 6 | */ 7 | id: string; 8 | /** 9 | * A text content will split into multiple chunks. 10 | * Accepts a list of code chunks and returns a list of embeddings data 11 | */ 12 | embed(chunks: string[]): Promise; 13 | } 14 | 15 | export enum EmbeddingsProviderType { 16 | Local = 'local', 17 | OpenAI = 'openai', 18 | Ollama = 'ollama', 19 | } 20 | -------------------------------------------------------------------------------- /src/code-search/embedding/_base/NamedChunk.ts: -------------------------------------------------------------------------------- 1 | import { TreeSitterFileManager } from 'src/editor/cache/TreeSitterFileManager'; 2 | import vscode from 'vscode'; 3 | 4 | import { createNamedElement } from '../../../code-context/ast/TreeSitterWrapper'; 5 | import { NamedElement } from '../../../editor/ast/NamedElement'; 6 | import { TextRange } from '../../scope-graph/model/TextRange'; 7 | import { ChunkItem, Embedding } from './Embedding'; 8 | 9 | export interface NamedChunkItem { 10 | name: string; 11 | path: string; 12 | text: string; 13 | score?: number; 14 | range: TextRange; 15 | namedElements: NamedElement[]; 16 | embedding: Embedding; 17 | } 18 | 19 | export class NamedChunk { 20 | static async create(treeSitterFileManager: TreeSitterFileManager, chunk: ChunkItem): Promise { 21 | let document; 22 | try { 23 | const fileUri = vscode.Uri.file(chunk.path); 24 | document = await vscode.workspace.openTextDocument(fileUri); 25 | } catch (error) { 26 | return Promise.reject(error); 27 | } 28 | 29 | let elementBuilder = await createNamedElement(treeSitterFileManager, document); 30 | 31 | let namedElements = elementBuilder.getElementForSelection(chunk.range.start.line, chunk.range.end.line); 32 | 33 | return { 34 | name: chunk.name, 35 | path: chunk.path, 36 | text: chunk.text, 37 | range: chunk.range, 38 | namedElements: namedElements, 39 | embedding: chunk.embedding, 40 | }; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/code-search/embedding/utils/withExponentialBackoff.ts: -------------------------------------------------------------------------------- 1 | interface APIError extends Error { 2 | response?: Response; 3 | } 4 | 5 | const RETRY_AFTER_HEADER = 'Retry-After'; 6 | 7 | const withExponentialBackoff = async (apiCall: () => Promise, maxRetries = 5, initialDelaySeconds = 1) => { 8 | for (let attempt = 0; attempt < maxRetries; attempt++) { 9 | try { 10 | const result = await apiCall(); 11 | return result; 12 | } catch (error: any) { 13 | if ((error as APIError).response?.status === 429 && attempt < maxRetries - 1) { 14 | const retryAfter = (error as APIError).response?.headers.get(RETRY_AFTER_HEADER); 15 | const delay = retryAfter ? parseInt(retryAfter, 10) : initialDelaySeconds * 2 ** attempt; 16 | console.log(`Hit rate limit. Retrying in ${delay} seconds (attempt ${attempt + 1})`); 17 | await new Promise(resolve => setTimeout(resolve, delay * 1000)); 18 | } else { 19 | throw error; // Re-throw other errors 20 | } 21 | } 22 | } 23 | throw new Error('Failed to make API call after multiple retries'); 24 | }; 25 | 26 | export { withExponentialBackoff }; 27 | -------------------------------------------------------------------------------- /src/code-search/history/BugLooper.ts: -------------------------------------------------------------------------------- 1 | import { HistoryAgent } from './_base/HistoryAgent'; 2 | 3 | /** 4 | * The BugLooperTool class is an exquisite TypeScript class that offers a sophisticated suite of functionalities related to time travel. 5 | * This class is primarily used to encapsulate and summarize commits, as well as to provide a comprehensive view of the history of commits. 6 | * 7 | * For instance: 8 | * - In commit , on , what changes were made by ? Could these changes be related to ? 9 | * - In commit , on , what changes were made by ? Could these changes be simply a ? 10 | * 11 | * This class is a powerful tool for developers to track and understand the evolution of their codebase. 12 | */ 13 | export class BugLooper extends HistoryAgent { 14 | name: string = 'BugLooper'; 15 | description: string = 'BugLooper is a tool that helps you to track and understand the evolution of your codebase.'; 16 | 17 | /** 18 | * The summaryCommit method is used to summarize the changes made in a commit. 19 | */ 20 | summaryCommit() { 21 | // 22 | } 23 | 24 | /** 25 | * The whoIsKiller method is used to identify the author of a commit. 26 | */ 27 | whoIsKiller() {} 28 | 29 | /** 30 | * The history method is used to provide a comprehensive view of the history of commits. 31 | */ 32 | history() { 33 | // 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/code-search/history/_base/HistoryAgent.ts: -------------------------------------------------------------------------------- 1 | export abstract class HistoryAgent { 2 | abstract name: string; 3 | abstract description: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/code-search/history/_base/HistoryBuilder.ts: -------------------------------------------------------------------------------- 1 | import { GitCommit } from '../../../git/model/GitCommit'; 2 | 3 | export class HistoryBuilder { 4 | /// build by issue id / story id 5 | buildByIssueId(issueId: string): GitCommit[] { 6 | return []; 7 | } 8 | 9 | /// build by single file with function 10 | buildBySingleFile(filePath: string): GitCommit[] { 11 | return []; 12 | } 13 | 14 | buildBySymbolId(symbolId: string): GitCommit[] { 15 | return []; 16 | } 17 | 18 | /// build by all 19 | buildAll(): GitCommit[] { 20 | return []; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/code-search/history/_base/TimeTravelDebugger.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * TimeTravelDebugger 接口定义了一个时间旅行调试器的行为 3 | */ 4 | export interface TimeTravelDebugger { 5 | /** 6 | * 捕获当前状态快照 7 | */ 8 | takeSnapshot(): Snapshot; 9 | 10 | /** 11 | * 恢复到指定状态快照 12 | * @param snapshot - 要恢复的状态快照 13 | */ 14 | restoreSnapshot(snapshot: Snapshot): void; 15 | 16 | /** 17 | * 回溯指定步数 18 | * @param steps - 要回溯的步数 19 | */ 20 | rewind(steps: number): void; 21 | 22 | /** 23 | * 快进指定步数 24 | * @param steps - 要快进的步数 25 | */ 26 | fastForward(steps: number): void; 27 | 28 | /** 29 | * 暂停代码执行 30 | */ 31 | pause(): void; 32 | 33 | /** 34 | * 重新执行代码 35 | */ 36 | replay(): void; 37 | } 38 | -------------------------------------------------------------------------------- /src/code-search/indexing/model/CodebaseIndexType.ts: -------------------------------------------------------------------------------- 1 | export enum CodebaseIndexType { 2 | ChunkCodebase, 3 | CodeSnippets, 4 | LanceDb, 5 | FullTextSearch, 6 | } 7 | -------------------------------------------------------------------------------- /src/code-search/indexing/third/ElasticSearchIndexer.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CodebaseIndex, 3 | IndexingProgressUpdate, 4 | IndexTag, 5 | MarkCompleteCallback, 6 | RefreshIndexResults, 7 | } from '../_base/CodebaseIndex'; 8 | 9 | export class ElasticSearchIndexer implements CodebaseIndex { 10 | artifactId = 'elasticsearch'; 11 | 12 | update( 13 | tag: IndexTag, 14 | result: RefreshIndexResults, 15 | markComplete: MarkCompleteCallback, 16 | repoName: string | undefined, 17 | ): AsyncGenerator { 18 | throw new Error('Method not implemented.'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/code-search/reranker/Reranker.ts: -------------------------------------------------------------------------------- 1 | import { Chunk } from '../chunk/_base/Chunk'; 2 | import { Embedding } from '../embedding/_base/Embedding'; 3 | 4 | export interface Reranker { 5 | name: string; 6 | rerank(query: string, chunks: Chunk[]): Promise; 7 | } 8 | -------------------------------------------------------------------------------- /src/code-search/retrieval/RetrievalQueryTerm.ts: -------------------------------------------------------------------------------- 1 | import { BranchAndDir } from '../indexing/_base/CodebaseIndex'; 2 | 3 | export class RetrievalQueryTerm { 4 | query = ''; 5 | n = 0; 6 | tags: BranchAndDir[]; 7 | filterDirectory?: string; 8 | language?: string; 9 | minimumScore: number; 10 | 11 | constructor( 12 | query: string, 13 | n: number, 14 | tags: BranchAndDir[], 15 | filterDirectory?: string, 16 | language?: string, 17 | minimumScore: number = 0.618, 18 | ) { 19 | this.query = query; 20 | this.n = n; 21 | this.tags = tags; 22 | this.filterDirectory = filterDirectory; 23 | this.language = language; 24 | this.minimumScore = minimumScore; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/code-search/scope-graph/edge/EdgeKind.ts: -------------------------------------------------------------------------------- 1 | export interface EdgeKind {} 2 | 3 | export class ScopeToScope implements EdgeKind {} 4 | 5 | export class DefToScope implements EdgeKind {} 6 | 7 | export class ImportToScope implements EdgeKind {} 8 | 9 | export class RefToDef implements EdgeKind {} 10 | 11 | export class RefToImport implements EdgeKind {} 12 | -------------------------------------------------------------------------------- /src/code-search/scope-graph/model/ImportWithRefs.ts: -------------------------------------------------------------------------------- 1 | import { TextRange } from './TextRange'; 2 | 3 | /** 4 | * The `ImportWithRefs` interface in TypeScript is used to represent an import statement with its references in the code. 5 | * It contains information about the import name, the range of the import text, the original import text, and the usage of the import text. 6 | * 7 | * @interface 8 | * 9 | * @property {string} name - Represents the name of the import, such as `List`. 10 | * 11 | * @property {TextRange} range - Represents the range of the import text in the code. The `TextRange` object typically includes the start and end positions of the import text. 12 | * 13 | * @property {string} text - Represents the original import text, like `import java.util.List;`. This is the exact text that appears in the code. 14 | * 15 | * @property {TextRange[]} refs - An array of `TextRange` objects that represent the usage of the import text in the code, like `new List();`. Each `TextRange` object in the array typically includes the start and end positions of the usage of the import text. 16 | * 17 | */ 18 | export interface ImportWithRefs { 19 | /// the import name, like `List` 20 | name: string; 21 | /// the range of the import text 22 | range: TextRange; 23 | /// origin import text, like `import java.util.List;` 24 | text: string; 25 | /// use import text, like `new List();` 26 | refs: TextRange[]; 27 | } 28 | -------------------------------------------------------------------------------- /src/code-search/scope-graph/model/Namespace.ts: -------------------------------------------------------------------------------- 1 | export type NameSpace = Array; 2 | export type NameSpaces = Array; 3 | -------------------------------------------------------------------------------- /src/code-search/scope-graph/model/SymbolId.ts: -------------------------------------------------------------------------------- 1 | import { NameSpaces } from './Namespace'; 2 | 3 | export interface SymbolId { 4 | namespaceIndex: number; 5 | symbolIndex: number; 6 | } 7 | 8 | export function nameOfSymbol(namespaces: NameSpaces, symbolId: SymbolId): string { 9 | return namespaces[symbolId.namespaceIndex][symbolId.symbolIndex]; 10 | } 11 | 12 | export function allSymbols(namespaces: NameSpaces): string[] { 13 | return namespaces.flatMap(ns => ns.slice()).filter((symbol, index, arr) => arr.indexOf(symbol) === index); 14 | } 15 | 16 | export function symbolIdOf(namespaces: NameSpaces, symbol: string): SymbolId | undefined { 17 | for (let namespaceIdx = 0; namespaceIdx < namespaces.length; namespaceIdx++) { 18 | const symbolIdx = namespaces[namespaceIdx].indexOf(symbol); 19 | if (symbolIdx !== -1) { 20 | return { 21 | namespaceIndex: namespaceIdx, 22 | symbolIndex: symbolIdx, 23 | }; 24 | } 25 | } 26 | 27 | return undefined; 28 | } 29 | -------------------------------------------------------------------------------- /src/code-search/scope-graph/node/LocalDef.ts: -------------------------------------------------------------------------------- 1 | import { SymbolId } from '../model/SymbolId'; 2 | import { TextRange } from '../model/TextRange'; 3 | import { NodeKind } from './NodeKind'; 4 | 5 | /// A definition node 6 | export class LocalDef extends NodeKind { 7 | range: TextRange; 8 | symbolId?: SymbolId | null; 9 | 10 | constructor(range: TextRange, symbolId?: SymbolId | null) { 11 | super(range); 12 | this.range = range; 13 | this.symbolId = symbolId; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/code-search/scope-graph/node/LocalImport.ts: -------------------------------------------------------------------------------- 1 | import { TextRange } from '../model/TextRange'; 2 | import { NodeKind } from './NodeKind'; 3 | 4 | export class LocalImport extends NodeKind { 5 | range: TextRange; 6 | 7 | constructor(range: TextRange) { 8 | super(range); 9 | this.range = range; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/code-search/scope-graph/node/LocalScope.ts: -------------------------------------------------------------------------------- 1 | import Graph from 'graphology'; 2 | 3 | import { ScopeToScope } from '../edge/EdgeKind'; 4 | import { TextRange } from '../model/TextRange'; 5 | import { NodeKind } from './NodeKind'; 6 | 7 | export class LocalScope extends NodeKind { 8 | range: TextRange; 9 | 10 | constructor(range: TextRange) { 11 | super(range); 12 | this.range = range; 13 | } 14 | } 15 | 16 | export class ScopeStack implements Iterable { 17 | private scopeGraph: Graph; 18 | private start: string | undefined; 19 | 20 | constructor(scopeGraph: Graph, start: string | undefined = undefined) { 21 | this.scopeGraph = scopeGraph; 22 | this.start = start; 23 | } 24 | 25 | [Symbol.iterator](): Iterator { 26 | let current = this.start; 27 | 28 | return { 29 | next: () => { 30 | if (current) { 31 | const parentId = this.scopeGraph 32 | .outEdges(current) 33 | .filter(edge => this.scopeGraph.getEdgeAttributes(edge) instanceof ScopeToScope) 34 | .map(edge => this.scopeGraph.target(edge))[0]; 35 | 36 | const original = current; 37 | current = parentId; 38 | return { value: original, done: false }; 39 | } else { 40 | return { value: undefined, done: true }; 41 | } 42 | }, 43 | }; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/code-search/scope-graph/node/NodeKind.ts: -------------------------------------------------------------------------------- 1 | import { TextRange } from '../model/TextRange'; 2 | 3 | export class NodeKind { 4 | range: TextRange; 5 | 6 | constructor(range: TextRange) { 7 | this.range = range; 8 | } 9 | 10 | name(buffer: string): string { 11 | return buffer.substring(this.range!!.start.byte, this.range!!.end.byte); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/code-search/scope-graph/node/Reference.ts: -------------------------------------------------------------------------------- 1 | import { SymbolId } from '../model/SymbolId'; 2 | import { TextRange } from '../model/TextRange'; 3 | import { NodeKind } from './NodeKind'; 4 | 5 | export class Reference extends NodeKind { 6 | range: TextRange; 7 | symbolId: SymbolId | null; 8 | 9 | constructor(range: TextRange, symbolId: SymbolId | null) { 10 | super(range); 11 | this.range = range; 12 | this.symbolId = symbolId; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/code-search/search-strategy/_base/HydeDocument.ts: -------------------------------------------------------------------------------- 1 | export enum HydeDocumentType { 2 | Code = 'code', 3 | Keywords = 'keywords', 4 | } 5 | 6 | export class HydeDocument { 7 | constructor( 8 | public type: HydeDocumentType, 9 | public content: T, 10 | ) {} 11 | } 12 | -------------------------------------------------------------------------------- /src/code-search/search-strategy/_base/HydeStep.ts: -------------------------------------------------------------------------------- 1 | export enum HydeStep { 2 | /// the first step of the search-strategy 3 | Propose = 'propose', 4 | /// the second step of the search-strategy 5 | Retrieve = 'retrieve', 6 | /// the end of the search-strategy 7 | Evaluate = 'evaluate', 8 | } 9 | -------------------------------------------------------------------------------- /src/code-search/search-strategy/_base/StrategyFinalPrompt.ts: -------------------------------------------------------------------------------- 1 | import { ChunkItem } from '../../embedding/_base/Embedding'; 2 | 3 | export class StrategyFinalPrompt { 4 | constructor( 5 | public readonly prompt: string, 6 | public readonly chunks: ChunkItem[], 7 | ) {} 8 | } 9 | -------------------------------------------------------------------------------- /src/code-search/search/_base/SearchOptions.ts: -------------------------------------------------------------------------------- 1 | export interface SearchOptions { 2 | include: string; 3 | } 4 | -------------------------------------------------------------------------------- /src/code-search/search/_base/SemanticSearch.ts: -------------------------------------------------------------------------------- 1 | import { CancellationToken } from 'vscode'; 2 | 3 | import { SearchOptions } from './SearchOptions'; 4 | 5 | export interface SemanticSearch { 6 | /** 7 | * 搜索相似代码块 8 | * @param {string[]} items - 要搜索的文本,例如 `keyword`,。 9 | * @param {number} maxResults - 最大结果数。 10 | * @param {object} options - 搜索选项对象。 11 | * @param {boolean} options.include - 是否包含指定的内容,诸如于路径、文件名等。 12 | * @param {object} cancellationToken - 用于取消操作的信号对象。 13 | * @returns {Promise} - 返回搜索结果的数组。 14 | */ 15 | searchChunks( 16 | items: string[], 17 | maxResults: number, 18 | options: SearchOptions, 19 | cancellationToken: CancellationToken, 20 | ): Promise>; 21 | } 22 | -------------------------------------------------------------------------------- /src/code-search/similar/SimilarChunk.ts: -------------------------------------------------------------------------------- 1 | export interface SimilarChunk { 2 | path: string; 3 | text: string; 4 | } 5 | -------------------------------------------------------------------------------- /src/code-search/similar/algorithm/SimilarSearcher.ts: -------------------------------------------------------------------------------- 1 | import { SimilarChunk } from '../SimilarChunk'; 2 | import { SimilarSearchElement } from '../SimilarSearchElementBuilder'; 3 | 4 | export interface SimilarSearcher { 5 | search(element: SimilarSearchElement): SimilarChunk[]; 6 | 7 | extractChunks(mostRecentFiles: T[]): string[][]; 8 | 9 | getMostRecentFiles(languageId: string): T[]; 10 | } 11 | -------------------------------------------------------------------------------- /src/code-search/similar/algorithm/TokenizedSimilarity.ts: -------------------------------------------------------------------------------- 1 | import { StopwordsBasedTokenizer } from "../../tokenizer/StopwordsBasedTokenizer"; 2 | 3 | export interface Similarity { 4 | computeInputSimilarity(query: string, chunks: Array>): Array>; 5 | } 6 | 7 | export abstract class TokenizedSimilarity implements Similarity { 8 | tokenize(input: string): Set { 9 | return StopwordsBasedTokenizer.instance().tokenize(input); 10 | } 11 | 12 | abstract computeInputSimilarity(query: string, chunks: Array>): Array>; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/code-search/tokenizer/CodeTokenizer.ts: -------------------------------------------------------------------------------- 1 | export interface CodeTokenizer { 2 | tokenize(input: string): Set; 3 | } 4 | -------------------------------------------------------------------------------- /src/code-search/tokenizer/WhitespaceBasedTokenizer.ts: -------------------------------------------------------------------------------- 1 | import { CodeTokenizer } from './CodeTokenizer'; 2 | 3 | export class WhitespaceBasedTokenizer implements CodeTokenizer { 4 | tokenize(input: string): Set { 5 | let words = this.splitIntoWords(input); 6 | return new Set(words); 7 | } 8 | 9 | /** 10 | * @param input 11 | */ 12 | splitIntoWords(input: string): string[] { 13 | return input.split(/[^a-zA-Z0-9]/).filter(word => word.length > 0); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/code-search/utils/FileFilter.ts: -------------------------------------------------------------------------------- 1 | import { Uri, WorkspaceFolder } from 'vscode'; 2 | 3 | const ignore = require('ignore'); 4 | const fs = require('fs'); 5 | const isBinaryFile = require('isbinaryfile').isBinaryFile; 6 | 7 | /** 8 | * Example usage: 9 | * ```javascript 10 | * // Example usage: 11 | * const filter = new FileFilter(); 12 | * const uri = Uri.file('/path/to/file.jpg'); 13 | * const workspace = { 14 | * getWorkspaceFolders: () => [], 15 | * }; 16 | * const includeUntitled = false; 17 | * console.log(filter.shouldIncludeFile(uri, workspace, includeUntitled)); 18 | * ``` 19 | */ 20 | class FileFilter { 21 | isIgnored(uri: Uri, workspaceFolder: WorkspaceFolder | undefined) { 22 | let ignored = ignore().add(fs.readFileSync('.gitignore').toString()); 23 | 24 | return ignored.ignores(uri.path); 25 | } 26 | 27 | private getFileExtension(uri: Uri): string { 28 | const pathSegments = uri.path.split('/'); 29 | const fileName = pathSegments.pop() || ''; 30 | const dotIndex = fileName.lastIndexOf('.'); 31 | return dotIndex !== -1 ? fileName.substring(dotIndex + 1) : ''; 32 | } 33 | 34 | async isBinaryFile(data: any, length: number) { 35 | return await isBinaryFile(data, length); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/code-search/utils/IndexPathHelper.ts: -------------------------------------------------------------------------------- 1 | import os from 'node:os'; 2 | 3 | import fs from 'fs'; 4 | import path from 'path'; 5 | 6 | export function getAutoDevGlobalPath(): string { 7 | // This is ~/.autodev on mac/linux 8 | const autodevPath = path.join(os.homedir(), '.autodev'); 9 | if (!fs.existsSync(autodevPath)) { 10 | fs.mkdirSync(autodevPath); 11 | } 12 | 13 | return autodevPath; 14 | } 15 | 16 | export function getDocsSqlitePath(): string { 17 | return path.join(getIndexFolderPath(), 'docs.sqlite'); 18 | } 19 | 20 | export function getIndexFolderPath(): string { 21 | const indexPath = path.join(getAutoDevGlobalPath(), 'index'); 22 | if (!fs.existsSync(indexPath)) { 23 | fs.mkdirSync(indexPath); 24 | } 25 | return indexPath; 26 | } 27 | 28 | export function getLanceDbPath(): string { 29 | return path.join(getIndexFolderPath(), 'lancedb'); 30 | } 31 | 32 | export function getBasename(filepath: string, n: number = 1): string { 33 | return filepath.split(/[\\/]/).pop() ?? ''; 34 | } 35 | -------------------------------------------------------------------------------- /src/code-search/utils/constants.ts: -------------------------------------------------------------------------------- 1 | export const MAX_CHUNK_SIZE = 500; // 512 - buffer for safety (in case of differing tokenizers) 2 | 3 | export const RETRIEVAL_PARAMS = { 4 | rerankThreshold: 0.3, 5 | nFinal: 10, 6 | nRetrieve: 20, 7 | bm25Threshold: -2.5, 8 | }; 9 | -------------------------------------------------------------------------------- /src/commands/commands.ts: -------------------------------------------------------------------------------- 1 | import { commands } from 'vscode'; 2 | 3 | import { CMD_OPEN_SETTINGS, CMD_NEW_CHAT_SESSION } from 'base/common/configuration/configuration'; 4 | 5 | export function openSettings() { 6 | return commands.executeCommand(CMD_OPEN_SETTINGS); 7 | } 8 | 9 | export function reloadWebview() { 10 | commands.executeCommand('workbench.action.webview.reloadWebviewAction'); 11 | } 12 | 13 | export function newChatSession(prompt?: string) { 14 | commands.executeCommand(CMD_NEW_CHAT_SESSION, prompt); 15 | } 16 | -------------------------------------------------------------------------------- /src/devins/DevInsLanguage.ts: -------------------------------------------------------------------------------- 1 | // todo 2 | -------------------------------------------------------------------------------- /src/devins/EmbeddMarkdown.ts: -------------------------------------------------------------------------------- 1 | // TODO: follow https://code.visualstudio.com/api/language-extensions/embedded-languages 2 | -------------------------------------------------------------------------------- /src/domain/QueryExpansion.ts: -------------------------------------------------------------------------------- 1 | import { TeamTerm } from './TeamTerm'; 2 | import { TeamTermService } from './TeamTermService'; 3 | 4 | export class QueryExpansion { 5 | constructor( 6 | private teamTermService: TeamTermService, 7 | ) {} 8 | 9 | expand(query: string): string { 10 | let terms: TeamTerm[] = []; 11 | try { 12 | terms = this.teamTermService.fetch(); 13 | } catch (e) { 14 | console.info(e); 15 | } 16 | 17 | terms.forEach(term => { 18 | query = query.replace(term.localized, term.localized + '(' + term.term + ')'); 19 | }); 20 | 21 | return query; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/domain/TeamTerm.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Represents a term used in a specific team's language. 3 | */ 4 | export interface TeamTerm { 5 | id: string; 6 | /// term should be in english, like `function` 7 | /// for example: `永远的神` will be `yyds` 8 | term: string; 9 | /// origin language, like Chinese 10 | localized: string; 11 | } 12 | -------------------------------------------------------------------------------- /src/editor/ast/PositionUtil.ts: -------------------------------------------------------------------------------- 1 | import vscode, { Position, Selection } from 'vscode'; 2 | import type { Point, SyntaxNode } from 'web-tree-sitter'; 3 | 4 | export namespace PositionUtil { 5 | export function fromNode(point: Point): Position { 6 | return new Position(point.row, point.column); 7 | } 8 | 9 | export function toPoint(position: Position): Point { 10 | return { row: position.line, column: position.character }; 11 | } 12 | 13 | export function selectionFromNode(node: SyntaxNode): Selection { 14 | const start = fromNode(node.startPosition); 15 | const end = fromNode(node.endPosition); 16 | return new Selection(start, end); 17 | } 18 | 19 | export function selectionToNode(selection: Selection): [Point, Point] { 20 | return [toPoint(selection.start), toPoint(selection.end)]; 21 | } 22 | } 23 | 24 | export function selectCodeInRange(start: vscode.Position, end: vscode.Position) { 25 | const editor = vscode.window.activeTextEditor; 26 | if (editor) { 27 | const newSelection = new vscode.Selection(start, end); 28 | editor.selection = newSelection; 29 | editor.revealRange(newSelection); 30 | } 31 | } 32 | 33 | export function insertCodeByRange(textRange: Position, doc: string) { 34 | const editor = vscode.window.activeTextEditor; 35 | if (editor) { 36 | editor.edit(editBuilder => { 37 | editBuilder.insert(textRange, doc); 38 | }); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/editor/ast/TextInRange.ts: -------------------------------------------------------------------------------- 1 | import { Position, Range } from 'vscode'; 2 | import { SyntaxNode } from 'web-tree-sitter'; 3 | 4 | import { Point, TextRange } from '../../code-search/scope-graph/model/TextRange'; 5 | 6 | export class TextInRange extends Range { 7 | text: string; 8 | startIndex: number; 9 | endIndex: number; 10 | 11 | private constructor(displayName: string = '', start: Position, end: Position, startIndex: number, endIndex: number) { 12 | super(start, end); 13 | this.text = displayName; 14 | this.startIndex = startIndex; 15 | this.endIndex = endIndex; 16 | } 17 | 18 | static fromNode(id: SyntaxNode) { 19 | const startPosition = new Position(id.startPosition.row, id.startPosition.column); 20 | const endPosition = new Position(id.endPosition.row, id.endPosition.column); 21 | 22 | const startIndex = id.startIndex; 23 | const endIndex = id.endIndex; 24 | 25 | return new TextInRange(id.text, startPosition, endPosition, startIndex, endIndex); 26 | } 27 | 28 | toTextRange(): TextRange { 29 | const start = new Point(this.start.line, this.start.character, this.startIndex); 30 | const end = new Point(this.end.line, this.end.character, this.endIndex); 31 | return new TextRange(start, end, this.text); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/editor/cache/FileCacheManger.ts: -------------------------------------------------------------------------------- 1 | import { Uri } from 'vscode'; 2 | 3 | export interface FileCacheManger { 4 | getDocument(uri: Uri, version: number): T | undefined; 5 | setDocument(uri: Uri, version: number, file: T): void; 6 | } 7 | -------------------------------------------------------------------------------- /src/editor/codemodel/CodeElementType.ts: -------------------------------------------------------------------------------- 1 | export enum CodeElementType { 2 | File, 3 | Structure, 4 | Method, 5 | Variable, 6 | } 7 | -------------------------------------------------------------------------------- /src/editor/codemodel/PositionElement.ts: -------------------------------------------------------------------------------- 1 | import { CodePosition } from './CodeElement'; 2 | 3 | export interface PositionElement { 4 | start: CodePosition; 5 | end: CodePosition; 6 | } 7 | -------------------------------------------------------------------------------- /src/editor/codemodel/presenter/CommentedUmlPresenter.ts: -------------------------------------------------------------------------------- 1 | import { LANGUAGE_LINE_COMMENT_MAP } from 'base/common/languages/docstring'; 2 | import { CodeFile, CodeStructure } from '../CodeElement'; 3 | import { PlantUMLPresenter } from './PlantUMLPresenter'; 4 | 5 | export class CommentedUmlPresenter extends PlantUMLPresenter { 6 | present(file: CodeFile): string { 7 | const commentSymbol = LANGUAGE_LINE_COMMENT_MAP[file.language]; 8 | const plantUml = this.render(file); 9 | 10 | return plantUml 11 | .split('\n') 12 | .map(line => { 13 | return `${commentSymbol} ${line}`; 14 | }) 15 | .join('\n'); 16 | } 17 | 18 | presentClass(clazz: CodeStructure, lang: string): string { 19 | const commentSymbol = LANGUAGE_LINE_COMMENT_MAP[lang]; 20 | const plantUml = this.renderClass(clazz); 21 | 22 | return plantUml 23 | .split('\n') 24 | .map(line => { 25 | return `${commentSymbol} ${line}`; 26 | }) 27 | .join('\n'); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/editor/codemodel/presenter/Presenter.ts: -------------------------------------------------------------------------------- 1 | import { CodeFile } from '../CodeElement'; 2 | 3 | export interface Presenter { 4 | present(file: CodeFile): string; 5 | } 6 | -------------------------------------------------------------------------------- /src/editor/diff/DiffManager.ts: -------------------------------------------------------------------------------- 1 | import { Repository } from '../../types/git'; 2 | 3 | export class DiffManager { 4 | static simplifyDiff(gitRoot: Repository, diffString: string) { 5 | return diffString; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/editor/editor-api/IdeAction.ts: -------------------------------------------------------------------------------- 1 | import { GitAction } from '../../git/GitAction'; 2 | 3 | export interface IdeAction { 4 | git: GitAction; 5 | getTerminalContents(): Promise; 6 | runCommand(command: string): Promise; 7 | readFile(filepath: string): Promise; 8 | getBranch(dir: string): Promise; 9 | getStats(directory: string): Promise<{ [path: string]: number }>; 10 | getRepoName(dir: string): Promise; 11 | getWorkspaceDirectories(): string[]; 12 | } 13 | -------------------------------------------------------------------------------- /src/git/message/IssueIdParser.ts: -------------------------------------------------------------------------------- 1 | import { GitCommit } from '../model/GitCommit'; 2 | 3 | /** 4 | * Will parse the issue id from the commit message 5 | */ 6 | export class IssueIdParser { 7 | /** 8 | * Parse the issue id from the commit message 9 | * @param commitMessage The commit message to parse 10 | * @returns The issue id 11 | */ 12 | parseIssueId(commitMessage: string): string[] { 13 | return []; 14 | } 15 | 16 | /** 17 | * 18 | */ 19 | fetchCommitByIssueId(issueId: string): GitCommit[] { 20 | return []; 21 | } 22 | 23 | /** 24 | * Fetch the commit by the issue id 25 | */ 26 | fetchCommitBySingleFile(filePath: string): GitCommit[] { 27 | return []; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/git/model/GitCommit.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The `GitCommit` interface in TypeScript represents a single commit in a Git repository. 3 | * It provides a structured way to interact with and manipulate Git commit data. 4 | */ 5 | export interface GitCommit { 6 | /** 7 | * The hash value of the commit. This is a unique identifier for each commit. 8 | */ 9 | hash: string; 10 | /** 11 | * The commit message. This is a brief description of the changes made in the commit. 12 | */ 13 | message: string; 14 | /** 15 | * An array of strings representing the list of files that were changed in the commit. 16 | */ 17 | filesChanged: string[]; 18 | } 19 | -------------------------------------------------------------------------------- /src/git/parser/SimpleGitLogParser.ts: -------------------------------------------------------------------------------- 1 | export interface ParsedFileChange { 2 | status: string; 3 | /// 4 | content: string; 5 | filename: string; 6 | } 7 | 8 | export function parseGitLog(log: string): ParsedFileChange[] { 9 | const changes: ParsedFileChange[] = []; 10 | const lines = log.split('\n'); 11 | let currentFile: Partial | null = null; 12 | 13 | for (const line of lines) { 14 | if (line.startsWith('diff --git')) { 15 | if (currentFile && currentFile.filename) { 16 | changes.push(currentFile as ParsedFileChange); 17 | } 18 | currentFile = { filename: '', status: '', content: '' }; 19 | const parts = line.split(' '); 20 | currentFile.filename = parts[2].substring(2); // remove the 'a/' prefix 21 | } else if (line.startsWith('index')) { 22 | // Do nothing with index line for now 23 | } else if (line.startsWith('---')) { 24 | currentFile!.status = line.includes('/dev/null') ? 'deleted' : 'modified'; 25 | } else if (line.startsWith('+++')) { 26 | currentFile!.status = line.includes('/dev/null') ? 'deleted' : 'added'; 27 | } else if (line.startsWith('@@')) { 28 | currentFile!.content += line + '\n'; 29 | } else if (line.startsWith('+') || line.startsWith('-') || line.startsWith(' ')) { 30 | currentFile!.content += line + '\n'; 31 | } 32 | } 33 | 34 | if (currentFile && currentFile.filename) { 35 | changes.push(currentFile as ParsedFileChange); 36 | } 37 | 38 | return changes; 39 | } 40 | -------------------------------------------------------------------------------- /src/migrations/configurationMigrationHelper.ts: -------------------------------------------------------------------------------- 1 | import { l10n, window } from 'vscode'; 2 | 3 | import { ConfigurationService } from 'base/common/configuration/configurationService'; 4 | 5 | export class ConfigurationMigrationHelper { 6 | constructor(private configService: ConfigurationService) {} 7 | 8 | async migrationOpenAILegacyConfig() { 9 | const configService = this.configService; 10 | if (!configService.hasConfig('openaiCompatibleConfig')) { 11 | return; 12 | } 13 | 14 | const confirmed = await window.showWarningMessage( 15 | 'The `openaiCompatibleConfig` is outdated, now migrate to the latest?', 16 | l10n.t('Yes'), 17 | l10n.t('No'), 18 | ); 19 | 20 | if (confirmed !== 'Yes') { 21 | return; 22 | } 23 | 24 | const openaiCompatibleConfig = this.configService.getConfig('openaiCompatibleConfig'); 25 | 26 | console.log(openaiCompatibleConfig); 27 | } 28 | 29 | async run() { 30 | this.migrationOpenAILegacyConfig(); 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/prompt-manage/ActionType.ts: -------------------------------------------------------------------------------- 1 | export enum ActionType { 2 | AutoDoc, 3 | AutoTest, 4 | GenApiData, 5 | QuickAction, 6 | Rename, 7 | GenCommitMessage, 8 | LlmReranker, 9 | AutoMethod, 10 | } 11 | -------------------------------------------------------------------------------- /src/prompt-manage/InteractionType.ts: -------------------------------------------------------------------------------- 1 | export enum InteractionType { 2 | ChatPanel = 'ChatPanel', 3 | AppendCursor = 'AppendCursor', 4 | AppendCursorStream = 'AppendCursorStream', 5 | OutputFile = 'OutputFile', 6 | ReplaceSelection = 'ReplaceSelection', 7 | } 8 | -------------------------------------------------------------------------------- /src/prompt-manage/custom-action/CustomActionExecutePrompt.ts: -------------------------------------------------------------------------------- 1 | import { ToolchainContextItem } from '../../toolchain-context/ToolchainContextProvider'; 2 | 3 | export interface CustomActionExecutePrompt { 4 | displayPrompt: string; 5 | requestPrompt: string; 6 | contextItems: ToolchainContextItem[]; 7 | } 8 | -------------------------------------------------------------------------------- /src/prompt-manage/custom-action/CustomActionTemplateContext.ts: -------------------------------------------------------------------------------- 1 | import { NamedElement } from '../../editor/ast/NamedElement'; 2 | import { TemplateContext } from '../template/TemplateContext'; 3 | 4 | export interface CustomActionTemplateContext extends TemplateContext { 5 | filepath: string; 6 | element: NamedElement; 7 | beforeCursor: string; 8 | afterCursor: string; 9 | selection: string; 10 | commentSymbol: string; 11 | toolchainContext: string; 12 | input?: string; 13 | output?: string; 14 | spec?: string; 15 | similarChunk?: string; 16 | } 17 | -------------------------------------------------------------------------------- /src/prompt-manage/custom-action/CustomActionType.ts: -------------------------------------------------------------------------------- 1 | export enum CustomActionType { 2 | Default, 3 | QuickAction, 4 | } 5 | -------------------------------------------------------------------------------- /src/prompt-manage/executor/FileGenerateTask.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'node:fs'; 2 | import * as path from 'node:path'; 3 | 4 | import * as vscode from 'vscode'; 5 | 6 | import { StreamingMarkdownCodeBlock } from 'base/common/markdown/StreamingMarkdownCodeBlock'; 7 | 8 | export class FileGenerateTask { 9 | constructor( 10 | private readonly project: vscode.WorkspaceFolder, 11 | private readonly outputText: string, 12 | private readonly fileName: string | undefined = undefined, 13 | ) {} 14 | 15 | public async run() { 16 | let parsedCode = StreamingMarkdownCodeBlock.parse(this.outputText); 17 | const inferFileName = 18 | this.fileName === undefined 19 | ? 'output-' + Date.now() + (parsedCode.language === '' ? '.txt' : '.' + parsedCode.language) 20 | : this.fileName; 21 | 22 | const filePath = path.resolve(this.project.uri.fsPath, inferFileName); 23 | await fs.promises.writeFile(filePath, this.outputText); 24 | 25 | await this.refreshAndOpenInEditor(filePath); 26 | } 27 | 28 | private async refreshAndOpenInEditor(filePath: string) { 29 | try { 30 | const doc = await vscode.workspace.openTextDocument(filePath); 31 | await vscode.window.showTextDocument(doc); 32 | } catch (error) { 33 | console.error('Error opening file:', error); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/prompt-manage/loader/TemplateLoader.ts: -------------------------------------------------------------------------------- 1 | export abstract class TemplateLoader { 2 | async load(name: string): Promise { 3 | return Promise.reject(new Error('Method not implemented.')); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/prompt-manage/loader/VSCodeTemplateLoader.ts: -------------------------------------------------------------------------------- 1 | import { Uri } from 'vscode'; 2 | 3 | import { TemplateLoader } from './TemplateLoader'; 4 | 5 | export class VSCodeTemplateLoader extends TemplateLoader { 6 | constructor(private extensionUri: Uri) { 7 | super(); 8 | } 9 | 10 | async load(filepath: string): Promise { 11 | if (!this.extensionUri) { 12 | throw new Error('Extension URI is not defined'); 13 | } 14 | 15 | const templateUri = Uri.joinPath(this.extensionUri, filepath); 16 | return await this.readFile(templateUri.fsPath); 17 | } 18 | 19 | private async readFile(filepath: string): Promise { 20 | const fs = require('fs'); 21 | return new Promise((resolve, reject) => 22 | fs.readFile(filepath, 'utf8', (err: any, data: any) => { 23 | if (err) { 24 | reject(err); 25 | } else { 26 | resolve(data); 27 | } 28 | }), 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/prompt-manage/prompts-override/PromptOverrider.ts: -------------------------------------------------------------------------------- 1 | export class PromptOverrider {} 2 | -------------------------------------------------------------------------------- /src/prompt-manage/team-prompts/TeamPromptAction.ts: -------------------------------------------------------------------------------- 1 | import { CustomActionPrompt } from '../custom-action/CustomActionPrompt'; 2 | 3 | export interface TeamPromptAction { 4 | actionName: string; 5 | actionPrompt: CustomActionPrompt; 6 | } 7 | -------------------------------------------------------------------------------- /src/prompt-manage/template/TemplateContext.ts: -------------------------------------------------------------------------------- 1 | export interface TemplateContext { 2 | language: string; 3 | chatContext?: string; 4 | } 5 | 6 | class EmptyContext implements TemplateContext { 7 | language: string = ''; 8 | chatContext?: string | undefined; 9 | } 10 | -------------------------------------------------------------------------------- /src/service/Service.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Service interface for all services. 3 | */ 4 | export interface Service {} 5 | -------------------------------------------------------------------------------- /src/test/ScopeTestUtil.ts: -------------------------------------------------------------------------------- 1 | import { LanguageProfileUtil } from '../code-context/_base/LanguageProfile'; 2 | import { TreeSitterFile } from '../code-context/ast/TreeSitterFile'; 3 | 4 | export async function testScopes(langId: string, src: string, expected: string, tsfFile: TreeSitterFile) { 5 | const graph = await tsfFile.scopeGraph(); 6 | const language = LanguageProfileUtil.from(langId)!!; 7 | const observed = graph.debug(src, language); 8 | return observed.toString(); 9 | } 10 | 11 | export async function printScopeGraph(langId: string, src: string, tsfFile: TreeSitterFile) { 12 | const graph = await tsfFile.scopeGraph(); 13 | const language = LanguageProfileUtil.from(langId)!!; 14 | console.log(graph.debug(src, language).toString()); 15 | } 16 | -------------------------------------------------------------------------------- /src/test/TestUtil.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | 3 | export const ROOT_DIR = path.join(__dirname, '..', '..'); 4 | -------------------------------------------------------------------------------- /src/test/codesearch/LinePartitionChunker.test.ts: -------------------------------------------------------------------------------- 1 | import { ChunkWithoutID } from '../../code-search/chunk/_base/Chunk'; 2 | import { LinePartitionChunker } from '../../code-search/chunk/LinePartitionChunker'; 3 | 4 | describe('LinePartitionChunker', () => { 5 | let chunker: LinePartitionChunker; 6 | 7 | beforeEach(() => { 8 | chunker = new LinePartitionChunker(); 9 | }); 10 | 11 | describe('chunk', () => { 12 | it('should return 2 chunks when return 3 lines', async () => { 13 | const filepath = 'test.txt'; 14 | const contents = 'This is a test content for the LinePartitionChunker class.\nLine 2\nLine3'; 15 | const maxChunkSize = 2; 16 | 17 | const chunks: ChunkWithoutID[] = []; 18 | let chunkWithoutIDS = chunker.chunk(filepath, contents, maxChunkSize); 19 | for await (const chunk of chunkWithoutIDS) { 20 | chunks.push(chunk); 21 | } 22 | 23 | expect(chunks.length).equal(2); 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/test/codesearch/LocalInference.test.ts: -------------------------------------------------------------------------------- 1 | describe('LocalInference', () => { 2 | it.skip('should encoding', async () => { 3 | // 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /src/test/codesearch/MarkdownChunker.test.ts: -------------------------------------------------------------------------------- 1 | import { MarkdownChunker } from '../../code-search/chunk/MarkdownChunker'; 2 | 3 | describe('MarkdownChunker', () => { 4 | let markdownChunker: MarkdownChunker; 5 | 6 | beforeEach(() => { 7 | markdownChunker = new MarkdownChunker(); 8 | }); 9 | 10 | describe('markdownChunker', () => { 11 | it('should return a chunk of the content', async () => { 12 | const content = '# Header\nThis is some content.'; 13 | const chunks = markdownChunker.markdownChunker(content, 10, 1); 14 | const result = []; 15 | for await (const chunk of chunks) { 16 | result.push(chunk); 17 | } 18 | expect(result).to.have.length(1); 19 | expect(result[0].content).to.equal(content); 20 | expect(result[0].startLine).to.equal(0); 21 | expect(result[0].endLine).to.equal(2); 22 | }); 23 | }); 24 | 25 | describe('findHeader', () => { 26 | it('should return the header of the content', () => { 27 | const lines = ['# Header', 'This is some content.']; 28 | const header = markdownChunker.findHeader(lines); 29 | expect(header).to.equal('Header'); 30 | }); 31 | 32 | it('should return undefined if no header is found', () => { 33 | const lines = ['This is some content.']; 34 | const header = markdownChunker.findHeader(lines); 35 | expect(header).to.be.undefined; 36 | }); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /src/test/codesearch/TransformersEmbeddingProvider.test.ts: -------------------------------------------------------------------------------- 1 | describe('TransformersEmbeddingProvider', () => { 2 | it.skip('should chunk for hello, world', async () => {}); 3 | }); 4 | -------------------------------------------------------------------------------- /src/test/codesearch/strategy/RankedKeywords.test.ts: -------------------------------------------------------------------------------- 1 | import { HydeKeywords } from '../../../code-search/search-strategy/_base/HydeKeywords'; 2 | 3 | describe('RankedKeywords', () => { 4 | it('should parse keywords correctly', () => { 5 | const content = ` 6 | Where is calculating the average of a list of numbers? 7 | 8 | - calculate average, average, average calculation 9 | - calculate, average 10 | - jisuan, pingjunshu, pingjun 11 | `; 12 | 13 | const expected: HydeKeywords = { 14 | question: 'Where is calculating the average of a list of numbers?', 15 | basic: ['calculate average', 'average', 'average calculation'], 16 | single: ['calculate', 'average'], 17 | localization: ['jisuan', 'pingjunshu', 'pingjun'], 18 | }; 19 | 20 | const result = HydeKeywords.from(content); 21 | expect(result).to.deep.equal(expected); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /src/test/language/go/GoBuildToolProvider.test.ts: -------------------------------------------------------------------------------- 1 | import { goVersionParser } from '../../../toolchain-context/buildtool/go/GoVersionParser'; 2 | 3 | describe('GoSupport', () => { 4 | describe('goVersionParser', () => { 5 | it('should return the correct version when the input string is valid', () => { 6 | const stdout = 'go version go1.21.1 darwin/amd64'; 7 | const result = goVersionParser(stdout); 8 | expect(result).to.equal('1.21.1'); 9 | }); 10 | 11 | it('should return an empty string when the input string does not contain a version', () => { 12 | const stdout = 'go version darwin/amd64'; 13 | const result = goVersionParser(stdout); 14 | expect(result).to.equal(''); 15 | }); 16 | 17 | it('should return an empty string when the input string is empty', () => { 18 | const stdout = ''; 19 | const result = goVersionParser(stdout); 20 | expect(result).to.equal(''); 21 | }); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /src/test/language/java/tooling/GradleInfo.test.ts: -------------------------------------------------------------------------------- 1 | import { parseGradleVersionInfo } from '../../../../toolchain-context/buildtool/gradle/GradleVersionInfo'; 2 | 3 | describe('parseGradleInfo', () => { 4 | it('should parse gradle info correctly', () => { 5 | const gradleInfoString = ` 6 | --------------------------------------------------------- 7 | Gradle 8.3 8 | --------------------------------------------------------- 9 | 10 | Build time: 2023-08-17 07:06:47 UTC 11 | Revision: 8afbf24b469158b714b36e84c6f4d4976c86fcd5 12 | 13 | Kotlin: 1.9.0 14 | Groovy: 3.0.17 15 | Ant: Apache Ant(TM) version 1.10.13 compiled on January 4 2023 16 | JVM: 21.0.2 (Homebrew 21.0.2) 17 | OS: Mac OS X 14.4.1 x86_64 18 | `; 19 | 20 | const expectedGradleInfo = { 21 | gradleVersion: '8.3', 22 | buildTime: '2023-08-17 07:06:47 UTC', 23 | revision: '8afbf24b469158b714b36e84c6f4d4976c86fcd5', 24 | kotlinVersion: '1.9.0', 25 | groovyVersion: '3.0.17', 26 | antVersion: 'Apache Ant(TM) version 1.10.13 compiled on January 4 2023', 27 | jvmVersion: '21.0.2 (Homebrew 21.0.2)', 28 | os: 'Mac OS X 14.4.1 x86_64', 29 | }; 30 | 31 | const actualGradleInfo = parseGradleVersionInfo(gradleInfoString); 32 | 33 | expect(actualGradleInfo).to.deep.equal(expectedGradleInfo); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /src/test/language/kotlin/KotlinStructure.test.ts: -------------------------------------------------------------------------------- 1 | import { TestLanguageServiceProvider } from "src/test/TestLanguageService"; 2 | import { KotlinStructurerProvider } from "../../../code-context/kotlin/KotlinStructurerProvider"; 3 | 4 | const Parser = require('web-tree-sitter'); 5 | 6 | describe('KotlinStructure', () => { 7 | it('should convert a simple file to CodeFile', async () => { 8 | const kotlinHelloWorld = `package com.example 9 | interface Shape { 10 | val vertexCount: Int 11 | } 12 | 13 | class Rectangle(override val vertexCount: Int = 4) : Shape // Always has 4 vertices 14 | 15 | class Polygon : Shape { 16 | override var vertexCount: Int = 0 // Can be set to any number later 17 | }`; 18 | 19 | await Parser.init(); 20 | const parser = new Parser(); 21 | const languageService = new TestLanguageServiceProvider(parser); 22 | 23 | const structurer = new KotlinStructurerProvider(); 24 | await structurer.init(languageService); 25 | 26 | const codeFile = await structurer.parseFile(kotlinHelloWorld, ''); 27 | console.log(codeFile); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /src/toolchain-context/ToolchainContextManager.ts: -------------------------------------------------------------------------------- 1 | import { ToolchainContextItem, CreateToolchainContext } from "./ToolchainContextProvider"; 2 | import { providerContainer } from "../ProviderContainer.config"; 3 | import { IToolchainContextProvider } from "src/ProviderTypes"; 4 | 5 | export class ToolchainContextManager { 6 | async collectContextItems(context: CreateToolchainContext): Promise { 7 | let map: Promise[] = providerContainer.getAll(IToolchainContextProvider) 8 | .map(async (provider) => { 9 | try { 10 | if (await provider?.isApplicable(context)) { 11 | return await provider?.collect(context); 12 | } else { 13 | return []; 14 | } 15 | } catch (e) { 16 | console.error("Error collecting context items", e); 17 | return []; 18 | } 19 | }); 20 | 21 | try { 22 | let results = await Promise.all(map); 23 | return results.reduce((acc, val) => acc.concat(val), []); 24 | } catch (e) { 25 | console.error("Error collecting context items", e); 26 | return []; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/toolchain-context/ToolchainContextProvider.ts: -------------------------------------------------------------------------------- 1 | import { NamedElement } from "../editor/ast/NamedElement"; 2 | import { ScopeGraph } from "../code-search/scope-graph/ScopeGraph"; 3 | 4 | export interface ToolchainContextItem { 5 | /// for recording and debugging 6 | clazz: string; 7 | text: string; 8 | } 9 | 10 | export interface CreateToolchainContext { 11 | action: string; 12 | language: string; 13 | filename: string; 14 | content: string; 15 | element?: NamedElement; 16 | graph?: ScopeGraph; 17 | extraItems?: ToolchainContextItem[]; 18 | } 19 | 20 | export interface ToolchainContextProvider { 21 | isApplicable(context: CreateToolchainContext): Promise 22 | 23 | collect(context: CreateToolchainContext): Promise 24 | } 25 | -------------------------------------------------------------------------------- /src/toolchain-context/buildtool/_base/BaseBuildToolProvider.ts: -------------------------------------------------------------------------------- 1 | import { BuildToolProvider } from "./BuildToolProvider"; 2 | import { PackageDependencies } from "./Dependence"; 3 | import vscode from "vscode"; 4 | import { CreateToolchainContext } from "../../ToolchainContextProvider"; 5 | import path from "path"; 6 | import fs from "fs"; 7 | 8 | export abstract class BaseBuildToolProvider implements BuildToolProvider { 9 | moduleTarget: string[] = []; 10 | 11 | abstract getToolingName(): string; 12 | 13 | abstract getToolingVersion(): Promise; 14 | 15 | abstract getDependencies(): Promise; 16 | 17 | abstract getTasks(): Promise; 18 | 19 | async isApplicable(context?: CreateToolchainContext): Promise { 20 | const workspaces = vscode.workspace.workspaceFolders || []; 21 | const workspace = workspaces[0]; 22 | 23 | let hasTarget = false; 24 | for (const target of this.moduleTarget) { 25 | const targetPath = path.join(workspace.uri.fsPath, target); 26 | if (fs.existsSync(targetPath)) { 27 | hasTarget = true; 28 | } 29 | } 30 | 31 | return hasTarget; 32 | } 33 | 34 | async getTargetContent(target: string): Promise { 35 | let workspaces = vscode.workspace.workspaceFolders || []; 36 | const workspace = workspaces[0]; 37 | 38 | const targetPath = path.join(workspace!!.uri.fsPath, target); 39 | return fs.readFileSync(targetPath, "utf-8"); 40 | } 41 | } -------------------------------------------------------------------------------- /src/toolchain-context/buildtool/_base/BuildToolProvider.ts: -------------------------------------------------------------------------------- 1 | import { PackageDependencies } from "./Dependence"; 2 | 3 | /** 4 | * The `Tooling` interface defines a set of methods for buildtool-related operations. 5 | * 6 | * @interface BuildToolProvider 7 | * @property {string} getToolingName - Returns the name of the buildtool. 8 | * @property {string} getToolingVersion - Returns the version of the buildtool. 9 | * @property {PackageDependencies} getDependencies - Returns an object representing the buildtool's dependencies. 10 | */ 11 | export interface BuildToolProvider { 12 | moduleTarget: string[]; 13 | 14 | /** 15 | * Returns the name of the buildtool. 16 | */ 17 | getToolingName(): string; 18 | 19 | /** 20 | * Returns the version of the buildtool. 21 | */ 22 | getToolingVersion(): Promise 23 | 24 | /** 25 | * Returns an object representing the buildtool's dependencies. 26 | */ 27 | getDependencies(): Promise; 28 | 29 | /** 30 | * Searches for dependencies in the buildtool. 31 | */ 32 | getTasks(): Promise; 33 | } -------------------------------------------------------------------------------- /src/toolchain-context/buildtool/_base/DependencyInspector.ts: -------------------------------------------------------------------------------- 1 | import { PackageDependencies } from "./Dependence"; 2 | 3 | export interface DependencyInspector { 4 | parseDependency(content: string): PackageDependencies[]; 5 | } 6 | -------------------------------------------------------------------------------- /src/toolchain-context/buildtool/_base/PackageManger.ts: -------------------------------------------------------------------------------- 1 | export enum PackageManger { 2 | MAVEN = "maven", 3 | GRADLE = "gradle", 4 | GoMod = "go_mod", 5 | NPM = "npm", 6 | YARN = "yarn", 7 | } -------------------------------------------------------------------------------- /src/toolchain-context/buildtool/go/GoVersionParser.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Parse the version info from `go version` command. 3 | * @param stdout e.g. `go version go1.21.1 darwin/amd64` 4 | * @returns the version of the Go tooling, e.g. `1.21.1` 5 | */ 6 | export function goVersionParser(stdout: string) { 7 | const versionRegex = /go version go(\d+\.\d+\.\d+)/; 8 | const match = versionRegex.exec(stdout); 9 | if (match) { 10 | return match[1]; 11 | } 12 | return ""; 13 | } 14 | -------------------------------------------------------------------------------- /src/toolchain-context/framework/cpp/CppFramework.ts: -------------------------------------------------------------------------------- 1 | export enum CppFrameworks { 2 | Boost = "Boost", 3 | ETL = "ETL", 4 | QT = "QT" 5 | } 6 | 7 | export enum CppTestFrameworks { 8 | GoogleTest = "GoogleTest", 9 | Catch2 = "Catch2", 10 | GoogleMock = "GoogleMock" 11 | } 12 | 13 | export const CPP_PACKAGE: string = "cpp"; 14 | 15 | export const MOST_POPULAR_CPP_PACKAGES: Set = new Set([ 16 | "opencv", 17 | "boost", 18 | "protobuf", 19 | "gmock", 20 | "gtest", 21 | "asio", 22 | "cpprestsdk", 23 | "fmt", 24 | "rapidjson", 25 | "spdlog", 26 | "nlohmann/json", 27 | "mysqlcppconn", 28 | "sqlite3", 29 | "websocketpp", 30 | "zeromq", 31 | "cppzmq", 32 | "sdl2", 33 | "gtkmm", 34 | "wxwidgets", 35 | "fltk", 36 | "qt", 37 | "poco", 38 | "thrift", 39 | "grpc", 40 | "mongodb", 41 | "redis-plus-plus", 42 | "cpp_redis", 43 | "postgresql", 44 | "cpp-netlib", 45 | "cpprestsdk", 46 | "crow", 47 | "pistache" 48 | ]); 49 | -------------------------------------------------------------------------------- /src/toolchain-context/framework/go/GoFrameworks.ts: -------------------------------------------------------------------------------- 1 | export enum GoFrameworks { 2 | Gin = "gin" 3 | } 4 | 5 | export enum GoTestFrameworks { 6 | GoTest = "go_test", 7 | GoMock = "go_mock" 8 | } -------------------------------------------------------------------------------- /src/toolchain-context/framework/javascript/utils/JavaScriptUtils.ts: -------------------------------------------------------------------------------- 1 | import { CreateToolchainContext } from "../../../ToolchainContextProvider"; 2 | 3 | export function applyJavaScript(context: CreateToolchainContext) { 4 | return context.language === "javascript" || context.language === "typescript" || context.language === "javascriptreact" || context.language === "typescriptreact"; 5 | } 6 | -------------------------------------------------------------------------------- /src/toolchain-context/framework/jvm/TechStack.ts: -------------------------------------------------------------------------------- 1 | export class TechStack { 2 | coreFrameworks: Map; 3 | testFrameworks: Map; 4 | deps: Map; 5 | devDeps: Map; 6 | 7 | constructor( 8 | coreFrameworks: Map = new Map(), 9 | testFrameworks: Map = new Map(), 10 | deps: Map = new Map(), 11 | devDeps: Map = new Map() 12 | ) { 13 | this.coreFrameworks = coreFrameworks; 14 | this.testFrameworks = testFrameworks; 15 | this.deps = deps; 16 | this.devDeps = devDeps; 17 | } 18 | 19 | coreFrameworksList(): string { 20 | return Array.from(this.coreFrameworks.keys()).join(", "); 21 | } 22 | 23 | testFrameworksList(): string { 24 | return Array.from(this.testFrameworks.keys()).join(", "); 25 | } 26 | } -------------------------------------------------------------------------------- /src/toolchain-context/version/JavaVersionProvider.ts: -------------------------------------------------------------------------------- 1 | import { injectable } from "inversify"; 2 | 3 | import { ToolchainContextItem, ToolchainContextProvider, CreateToolchainContext } from "../ToolchainContextProvider"; 4 | import { GradleBuildToolProvider } from "../buildtool/GradleBuildToolProvider"; 5 | 6 | @injectable() 7 | export class JavaVersionProvider implements ToolchainContextProvider { 8 | private clazzName = this.constructor.name; 9 | 10 | async isApplicable(context: CreateToolchainContext): Promise { 11 | return context.language === "java" && GradleBuildToolProvider.instance().isApplicable(context); 12 | } 13 | 14 | async collect(context: CreateToolchainContext): Promise { 15 | let gradleInfo; 16 | try { 17 | gradleInfo = await GradleBuildToolProvider.instance().getGradleVersion(); 18 | } catch (e) { 19 | console.info(e); 20 | return []; 21 | } 22 | 23 | if (gradleInfo) { 24 | return [ 25 | { 26 | clazz: this.clazzName, 27 | text: `You are using Java SDK version ${gradleInfo.jvmVersion}.` 28 | } 29 | ]; 30 | } 31 | 32 | return []; 33 | } 34 | } -------------------------------------------------------------------------------- /tests/vitest.setup.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext", "ES2021"], 6 | "module": "NodeNext", 7 | "skipLibCheck": true, 8 | "types": ["vite/client", "vitest/globals", "reflect-metadata"], 9 | 10 | /* Module paths alias */ 11 | "baseUrl": ".", 12 | "paths": { 13 | "base/*": ["src/base/*"] 14 | }, 15 | 16 | /* ioc */ 17 | "experimentalDecorators": true, 18 | "emitDecoratorMetadata": true, 19 | 20 | /* Bundler mode */ 21 | "moduleResolution": "NodeNext", 22 | "esModuleInterop": true, 23 | "forceConsistentCasingInFileNames": true, 24 | "resolveJsonModule": true, 25 | "isolatedModules": true, 26 | "noEmit": true, 27 | "jsx": "react-jsx", 28 | 29 | /* Linting */ 30 | "strict": true, 31 | "noUnusedLocals": false, 32 | "noUnusedParameters": false, 33 | "noFallthroughCasesInSwitch": true 34 | }, 35 | "include": ["src"], 36 | "exclude": ["node_modules"], 37 | "references": [{ "path": "./tsconfig.node.json" }] 38 | } 39 | -------------------------------------------------------------------------------- /tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "NodeNext", 6 | "moduleResolution": "NodeNext", 7 | "forceConsistentCasingInFileNames": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true 10 | }, 11 | "include": ["vite.config.mts"] 12 | } 13 | -------------------------------------------------------------------------------- /vendors/bindings/LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2012 Nathan Rajlich <nathan@tootallnate.net> 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /vendors/onnxruntime-node/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /vendors/onnxruntime-node/binding.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // Licensed under the MIT License. 4 | // export native binding 5 | exports.binding = 6 | // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires 7 | require(`./bin/napi-v3/${process.platform}/${process.arch}/onnxruntime_binding.node`); -------------------------------------------------------------------------------- /vendors/onnxruntime-node/version.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // Copyright (c) Microsoft Corporation. All rights reserved. 3 | // Licensed under the MIT License. 4 | Object.defineProperty(exports, "__esModule", { value: true }); 5 | exports.version = void 0; 6 | // This file is generated by /js/scripts/update-version.ts 7 | // Do not modify file content manually. 8 | exports.version = '1.17.3-rev.1'; --------------------------------------------------------------------------------