Closes#969
## What and why
On Windows, deleting an agent task and its worktree could fail with `os error 32` while the agent's process tree still held the directory or its files open. Deletion now waits up to 5 seconds for the agent process to be killed and reaped, then retries folder removal for transient locks. This also covers persistent ACP agents such as CodeBuddy that cannot reload their session and therefore stay alive while idle.
## How it was verified
- Windows desktop acceptance through the Tauri MCP bridge, using a deterministic ACP agent with a real PowerShell descendant holding a file open. Closed the conversation tab, then deleted the task with worktree removal enabled. A separate helper retained another file lock for 1.2 seconds: the pre-fix implementation showed `os error 32`; the fixed implementation deleted the task and directory, with both agent processes gone.
- Also verified direct deletion, archive then delete, and deletion with worktree removal unchecked. Processes exited in all cases; branches were preserved, and unchecked removal preserved the folder.
- `cargo test -p ide-jsonrpc -p ide-agent -- --test-threads=2`: 155 passed, 5 real-agent tests ignored. The test runner used Git Bash on PATH and a process-local `core.autocrlf=false`, matching CI's LF fixture setup; no global Git settings were changed.
- `cargo clippy -p ide-jsonrpc -p ide-agent --all-targets -- -D warnings`, `cargo fmt --all --check`, and `git diff --check`: passed.
- Full workspace (Windows/macOS/Linux), frontend and E2E CI: [final PR run](https://github.com/l0ng-ai/openidea/actions/runs/41819945536).
- Windows regression coverage now checks deletion while waiting for permission and while idle without `session/load`, actual sharing violations, delayed file-lock release, and `Peer::exited()` waiting for a descendant's file handle to close. Existing Unix process tests remain enabled.
- Evidence (local, not committed):
- Before: `C:/Users/thoma/repo/pr1240-evidence-20261104/before.png`
- After: `C:/Users/thoma/repo/pr1240-evidence-20261104/after.png`
- Recording: `C:/Users/thoma/repo/pr1240-evidence-20261104/after.gif`
- Runtime results: `C:/Users/thoma/repo/pr1240-evidence-20261104/runtime-cases.json`
- Real signed-in CodeBuddy and native Claude/Codex were not exercised. Native Claude/Codex use an in-process connection, so their `exited()` resolves immediately and removal relies on the bounded retry. Shared-worktree fork protection remains unchanged.
Deleting a worktree-isolated agent task together with its worktree failed for good with "fatal: '<path>' is not a working tree" once git no longer recognized the worktree: its registration was pruned, the repository moved, or the worktree's `.git` file was deleted.
When `git worktree remove --force` fails but the folder is still there and lies inside the agent worktrees directory, the folder is now removed directly, so the task can always be deleted. A stale registration is pruned by git later. Paths outside that directory (the task's cwd comes from its stored record) keep git's error and are never deleted by hand.
Fixes#969.
Co-authored-by: a-rookie-of-C-language <[email protected]>
Agent tasks failed in projects without git because change tracking assumed a repository. Outside a repository there are no changes to compare; worktree isolation is hidden and the task runs in the local checkout, and asking for a worktree there returns a clear error.
Co-authored-by: a-rookie-of-C-language <[email protected]>
Git blobs were always decoded as UTF-8, so files in GBK or other legacy encodings showed every line as changed in the gutter, diff, blame and commit views, and staging/committing could re-encode them wrongly.
Blob text is now decoded and encoded with the file's encoding: the open document's encoding, else detection on the working file with the project default as fallback, else detection on the blob. Covers line hunks, file-at-revision, blame, stage patch/hunks, commit, conflict versions, diff text, and the agent worktree's file_at, partial commit and patch helpers. Text that cannot be represented in the target encoding is reported as an error instead of being written lossily.
Fixes#243
未在 Windows 实机验证。
* fix(agents): Leave changes made before a local checkout task out of its changes
A task in the project's own checkout listed every uncommitted and untracked
file as its own. The files already changed when the task starts are now
recorded with their size and modification time, and drop out of the task's
changes until they are edited again.
* feat(agents): Show the current branch for a local checkout task
## 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.