从零开发一款ChatGPT VSCode插件

‍本文作者是360奇舞团开发工程师

引言

OpenAI发布了ChatGPT,就像是给平静许久的互联网湖面上扔了一颗重磅炸弹,刹那间所有人都在追捧学习它。究其原因,它其实是一款真正意义上的人工智能对话机器人。它使用了深度学习技术,通过大量的训练数据和自监督学习方法进行训练,以模拟人类的对话能力和生成自然语言回应。日常生产、学习中利用好ChatGPT这个工具,是绝对能够提升我们工作效率的,这一点对于我们程序员来说,感受应该尤为明显。我们最常用的开发工具VSCode,已经有许多的插件集成了ChatGPT功能,这篇文章将从零开始,介绍这些插件的实现原理与思路,希望对你有所帮助。

基本需求

实现一款可以跟ChatGPT对话的插件,可以通过一问一答的形式来进行对话,并且可以将我们选中的代码发送给ChatGPT,让其可以对代码进行优化。当然如果要访问ChatGPT,首先需要绑定我们在OpenAI后台申请的ApiKey.

VSCode 插件基本配置

首先简单介绍一下VSCode插件开发的基本流程

  1. 安装脚手架

npm install -g yo generator-code

然后cd到你的工作目录,运行yo code,根据向导一步步选择即可,没啥好说的,运行完后就生成了一个干净的可以运行的插件工程了。
2. 工程目录介绍
00e34aacf33fd3c83989ef4da7c983d4.png
查看当前目录,工程的核心是package.jsonextension.js.首先看下package.json的配置文件:

  • name:工程名称

  • displayName: 应用市场名称

  • description: 应用描述

  • version: 当前插件版本

  • engines: 表示插件最低支持的vscode版本

  • categories: 插件应用市场分类

  • main: 程序的主入口文件

  • activationEvents:重要,扩展的激活事件数组,表示可以被哪些事件激活当前插件。比如:

"activationEvents": ["onView:chatgpt-for-vscode.view","onCommand:chatgpt-for-vscode.setAPIKey","onCommand:chatgpt-for-vscode.askGPT","onCommand:chatgpt-for-vscode.whyBroken","onCommand:chatgpt-for-vscode.optimizeCode","onCommand:chatgpt-for-vscode.explainCode","onCommand:chatgpt-for-vscode.refactor"],

onView:表示 通过视图触发,chatgpt-for-vscode.view是视图Id。当触发这个视图时,唤起当前插件
onCommand: 表示通过命令触发,后面是命令Id,这些都是我们自定义的命令。在VSCode中按下快捷键:Command + Shift + P 输入命令title后唤起插件,命令titlecontributes,commands模块里面定义,后面介绍。
除了这两个还有:onLanguageonUrionDebugworkspaceContainsonFileSystem等,如果设置为*,只要一启动VSCode,插件就会被激活,当然为了用户体验,官方不推荐这么做。

  • contributes重要,配置插件的主要功能点。比如:

