☰
VSCode Agent Sessions 运行命令生成指南:基于 tasks.json 的 `inAgents` 任务与自动执行的完整实践
2026/11/2 19:05:18 网站建设 项目流程

VSCode Agent Sessions 运行命令生成指南:基于 tasks.json 的inAgents任务与自动执行的完整实践

【免费下载链接】vscodeVisual Studio Code项目地址: https://gitcode.com/GitHub_Trending/vscode6/vscode

Agent Session(智能会话/代理会话)工作区顶部标题栏的Run 按钮,可以让用户一键执行项目的安装、开发等常用命令。这些出现在 Run 按钮中的运行命令并非特设功能,而是以 VSCode 标准任务(tasks.json)为基础、通过inAgents标记接入的一套机制。本指南以官方内置技能 generate-run-commands/SKILL.md 为主线,讲解运行命令的任务模式(schema)、生成与修改的决策逻辑、文件写入与合并规则,并结合仓库源码揭示inAgents、runOptions.runOn = "worktreeCreated"从配置解析到自动调度的完整链路。读完你将能够为任意 Agent Session 工作区正确编写、推断、合并与调试运行命令。

Skill 的定位:内置技能如何参与运行命令

在仓库中,generate-run-commands属于 Agent 会话的内置技能(skills)之一,与commit、code-review、create-pr等并列存放于 src/vs/sessions/skills 目录。它的作用由文档头部的 YAML Front Matter 定义:

name: generate-run-commands description: Generate or modify run commands for the current session. Use when the user wants to set up or update run commands that appear in the session's Run button.

即:当用户希望为当前会话设置或更新出现在标题栏 Run 按钮中的运行命令时,Agent 就会调用该技能。SKILL.md 本身属于"可定制"的内置技能——文档第一行注释明确说明,在产品内可以自定义并保存副本以覆盖其默认行为,删除该副本则恢复内置行为。因此,理解这份技能文档的本质,就是理解 VSCode 对"运行命令"这一概念的标准建模。

任务模式(Task Schema):运行命令到底是什么

SKILL.md 给出的第一个核心结论是:一个运行命令就是一个tasks.json中的任务(task),它依赖两个关键字段:

  • "inAgents": true—必填:使该任务出现在 Agent(会话)的 Run 按钮中;
  • "runOptions": { "runOn": "worktreeCreated" }—可选:每当新建 worktree 时自动运行该任务(用于 setup/install 类命令)。

文档给出的最小可用示例为:

{ "tasks": [ { "label": "Install dependencies", "type": "shell", "command": "npm install", "inAgents": true, "runOptions": { "runOn": "worktreeCreated" } }, { "label": "Start dev server", "type": "shell", "command": "npm run dev", "inAgents": true } ] }

示例展示了两类典型任务:一类是带runOn: worktreeCreated的环境准备命令(安装依赖),另一类是仅带inAgents: true的常驻/启动命令(启动开发服务器)。二者的差异正是"环境就绪"与"按需运行"两种语义的划分。

源码中的字段定义

在任务模型 tasks.ts 中,inAgents的注释直接印证了它的职责——"Show this task in the Agents run action dropdown"(将该任务显示在 Agents 的 run 操作下拉菜单中),它与hide(不显示在 run task 快速选择器中)是同一层级配置属性。

runOn则由内部枚举RunOnOptions支撑:

export enum RunOnOptions { default = 1, folderOpen = 2, worktreeCreated = 3 }

IRunOptions实际包含四个属性,任务配置模块 taskConfiguration.ts 在解析时会为未显式给出的属性补齐默认值:

runOptions 属性默认值说明(来自 taskConfiguration.ts)
reevaluateOnReruntrue重新运行时是否重新评估任务
runOndefault触发的时机,见下方枚举
instanceLimit1可并发运行的最大实例数(解析时取max(配置值, 1))
instancePolicyprompt实例数达到上限时的策略(terminateNewest/terminateOldest/prompt/warn/silent)

值得注意的是,SKILL.md 只用了runOn一个字段,但 JSON Schema 层面为runOn定义了三档取值(见 jsonSchema_v2.ts):default、folderOpen(文件夹打开时自动运行)、worktreeCreated(创建 Agent Session worktree 时自动运行)。而 taskConfiguration.ts 的 RunOnOptions.fromString 在解析时对值做toLowerCase()后匹配,因此folderOpen/worktreeCreated的大小写写法均会被正确识别。

校验与自动补全

inAgents与runOn均已纳入任务的 JSON Schema 校验(见 jsonSchema_v2.ts 对inAgents的描述),这意味着在编辑器内手写tasks.json时同样可以获得校验、悬浮提示与取值枚举补全,inAgents语法错误的概率很低,与技能生成的写法完全一致。

