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.
On Windows the auto-downloaded jdtls ran through `bin\jdtls.bat`, which starts the Python wrapper and ends with `pause`. When Python failed, `pause` wrote its prompt to stdout in the console code page; the transport treated that as a broken LSP header ("non-UTF-8 header"), dropped it and the server was killed, so the status only said "exited with code 1".
- jdtls is now launched with `java` directly on every platform (Equinox launcher, platform config dir, JDK 24+ flags, forwarded JVM args, `-data`), so Python is no longer needed; user wrappers and unusual layouts keep their command.
- Output outside the protocol on stdout (and non-UTF-8 stderr) is decoded (UTF-8, then the Windows OEM/ANSI code page, then lossy), logged and included in the crash message, for stdio and TCP language servers, DAP adapters and ACP agents.
- Crash messages carry the real exit code and the last lines of output.
未在 Windows 实机验证 (Windows paths covered by unit tests and a Windows-target clippy run).
Fixes#90
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn