mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-08 17:02:17 +00:00
## 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.
109 lines
3.0 KiB
TOML
109 lines
3.0 KiB
TOML
[workspace]
|
|
resolver = "3"
|
|
members = ["crates/*", "src-tauri"]
|
|
|
|
[workspace.package]
|
|
version = "0.1.15"
|
|
edition = "2024"
|
|
rust-version = "1.96"
|
|
license = "Apache-2.0"
|
|
authors = ["OpenIDEA contributors"]
|
|
|
|
[workspace.dependencies]
|
|
# internal
|
|
ide-core = { path = "crates/ide-core" }
|
|
ide-vfs = { path = "crates/ide-vfs" }
|
|
ide-text = { path = "crates/ide-text" }
|
|
ide-language = { path = "crates/ide-language" }
|
|
ide-index = { path = "crates/ide-index" }
|
|
ide-syntax = { path = "crates/ide-syntax" }
|
|
ide-search = { path = "crates/ide-search" }
|
|
ide-jsonrpc = { path = "crates/ide-jsonrpc" }
|
|
ide-lsp = { path = "crates/ide-lsp" }
|
|
ide-dap = { path = "crates/ide-dap" }
|
|
ide-vcs = { path = "crates/ide-vcs" }
|
|
ide-terminal = { path = "crates/ide-terminal" }
|
|
ide-run = { path = "crates/ide-run" }
|
|
ide-workspace = { path = "crates/ide-workspace" }
|
|
ide-sdk = { path = "crates/ide-sdk" }
|
|
ide-build = { path = "crates/ide-build" }
|
|
ide-analysis = { path = "crates/ide-analysis" }
|
|
ide-coverage = { path = "crates/ide-coverage" }
|
|
ide-profiler = { path = "crates/ide-profiler" }
|
|
ide-http = { path = "crates/ide-http" }
|
|
ide-db = { path = "crates/ide-db" }
|
|
ide-web = { path = "crates/ide-web" }
|
|
ide-spell = { path = "crates/ide-spell" }
|
|
ide-agent = { path = "crates/ide-agent" }
|
|
ide-clipboard = { path = "crates/ide-clipboard" }
|
|
|
|
# serialization & IPC typing
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
toml = "0.9"
|
|
toml_edit = "0.25"
|
|
specta = { version = "=2.0.0-rc.25", features = ["derive"] }
|
|
|
|
# async & concurrency
|
|
tokio = { version = "1", features = ["rt-multi-thread", "macros", "sync", "time", "process", "io-util", "fs"] }
|
|
tokio-util = { version = "0.7", features = ["rt"] }
|
|
parking_lot = "0.12"
|
|
rayon = "1"
|
|
dashmap = "6"
|
|
futures = "0.3"
|
|
|
|
# errors & diagnostics
|
|
thiserror = "2"
|
|
anyhow = "1"
|
|
tracing = "0.1"
|
|
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
|
|
|
|
# text & fs
|
|
ropey = "1.6"
|
|
encoding_rs = "0.8"
|
|
chardetng = "0.1"
|
|
ignore = "0.4"
|
|
globset = "0.4"
|
|
notify = "8"
|
|
notify-debouncer-full = "0.6"
|
|
trash = "5"
|
|
blake3 = "1"
|
|
dunce = "1"
|
|
dirs = "6"
|
|
|
|
# search, index, language
|
|
grep-searcher = "0.1"
|
|
grep-regex = "0.1"
|
|
grep-matcher = "0.1"
|
|
nucleo-matcher = "0.3"
|
|
redb = "4"
|
|
tree-sitter = "0.25"
|
|
|
|
# protocols & integrations
|
|
lsp-types = "0.97"
|
|
gix = { version = "0.89", default-features = false }
|
|
portable-pty = "0.9"
|
|
reqwest = { version = "0.13", default-features = false, features = ["rustls-no-provider", "http2", "charset", "gzip", "deflate", "brotli"] }
|
|
rustls = { version = "0.23", default-features = false, features = ["ring", "std", "tls12", "logging"] }
|
|
rustls-platform-verifier = "0.7"
|
|
sqlx = { version = "0.9", default-features = false, features = ["runtime-tokio", "tls-rustls-ring-webpki", "sqlite", "postgres", "mysql"] }
|
|
uuid = { version = "1", features = ["v4"] }
|
|
|
|
# testing
|
|
insta = { version = "1", features = ["yaml"] }
|
|
proptest = "1"
|
|
tempfile = "3"
|
|
|
|
[profile.dev]
|
|
# Keep debug builds snappy while giving dependencies decent speed.
|
|
opt-level = 0
|
|
[profile.dev.package."*"]
|
|
opt-level = 2
|
|
|
|
[profile.release]
|
|
codegen-units = 1
|
|
lto = true
|
|
opt-level = 3
|
|
panic = "abort"
|
|
strip = true
|