决策逻辑(Decision Logic):先查、后改、必要时再问

SKILL.md 为 Agent 规定的决策流程高度务实,核心是"能推断就不打扰用户":

  1. 先读取现有的.vscode/tasks.json,检查是否已存在运行命令(即inAgents: true的任务)。
  2. 若已存在运行命令:将其视为修改请求(modify request)——询问用户具体想做什么:新增、删除还是更新某条命令。
  3. 若不存在运行命令:尝试根据工作区内容推断合理命令:
    • 检查package.json、Makefile、pyproject.toml、Cargo.toml、go.mod、.nvmrc等工程文件,以识别技术栈与常用命令;
    • 若 setup 命令明确(如npm install、pip install -r requirements.txt),直接添加并配置"runOptions": { "runOn": "worktreeCreated" },无需询问;
    • 若主要 run/dev 命令明确(如npm run dev、cargo run),直接添加,仅带"inAgents": true;
    • 仅当命令存在歧义时才询问用户,例如存在多个同等合理的选项、无法识别项目结构,或项目采用了非标准 setup。

推断来源的工程信号

上述工程文件覆盖了前端(package.json+.nvmrc锁定 Node 版本)、Make 系项目、Python(pyproject.toml)、Rust(Cargo.toml)、Go(go.mod)等主流生态。这一"从项目清单文件反推启动命令"的思路与仓库中SessionsTasksService面向多目标读取任务的设计相呼应——任务既可以从工作区根目录的.vscode/tasks.json读取,也可以来自用户级 tasks 配置,从而保证不同会话形态都能获得一致的可运行命令集合。

读取与修改背后的服务能力

技能文档描述的是 Agent 的行为准则,而其底层能力由 sessionsTasksService.ts 提供,文档中的每一步都能在接口上找到对应实现:

  • **"先读现有运行命令"**对应getSessionTasksOnce()——该方法"一次性返回会话任务(inAgents: true)快照",实现即按t => !!t.inAgents过滤(sessionsTasksService.ts);
  • **"新增命令"**对应createAndAddTask()——创建一个inAgents: true的 shell 任务并写入合适的tasks.json(工作区或用户级);
  • **"修改既有任务/打标"**对应addTaskToSessions()与updateTask()——其中addTaskToSessions会按 label 定位既有任务,通过 JSON 编辑在路径['tasks', index, 'inAgents']上写入true,实现"原地把普通任务变成运行命令";
  • **"删除命令"**对应removeTask()——按任务 label 从目标tasks.json中移除;
  • 会话中"不运行命令"的普通任务也并未被忽略——getNonSessionTasks()专门返回不带inAgents: true的任务,作为"Add Run Action"(添加运行操作)选择器中的候选建议(sessionsTasksService.ts)。

也就是说,"运行命令"并非一套独立的文件格式,而是对既有 VSCode Task 体系的一层视图过滤:inAgents决定它是否进入 Run 按钮的可见集合,其余任务定义能力(dependsOn依赖、shell 类型等)原样保留。例如getAllTasks()会返回全部任务(含无inAgents的),以便 agent-host 运行时通过dependsOn解析被运行命令依赖的普通任务。

文件写入与合并规则

SKILL.md 对落盘行为有两个硬性要求:

  1. 始终写入工作区根目录的.vscode/tasks.json;
  2. 若文件已存在则合并,绝不覆盖无关任务(merge,do not overwrite unrelated tasks)。

写入完成后,Agent 应简要向用户确认新增了哪些命令,以及如何从 Run 按钮触发它们。

合并示例

若工作区已存在一组用于调试的任务,那么新增运行命令的正确结果应如下所示——保留原有任务,仅追加两个inAgents条目:

{ "version": "2.0.0", "tasks": [ { "label": "Debug tests", "type": "shell", "command": "npm run test -- --debug", "problemMatcher": [] }, { "label": "Install dependencies", "type": "shell", "command": "npm install", "inAgents": true, "runOptions": { "runOn": "worktreeCreated" } }, { "label": "Start dev server", "type": "shell", "command": "npm run dev", "inAgents": true } ] }

为什么强调"不覆盖"?

从实现侧看,tasks.json承载的是整个工作区的任务声明,其中既包含作为运行命令的inAgents任务,也包含大量仅供 Run Task 面板、调试配置或其他工具消费的普通任务。若采用"整文件覆写"策略,会破坏problemMatcher、自定义options.cwd、dependsOn链等既有配置。因此 Agent 端正确的合并策略,与 sessionsTasksService.ts 中"按 label 定位任务、以属性级 JSON 补丁写入inAgents: true、或仅追加新任务条目"的编辑粒度保持一致。