"contributes": {"commands": [{"command": "chatgpt-for-vscode.setAPIKey","title": "GPT:绑定APIKey"},{"command": "chatgpt-for-vscode.askGPT","title": "GPT:询问 GPT"},{"command": "chatgpt-for-vscode.whyBroken","title": "GPT:说明这段代码存在的问题"},{"command": "chatgpt-for-vscode.optimizeCode","title": "GPT:优化这段代码"},{"command": "chatgpt-for-vscode.explainCode","title": "GPT:解释这段代码"},{"command": "chatgpt-for-vscode.refactor","title": "GPT:重构这段代码"}],"menus": {"editor/context": [{"command": "chatgpt-for-vscode.askGPT","group": "navigation@1"},{"command": "chatgpt-for-vscode.whyBroken","group": "navigation@2"},{"command": "chatgpt-for-vscode.optimizeCode","group": "navigation@3"},{"command": "chatgpt-for-vscode.explainCode","group": "navigation@4"},{"command": "chatgpt-for-vscode.refactor","group": "navigation@5"},{"command": "chatgpt-for-vscode.setAPIKey","group": "navigation@6"}]},"viewsContainers": {"activitybar": [{"id": "chatgpt-for-vscode","title": "ChatGPT","icon": "images/ChatGPT.png"}]},"views": {"chatgpt-for-vscode": [{"type": "webview","id": "chatgpt-for-vscode.view","name": "ChatGPT"}]}},
  • commands: command: 命令Id,这个命令Id跟activationEvents中配置的命令Id相同。title:输入的命令的名称。Command + Shift + P 输入这个命令title后找到对应的命令。
    5a0dd3b4eb2fa81ee18437cdea7ce53e.png

  • menus: editor/context:配置编辑器右键展示内容。command是命令Id,group:右键后展示看板的命令位置。这里navigation表示展示在模块的顶部。@*表示排序。
    63296978ac27341e39004dbb2c055ba2.png

  • viewsContainersactivitybar:配置右侧工具栏视图入口,配置后展示,注意这里的id,要跟后面的
    views模块里面的视图key值保持一致,表示点击右侧icon后展示那个视图,icon是你本地的图片路径。
    5d098dccf315705f424fd93bd4a5f889.png

  • views: 配置视图,这里使用webview展示自定义视图

  1. 配置完成package.json后右键命令展示,左侧状态栏Icon,顶部命令行选择输入命令,已经可以展示了。运行npm run test 后会打开默认安装你插件的VSCode面板,接下来就是完善触发命令后的代码逻辑了,核心在extension.ts中实现。

extension.ts模块开发

extension.ts 是程序的入口文件,里面有两个核心方法:

export function activate(context: vscode.ExtensionContext) {}
export function deactivate() {}

看字面意思很好理解,分别表示插件被激活与释放调用的生命周期方法.

1. 绑定APIKey命令逻辑

要想使用OpenAI的api,首先需要将自己的ApiKey与插件进行关联。这里使用VSCode自有APIvscode.window.showInputBox来获取用户输入.

this.apiKey = await this.context.globalState.get('chatgpt-api-key');if (!this.apiKey) {const apiKeyInput = await vscode.window.showInputBox({prompt: "请输入你的API Key",ignoreFocusOut: true,});this.apiKey = apiKeyInput;this.context.globalState.update('chatgpt-api-key', this.apiKey);}
  • 使用上下文的globalState来持久化保存ApiKey

  • 如果要让这个命令生效,需要在activate中进行注册

context.subscriptions.push(vscode.commands.registerCommand('chatgpt-for-vscode.setAPIKey', resetToken))async function resetToken() {await vscode.window.showInputBox({prompt: "请输入OpenAI API Key",ignoreFocusOut: true,});
}

执行command + shift + p 输入命令titleGPT:绑定APIKey后,展示效果如下:ff345131e0e3cdfa7e9044ec116346ec.png
这样就完成了对用户ApiKey的绑定逻辑.

2. 命令触发逻辑

与绑定用户ApiKey类似,其他命令的执行也是同样的流程,这里以onCommand:chatgpt-for-vscode.askGPT命令来说明:

// 注册命令
vscode.commands.registerCommand('chatgpt-for-vscode.askGPT', askChatGPT)
// 命令实现
async function askChatGPT(userInput: string) {let editor = vscode.window.activeTextEditor;if (editor) {const selectedCode = editor.document.getText(vscode.window.activeTextEditor?.selection);if(selectedCode.length) {chatViewProvider.sendOpenAiApiRequest(userInput, selectedCode);vscode.window.showInformationMessage(selectedCode);}else {vscode.window.showInformationMessage(`请选中一段代码`);}}
}
  • 注册命令后 使用editor.document.getText(vscode.window.activeTextEditor?.selection)来获取选中的代码段落,并判空.

  • 利用chatViewProvider.sendOpenAiApiRequest(userInput, selectedCode);利用这个方法用户输入的Prompt
    与选中的代码端传递出去,这个方法的实现后面介绍,注册所有的命令后,activate方法是这样的

