дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 11:15:40 +02:00
feat(agents): Dispatch and supervise coding agents over ACP (#72)
## What An Agents feature: hand a task to a coding agent and follow it from the IDE. Agents speak the [Agent Client Protocol](https://agentclientprotocol.com). Built in: Claude Code, Codex, Gemini CLI, GitHub Copilot, Cursor, OpenCode, Qwen Code, Kimi CLI, Goose, Auggie, Kiro, Mistral Vibe. You can add your own in `<config>/agents/<id>.toml` (`name`, `command`, `args`, `[env]`). An agent whose command isn't on `PATH` is listed under "Not installed". - **New Task page.** An editor page with a prompt box. You pick the agent, model, mode and thinking effort, and whether it runs in a new worktree (from a chosen branch) or in the checkout. - **Agents tool window.** Tasks are grouped by what they need: Needs Input, Failed, Running, Ready to Review, Archived. It also shows a stripe badge, a status bar item and notifications. - **Session tab.** - The conversation: Markdown, thinking, tool calls with diff stats, the plan. - Permission requests appear as an editor banner. - The changed files are compared against the task's base commit and open in the diff viewer. - A context-usage meter. - **Composer.** - `@` references files from the project index. A referenced file's text is sent when the agent accepts embedded context, otherwise a `resource_link`. - `/` lists the agent's commands; ↑/↓ recall earlier messages. - Images can be pasted, dropped or picked; Shift+Tab cycles the mode. - While the agent works, Enter queues the message and ⌘↵ interrupts the turn and sends it now. Queued messages can be sent now, edited or removed. - **Send to Agent.** In the editor and Project view context menus. It adds `@file:10-20` references to the message you typed last. - Landing the work is left to the existing Git features: the worktree is a normal branch. ## How - **`crates/ide-agent`**: one ACP agent process per task, running in the task's directory. - It folds `session/update` into a timeline and answers `session/request_permission`. - It tracks the session's settings: `configOptions`, falling back to the older `modes` / `models` fields. The user's choices are applied again on every new or reloaded session. - Tasks are saved as JSON per task. Sessions resume with `session/load` without duplicating history, and old task files are upgraded when read. - **`ide-jsonrpc`**: adds newline-delimited framing (ACP) next to Content-Length (LSP). - **`ide-vcs`**: adds `numstat_with_worktree` for the changes list. - **Editor**: - The Switcher (⌃⇥) lists every open editor, as IDEA does, not just files. - `EditorKindContribution.restorable` lets a kind's tabs be saved with the editor session, so agent tabs survive reloads. - **UI**: `Select` popups now size to fit short option details (they used to cut them off). ## Testing - `cargo test -p ide-agent` (14 tests). They use an in-memory ACP agent and cover permissions, restart with `session/load`, settings, the queue with send-now and stop, and prompt blocks. - There is also an ignored end-to-end test against the real Claude Code adapter: `OPENIDEA_AGENT_E2E=1 cargo test -p ide-agent real_claude -- --ignored`. - `pnpm vitest run`: 2052 tests. - `cargo clippy -p ide-agent -p openidea --all-targets -- -D warnings` and typecheck are clean. - Driven in the running app with Claude Code: - A task in a worktree, with permission answers, changes listed and the diff opened. - A follow-up after restarting the IDE. - `@` reference with embedded content, `/` commands, Shift+Tab mode changes. - A queued message and send-now, an image prompt, Send to Agent from a selection. - The Switcher and restored tabs after a reload. Not covered yet: only Claude Code was driven end to end. The other agents go through the same ACP path but weren't run here. Merged on the maintainer's go-ahead. Merge with main: kept both sides in Cargo.toml (ide-agent + ide-clipboard), the feature registry (agents + vim) and zh.json (no duplicate keys). After the merge: typecheck clean, full vitest 268 files / 2247 tests passed, ide-agent/ide-jsonrpc/ide-vcs 144 passed, bindings unchanged after regeneration.
Цей коміт міститься в:
1 джерело
b4742b730b
коміт
2eaa6cb0c7
75 files changed
+6377
-63
No files matched your search
@@ -298,6 +298,9 @@ export const intellijMacos: Record<string, string[]> = {
|
||||
"http.runAll": [],
|
||||
"db.execute": ["Meta+Enter"],
|
||||
"db.showToolWindow": [],
|
||||
"agents.newTask": ["Meta+Shift+I"],
|
||||
"agents.showToolWindow": [],
|
||||
"agents.sendToAgent": [],
|
||||
// Database tool window (when the tree has focus; `db.openConsole` anywhere).
|
||||
"db.openConsole": ["Meta+Shift+L"],
|
||||
"db.newDataSource": [],
|
||||
|
||||
@@ -295,6 +295,9 @@ export const intellijWindows: Record<string, string[]> = {
|
||||
"http.runAll": [],
|
||||
"db.execute": ["Ctrl+Enter"],
|
||||
"db.showToolWindow": [],
|
||||
"agents.newTask": ["Ctrl+Alt+Shift+I"],
|
||||
"agents.showToolWindow": [],
|
||||
"agents.sendToAgent": [],
|
||||
// Database tool window (when the tree has focus; `db.openConsole` anywhere).
|
||||
"db.openConsole": ["Ctrl+Shift+Q"],
|
||||
"db.newDataSource": [],
|
||||
|
||||
@@ -322,6 +322,10 @@ export const vscodeMacos: Record<string, string[]> = {
|
||||
"find.popup.previousResult": ["Meta+Shift+G"],
|
||||
"find.popup.openResult": [],
|
||||
"find.popup.recentSearches": ["Alt+Down"],
|
||||
// Agents (VS Code's chat: ⇧⌘I)
|
||||
"agents.newTask": ["Meta+Shift+I"],
|
||||
"agents.showToolWindow": [],
|
||||
"agents.sendToAgent": [],
|
||||
// Search fields (find bar, Find in Files): last, so they win over editor keys while one is focused.
|
||||
"find.field.newLine": ["Meta+Shift+Enter"],
|
||||
"find.field.recentSearches": ["Alt+Down"],
|
||||
|
||||
@@ -59,4 +59,8 @@ export const vscodeWindows: Record<string, string[]> = {
|
||||
"markdown.editorOnly": [],
|
||||
"markdown.editorAndPreview": ["Ctrl+K V"],
|
||||
"markdown.previewOnly": ["Ctrl+Shift+V"],
|
||||
// Agents (VS Code's chat: Ctrl+Shift+I)
|
||||
"agents.newTask": ["Ctrl+Shift+I"],
|
||||
"agents.showToolWindow": [],
|
||||
"agents.sendToAgent": [],
|
||||
};
|
||||
@@ -3259,6 +3259,61 @@
|
||||
"inserts a template from the Includes or Code tab.": "插入“包含”或“代码”标签页中的模板。",
|
||||
"File templates insert this with {code}, indented like the directive; a directive line whose include is empty is dropped. The file template variables apply.": "文件模板通过 {code} 插入此内容,缩进与该指令一致;所含内容为空的指令行将被删除。文件模板变量同样适用。",
|
||||
"Inserted where a file template says {code}.": "插入到文件模板中写有 {code} 的位置。",
|
||||
"Agents": "智能体",
|
||||
"New Agent Task": "新建 Agent 任务",
|
||||
"No agent tasks yet": "还没有 Agent 任务",
|
||||
"New Task…": "新建任务…",
|
||||
"Needs Input": "等待输入",
|
||||
"Ready to Review": "待审阅",
|
||||
"Archived": "已归档",
|
||||
"Archive": "归档",
|
||||
"Archive Task": "归档任务",
|
||||
"Delete Agent Task": "删除 Agent 任务",
|
||||
"Also remove its worktree folder": "同时删除它的 worktree 目录",
|
||||
"needs input": "等待输入",
|
||||
"running": "正在运行",
|
||||
"This agent task no longer exists": "这个 Agent 任务已不存在",
|
||||
"Local checkout": "当前工作区",
|
||||
"Needs input": "等待输入",
|
||||
"Ready": "就绪",
|
||||
"Starting the agent…": "正在启动 agent…",
|
||||
"Working…": "处理中…",
|
||||
"Thinking": "思考过程",
|
||||
"Plan": "计划",
|
||||
"Message": "消息",
|
||||
"The agent is working. You can type your next message.": "Agent 正在处理,可以先写下一条消息。",
|
||||
"Reply to the agent": "回复 agent",
|
||||
"Send": "发送",
|
||||
"vs": "对比",
|
||||
"file": "个文件",
|
||||
"files": "个文件",
|
||||
"No changes yet": "还没有改动",
|
||||
"What should the agent do?": "让 agent 做点什么?",
|
||||
"Describe the task": "描述任务",
|
||||
"New worktree": "新 worktree",
|
||||
"Starting…": "正在启动…",
|
||||
"Waiting for your answer": "等待你的回答",
|
||||
"The agent stopped": "Agent 已停止",
|
||||
"Not installed": "未安装",
|
||||
"{command} was not found on PATH": "在 PATH 中找不到 {command}",
|
||||
"Agent tasks": "Agent 任务",
|
||||
"Describe a task for the agent. @ references a file, / runs a command": "描述要交给 agent 的任务。@ 引用文件,/ 运行命令",
|
||||
"away from your changes": "不影响你的改动",
|
||||
"edits your files directly": "直接修改你的文件",
|
||||
"from": "基于",
|
||||
"Models and modes appear after this agent's first task.": "这个 agent 跑完第一个任务后会显示模型和模式。",
|
||||
"Queue a message for when the agent is done (⌘↵ sends it now)": "排队一条消息,agent 做完后发送(⌘↵ 立即发送)",
|
||||
"Couldn't send the message": "消息发送失败",
|
||||
"Couldn't change the setting": "设置修改失败",
|
||||
"Couldn't update the queue": "队列更新失败",
|
||||
"Queued messages": "排队中的消息",
|
||||
"Send now": "立即发送",
|
||||
"Queue": "排队",
|
||||
"Reference a File (@)": "引用文件 (@)",
|
||||
"Attach Image…": "附加图片…",
|
||||
"Remove Image": "移除图片",
|
||||
"Image too large": "图片太大",
|
||||
"Send to Agent": "发送给 Agent",
|
||||
"Enable Vim emulation": "启用 Vim 模拟",
|
||||
"Configuration file": "配置文件",
|
||||
"mappings": "个映射",
|
||||
|
||||
Reference in new issue
Заблокувати користувача