运行命令如何被触发:Run 按钮与 worktree 自动执行

Run 按钮与下拉菜单

inAgents: true的任务会出现在会话标题栏 Run 按钮的下拉菜单中,点击即运行。这与任务的读取链路(getSessionTasks/getSessionTasksOnce的!!t.inAgents过滤)一致:只有当inAgents为真时任务才会被纳入该视图。

worktreeCreated 的自动调度原理

runOn: worktreeCreated的真正含义值得深挖:它指在Agent Session 创建了实际 git worktree 时自动执行该任务。仓库中的 worktreeCreatedTaskDispatcher.ts 以 workbench 贡献点(workbench.contrib.sessions.worktreeCreatedTaskDispatcher)实现了这一逻辑,其行为要点:

  • 每个新会话只触发一次:当某会话首次报告真实的 git worktree(监视条件为session.workspace中存在带workTreeUri的文件夹)时,调度器拉取该会话全部任务,逐个执行runOptions.runOn === 'worktreeCreated'的条目;
  • 避免重复执行:若会话的运行时本身已在服务端执行过这些任务(通过ISessionCapabilities.runsWorktreeCreatedTasks信号标识),调度器会直接跳过,防止双重执行;
  • 随会话生命周期清理:被调度任务返回的 stop handles 按会话跟踪,当会话被归档(archived)或移除时统一 dispose,避免 setup/构建这类长生命周期进程泄漏;
  • 可开关:Agent host 会话是否自动执行worktreeCreated任务受设置chat.agentHost.runWorktreeCreatedTasks控制(默认true),关闭后仅影响自动调度,手动通过 Run Task 面板运行不受影响。

这意味着,一个"Install dependencies"配置了runOn: worktreeCreated后,Agent 每创建一个新 worktree 就能自动获得已就绪的依赖环境——这正是 SKILL.md 将 setup 类命令与worktreeCreated绑定的原因:用一条配置换取每个新工作区的零手工准备。

实战注意事项

基于上述机制,在实际使用或让 Agent 生成运行命令时,值得关注以下几点:

  • 区分两类语义:依赖安装、构建产物准备这类"环境就绪"命令应加runOptions: { runOn: "worktreeCreated" };而 dev server、测试等需用户按需触发的命令,只加inAgents: true,避免在每次建 worktree 时被自动拉起。
  • 让 Agent 先探查再写入:技能要求 Agent 先读现有.vscode/tasks.json,因此当工作区已有运行命令时,向 Agent 明确提出"新增/删除/更新哪条命令"比笼统地"帮我配一下"更高效。
  • 合并优于覆写:无论是人工编辑还是让 Agent 修改,都应保留文件中的既有任务;不确定时可先查看该文件确认任务 label,避免与已有条目冲突。
  • 利用普通任务的迁移:若工作区已有期望出现在 Run 按钮里的任务,可通过会话的"Add Run Action"将非inAgents任务打上标记,而无须复制一份命令。
  • 验证与回退:所有任务字段均在 jsonSchema_v2.ts 定义的 Schema 校验之下,若希望从 Agent 生成的运行命令恢复到内置默认行为,删除技能的自定义副本即可。

深入阅读

  • 技能本体:src/vs/sessions/skills/generate-run-commands/SKILL.md,以及 src/vs/sessions/skills 下的全部内置技能;
  • 任务数据模型与inAgents/RunOnOptions定义:src/vs/workbench/contrib/tasks/common/tasks.ts;
  • 任务 JSON Schema(含inAgents与runOn枚举):src/vs/workbench/contrib/tasks/common/jsonSchema_v2.ts;
  • runOn/runOptions解析与默认值:任务配置解析 src/vs/workbench/contrib/tasks/common/taskConfiguration.ts;
  • 会话任务服务(读取、打标、新建、删除运行命令):src/vs/sessions/contrib/chat/browser/sessionsTasksService.ts;
  • worktreeCreated 自动执行调度器:src/vs/sessions/contrib/chat/browser/worktreeCreatedTaskDispatcher.ts。

综上,VSCode Agent Session 的运行命令机制可以总结为一句话:标准tasks.json任务 +inAgents可见性标记 + 可选的runOn: worktreeCreated自动触发。掌握这套模式后,无论是人工编辑还是借助generate-run-commands技能,都能为会话工作区快速搭建出"创建即就绪、按钮即启动"的完整运行体验。

【免费下载链接】vscodeVisual Studio Code项目地址: https://gitcode.com/GitHub_Trending/vscode6/vscode

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询