export function activate(context: vscode.ExtensionContext) {const chatViewProvider = new view_provider.default(context);context.subscriptions.push(vscode.commands.registerCommand('chatgpt-for-vscode.askGPT', askChatGPT), vscode.commands.registerCommand('chatgpt-for-vscode.whyBroken', askGPTWhyBroken), vscode.commands.registerCommand('chatgpt-for-vscode.explainCode', askGPTToExplain), vscode.commands.registerCommand('chatgpt-for-vscode.refactor', askGPTToRefactor), vscode.commands.registerCommand('chatgpt-for-vscode.optimizeCode', askGPTToOptimize), vscode.commands.registerCommand('chatgpt-for-vscode.setAPIKey', resetToken), vscode.window.registerWebviewViewProvider("chatgpt-for-vscode.view", chatViewProvider, {webviewOptions: { retainContextWhenHidden: true }}));async function askGPTWhyBroken() { await askChatGPT('说明下面的代码会出现什么问题?'); }async function askGPTToExplain() { await askChatGPT('请帮我解释一下下面的代码?'); }async function askGPTToRefactor() { await askChatGPT('帮我重构下面的代码'); }async function askGPTToOptimize() { await askChatGPT('帮我优化下面的代码'); }async function resetToken() {await chatViewProvider.ensureApiKey();}async function askChatGPT(userInput: string) {let editor = vscode.window.activeTextEditor;if (editor) {const selectedCode = editor.document.getText(vscode.window.activeTextEditor?.selection);if(selectedCode.length) {chatViewProvider.sendOpenAiApiRequest(userInput, selectedCode);vscode.window.showInformationMessage(selectedCode);}else {vscode.window.showInformationMessage(`请选中一段代码`);}}}
}
3.webView与chatViewProvider

上面的代码除了注册命令的APIregisterCommand,还有一个注册自定义webview视图的API,registerWebviewViewProvider,作用是展示我们自定义的webview,它有三个参数:

  • chatgpt-for-vscode.view是视图Id,跟package.jsonviews模块对应的Id相同,表示为那个视图Id注册provider.

  • chatViewProvider 视图提供者.

  • 第三个参数:webview的属性配置,retainContextWhenHidden: true表示:webview被隐藏时保持状态,避免被重置.
    接下来重点来看chatViewProvider:
    作为自定义视图的provider首先需要继承vscode.WebviewViewProvider这个接口

export interface WebviewViewProvider {/*** Revolves a webview view.** `resolveWebviewView` is called when a view first becomes visible. This may happen when the view is* first loaded or when the user hides and then shows a view again.** @param webviewView Webview view to restore. The provider should take ownership of this view. The*    provider must set the webview's `.html` and hook up all webview events it is interested in.* @param context Additional metadata about the view being resolved.* @param token Cancellation token indicating that the view being provided is no longer needed.** @return Optional thenable indicating that the view has been fully resolved.*/resolveWebviewView(webviewView: WebviewView, context: WebviewViewResolveContext, token: CancellationToken): Thenable<void> | void;}

这个接口只有一个方法,resolveWebviewView在视图首次可见时被调用。这可能发生在视图第一次加载时,或者当用户隐藏然后再次显示视图时。在这个方面里面设置webviewhtml与视图属性。

export default class ChatGptViewProvider implements vscode.WebviewViewProvider {private webView?: vscode.WebviewView;private apiKey?: string;private message?: any;constructor(private context: vscode.ExtensionContext) { }public resolveWebviewView(webviewView: vscode.WebviewView,_context: vscode.WebviewViewResolveContext,_token: vscode.CancellationToken,) {this.webView = webviewView;// webview属性设置webviewView.webview.options = {enableScripts: true,localResourceRoots: [this.context.extensionUri]};// 返回Html代码webviewView.webview.html = this.getHtml(webviewView.webview);// 接收webviewView.webview.onDidReceiveMessage(data => {if (data.type === 'askChatGPT') {this.sendOpenAiApiRequest(data.value);}});if (this.message !== null) {this.sendMessageToWebView(this.message);this.message = null;}}
}
4. 通信机制

自定义的webview和普通网页非常类似,都不能直接调用任何VSCodeAPI,但是,它唯一特别之处就在于多了一个名叫acquireVsCodeApi的方法,执行这个方法会返回一个超级阉割版的vscode对象.利用这个对象,可以实现webview与插件也就是provider的通信。

  • providerwebview发送消息:

this.webView?.webview.postMessage(message);
  • webview端接收消息:

window.addEventListener('message', event => {const message = event.data;console.log('Webview接收到的消息:', message);
}
  • webview主动发送消息给provider

const vscode = acquireVsCodeApi();
vscode.postMessage({text: '你好,我是Webview啊!'});
  • provider接收消息:

this.webView?.webview.onDidReceiveMessage(data => {if (data.type === 'askChatGPT') {this.sendOpenAiApiRequest(data.value);}
});

了解完双方的通信机制后,基本逻辑是:当点击webview上的发送按钮后,将用户输入发送给ChatGPTChatGPT处理完成后将返回信息发送给webviewwebview将回答信息展示出来,完成一次对话逻辑。

// 按钮绑定点击事件
document.getElementById("ask-button")?.addEventListener("click", submitHandler);
let submitHandler = function (e) {e.preventDefault();e.stopPropagation();const input = document.getElementById("question-input");if (input.value?.length > 0) {// 发送消息给 插件,使其完成ChatGPT请求vscode.postMessage({type: "askChatGPT",value: input.value,});input.value = "";}
};
5. 调用OPenAI接口

要想完成一次对话,需要调用OPenAI的API.具体的API你可以在官网找到:
79fc4a14332a9c9460f7edb57d51c37a.png

  • 参数model是你要对话的ChatGPT模型代码,不同模型针对同一个问题的答案会有所区别。具体模块区别可以参考下面图片:
    6827c009aafd1d484a03c8851f20b8f9.png
    更多模型可以点击这里去查看

  • 参数messages: 你的问题信息

  • 参数temperature: 它是一个用于控制生成文本的创造性的参数,其值介于0到2之间。值为1意味着模型将使用其默认采样策略,而值低于1.0将导致更保守和可预测的响应,值大于1.0将导致更有创造性和多样化的响应。

  • 参数max_tokens: 生成对话的最大token数量。这里的token可以理解为模型的构建块。了解完成上面的参数,可以利用fetch发起请求了:

let completion =  await fetch('https://api.openai.com/v1/chat/completions', {method: 'POST',body: JSON.stringify({model: "text-davinci-003",messages: [{ role: "user", content: question }],temperature: 0.7}),headers: {// eslint-disable-next-line @typescript-eslint/naming-convention"Content-Type": 'application/json',Authorization: 'Bearer ' + this.apiKey,},
}) as any;

根据返回的数据结构,解析响应数据,并将结果发送给webview进行展示,完成开发。
6e71432f43f4dc3aac2442dd5c953b80.png

发布插件

  • 扩展安装
    通过以上步骤基本完成了插件的开发,接下来有两种方式发布我们的插件,如果你的插件只是在内网使用,可以通过命令:vsce package, 将插件打包为vsix插件包,通过VSCode的扩展,从VSIX安装.
    当然首先要安装vsce这个工具

npm i vsce -g

c77920fcdcff3469af1710f37f8865a2.png

  • 上传到应用VSCode插件市场

    插件上传到VSCode应用市场,需要有应用市场的publisher账号,具体的账号创建流程这里不再涉及,创建账号后,登录当前账号,执行vsce publish,发布成功后大概需要过几分钟才能在应用市场搜到.发布账号有几个注意事项:

  • README.md文件默认会显示在插件主页;

  • README.md中的资源必须全部是HTTPS的,如果是HTTP会发布失败;

  • CHANGELOG.md会显示在变更选项卡;

  • 如果代码是放在git仓库并且设置了repository字段,发布前必须先提交git,否则会提示Git working directory not clean

  • 发布后需要等待几分钟应用市场才会更新;

  • 当然你可以在插件市场里面搜索chatgpt-for-vscode 来试用这个插件;

    2c8d1e6321f979bb4c577eb4a2ec2742.png

总结

以上就是一个ChatGPT插件的基本创建流程,核心是对VSCode API以及ChatGPT API的了解与使用。当然你所需要的功能都可以在对应的官方文档中找到。

参考文献:

https://code.visualstudio.com/api/extension-guides/overview
https://platform.openai.com/docs/api-reference/chat/create
http://blog.haoji.me/vscode-plugin-publish.html

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

8a105c36a3de2f7566ce7ed44ac623c1.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/70407.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《TCP/IP网络编程》阅读笔记--基于 TCP 的半关闭

目录 1--基于TCP的半关闭 1-1--TCP单方面完全断开的问题 1-2--shutdown()函数 1-3--半关闭的必要性 2--基于半关闭的文件传输程序 1--基于TCP的半关闭 1-1--TCP单方面完全断开的问题 Linux 系统中的 close 函数会将 TCP Socket 的连接完全断开&#xff0c;这意味着不能收…

苍穹外卖 day12 Echats 营业台数据可视化整合

苍穹外卖-day12 课程内容 工作台Apache POI导出运营数据Excel报表 功能实现&#xff1a;工作台、数据导出 工作台效果图&#xff1a; 数据导出效果图&#xff1a; 在数据统计页面点击数据导出&#xff1a;生成Excel报表 1. 工作台 1.1 需求分析和设计 1.1.1 产品原型 工作台是系…

智能安全帽~生命体征检测与危险气体检测一体化集成设计还是蓝牙无线外挂式方式好?

生命体征&#xff08;心率、血氧等&#xff09;检测&上报平台&#xff0c;危险气体采集&上报平台&#xff0c;是智能安全帽产品中常见的两种选配件&#xff0c;它们的实现有两种典型的模式&#xff1a; 1&#xff09;将传感器集成到主板上&#xff0c;做成一体化的智能…

Java并发编程第7讲——CompletableFuture、Future和ForkJoinPool(万字详解)

在Java中进行异步计算是比较难以理解的。一般来说&#xff0c;我们希望将任何计算都视为一系列步骤&#xff0c;但是在异步的情况下&#xff0c;这些步骤通常以回调函数的形式存在&#xff0c;要么散布在代码中&#xff0c;要么互相嵌套的很深。而我们需要处理可能发生在某个步…

设计模式-01简单工厂模式详解 详细代码对比

目录 ChatGpt问答原生代码简单工厂模式代码 简单工厂模式&#xff08;Simple Factory Pattern&#xff09;新增boat 对比两种方法原生代码为什么使用强制转换&#xff1f;简单工厂模式 简单工厂方法总结与原生代码的区别&#xff1a;优点:缺点&#xff1a; 参考 本文将介绍什么…

二维数组笔试题及其解析

Lei宝啊 &#xff1a;个人主页 愿所有美好不期而遇 前言&#xff1a; 数组名在寻常情况下表示首元素地址&#xff0c;但有两种情况例外&#xff1a; 1.sizeof(数组名)&#xff0c;这里的数组名表示整个数组&#xff0c;计算的是整个数组的大小 2.&数组名&#xff0c;这里的…

Hystrix和Sentinel熔断降级设计理念

目录 1 基本介绍2 Hystrix信号量和线程池区别2.1 信号量模式2.2 线程池模式2.3 注意 3 Sentinel介绍 1 基本介绍 Sentinel 和 Hystrix 的原则是一致的: 当检测到调用链路中某个资源出现不稳定的表现&#xff0c;例如请求响应时间长或异常比例升高的时候&#xff0c;则对这个资源…

目前无法建立VS2013与Qt的连接???

因为下载组件的时候&#xff0c;没有哪个选项&#xff0c;还是没有MSVC2013

微信小程序集成腾讯im,会话列表数据过多(长列表),卡顿问题的解决

说明 我这边用小程序集成im&#xff0c;然后结合公司的需求&#xff0c;做了一个聊天的小程序&#xff0c;在测试上线的时候没有问题&#xff0c;结果到客户那边&#xff0c;因为他们聊天的人多&#xff0c;会话列表达到了300多条&#xff0c;然后点击会话列表&#xff0c;进入…

C#,《小白学程序》第十六课:随机数(Random)第三,正态分布的随机数的计算方法与代码

1 文本格式 // 定义一个全局性&#xff08;公共&#xff09;的随机数发生器&#xff0c;便于大家&#xff08;各函数&#xff09;后面共同使用。 Random global_rnd new Random(); /// <summary> /// 生成服从标准正态分布的随机数 /// https://zhuanlan.zhihu.com/p/6…

Postern配置HTTP和HTTPS的步骤

Postern是一款强大的Android代理工具&#xff0c;它允许您在设备上配置全局代理来实现安全、隐私保护和自由上网。本文将详细介绍如何使用Postern在Android设备上配置HTTP和HTTPS代理&#xff0c;为您提供更便捷的上网体验。 步骤1&#xff1a;下载和安装Postern应用 首先&am…

pdf怎么合并在一起?几种方法快速合并

pdf怎么合并在一起&#xff1f;在处理PDF文件时&#xff0c;有时需要将多个PDF文件合并成一个文件。这种操作在日常学习、工作和生活中很常见。但是&#xff0c;如果没有专业的PDF工具&#xff0c;这项任务可能会变得非常繁琐、耗时和费力。因此&#xff0c;我们需要一款功能强…

Faster RCNN

【简介】 Faster RCNN[7]是第一个端到端&#xff0c;最接近于实时性能的深度学习检测算法&#xff0c;该网络的主要创新点就是提出了区域选择网络用于申城候选框&#xff0c;能几大提升检测框的生成速度。该网络首先输入图像到卷积网络中&#xff0c;生成该图像的特征映射。在特…

ActiveReportsJs 账票印刷

参考资料 官方文档 一. HTML部分 在页面上添加了Loading效果&#xff0c;账票印刷开始时显示Loading效果&#xff0c;印刷结束后隐藏Loading效果。ar-js-core.js是核心文件ar-js-pdf.js用来印刷PDFar-js-xlsx.js用来印刷EXCELar-js-locales.js用来设置语言 <!DOCTYPE htm…

优化SOCKS5的方法

在今天的互联网世界中&#xff0c;保护个人隐私和提升网络速度至关重要。作为一种常用的代理协议&#xff0c;SOCKS5代理服务器不仅可以保护您的隐私&#xff0c;还可以实现更快速的网络访问。本文将为您介绍一些优化SOCKS5代理服务器的方法&#xff0c;以提高网络速度和安全性…

阿里云2核4G服务器5M带宽五年租用价格表

阿里云2核4G服务器5M带宽可以选择轻量应用服务器或云服务器ECS&#xff0c;轻量2核4G4M带宽服务器297元一年&#xff0c;2核4G云服务器ECS可以选择计算型c7、c6或通用算力型u1实例等&#xff0c;买5年可以享受3折优惠&#xff0c;阿腾云分享阿里云服务器2核4G5M带宽五年费用表&…

Xcode,swift:Error Domain=kCLErrorDomain Code=1 (null)问题解决

问题描述: iOS开发时,当使用用户的位置权限时,获取用户经纬度报错:Error DomainkCLErrorDomain Code1 "(null)",错误域kCLError域代码1“(null)” 解决方法: 打开模拟机的设置-通用-语言与地区 将地区设置为中国(如果你的开发位置在中国的话) 点击左上方Features,选择…

发光太阳聚光器的蒙特卡洛光线追踪研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【大数据】Flink 详解(七):源码篇 Ⅱ

本系列包含&#xff1a; 【大数据】Flink 详解&#xff08;一&#xff09;&#xff1a;基础篇【大数据】Flink 详解&#xff08;二&#xff09;&#xff1a;核心篇 Ⅰ【大数据】Flink 详解&#xff08;三&#xff09;&#xff1a;核心篇 Ⅱ【大数据】Flink 详解&#xff08;四…

完成Centos上使用SSH公钥进行免密上传文件到gitee的步骤后,测试免密推送到gitee的时候还是需要输入邮箱和密码

如果你已经按照正确的步骤设置了SSH公钥并进行了免密测试&#xff0c;但仍然需要输入邮箱地址和密码才能推送到gitee&#xff0c;那么可能有以下几种原因&#xff1a; 您可能没有使用SSH URL来推送代码。请确保您使用的是SSH URL而不是HTTPS URL来推送代码。您可以使用命令 gi…