Commit Graph
14 Commits
Author SHA1 Message Date
l0ng-ai 82fe52f595 fix(agents): wait for the agent to exit before deleting its worktree (#1240)
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.
2026-11-04 19:39:40 +08:00
l0ng-ai e20eb1acf8 fix(agents): stop idle agents, run tasks locally by default, keep worktrees next to the project (#1050)
A task's agent process lived until the task was archived or the project closed, and stopping it killed only the direct child, so wrappers (npx, codex.cmd, claude shims) left the real agent running. Agents that support session/load are now stopped after 5 minutes idle and restarted with the session reloaded on the next message; agent connections, language servers and the native Claude CLI start in their own process group and are stopped with their whole tree.

New tasks run in the local checkout unless the user picks a worktree, and worktrees go next to the project (<parent>/<project>.worktrees/<task>), on the project's drive and outside its tree.

Fixes #1011
Fixes #1003
2026-11-04 00:38:33 +08:00
arookieofcanda-rookie-of-C-language 94d209c99c fix(agents): resolve agent commands through PATH x PATHEXT on Windows (#273)
On Windows std/tokio Command only tries .exe for a bare program name, so agents installed as npm shims (codex.cmd, claude.cmd) failed with "program not found". Bare names are now resolved through PATH x PATHEXT before spawning.

- ide-core::process gains find_executable / find_executable_in (moved from ide-run::which, which re-exports them).
- ide-jsonrpc Peer::spawn_framed resolves against the child's PATH (caller env, login shell, then ours): covers ACP agents and the native Codex driver.
- ide-agent newest_install builds candidates with executable_names, so the native Claude driver finds .cmd shims and multi-install selection works on Windows.
- ide-agent replay recorder resolves the same way.

Co-authored-by: a-rookie-of-C-language <186315048+a-rookie-of-C-language@users.noreply.github.com>
2026-10-29 23:00:01 +08:00
l0ng-ai 0cd927edf3 feat(agents): Native Claude Code / Codex drivers, ACP v2 and the ACP Registry (#151)
Agents can run through native drivers or any ACP agent, speak ACP v1 or v2, and be installed from the ACP Registry. Tasks gain fork, in-place edit-and-rerun, steering and usage-limit handling where the agent supports them.

- Native Claude Code (`claude` stream-json) and Codex (`codex app-server`) drivers, each served to the task machinery as an in-process ACP shim, using the newest install on PATH.
- ACP v2 with v1 fallback, negotiated on initialize; per-agent capabilities (fork, rollback, steer) so the UI only shows supported actions; usage-limit errors put the task in a `limited` status with the reset time.
- Settings › Tools › Agents lists Registry agents (featured first) to install, update and remove; installed agents update when a project opens. "More agents…" in the provider picker opens it. Registry index and downloads are HTTPS-only, release archives are checked against their sha256, and entries without one show "No checksum provided" and ask for confirmation before installing. Package names from the registry can't be passed as options to npm/uv.

Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
2026-10-29 07:50:04 +08:00
l0ng-ai 96be40cd84 fix(process): Give child processes the host environment inside an AppImage (#118)
Fixes #117

Inside an AppImage, AppRun and the linuxdeploy GTK/GStreamer hooks point LD_LIBRARY_PATH, PATH, XDG_DATA_DIRS, GIO_MODULE_DIR, GTK_PATH, GST_PLUGIN_* … into the mounted image, and every child inherited them, so host programs loaded the image's older libraries (curl + bundled nghttp2 → symbol lookup error when installing Kotlin LSP). ide_core::process::prepare (formerly no_window) now gives children the host environment back: entries inside $APPDIR are dropped (a <NAME>_ORIG wins), emptied variables and the runtime's launch variables are removed, explicit call-site values are kept; the IDE process itself is unchanged. Covers all spawn sites that used no_window plus terminal/run PTYs, run configuration environments and stop commands, login-shell probes, attach ps/kill, docker PATH, tool search PATH and the Linux browser opener. No-op outside an AppImage. Not verified on a Linux AppImage.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-28 13:50:20 +08:00
l0ng-ai 025e0019d2 feat(remote): SSH configurations, SFTP deployment, run targets and remote development (#91) 2026-10-27 23:12:19 +08:00
l0ng-ai 8eb4834a48 fix(lsp): Make the language server tests deterministic (#107)
`ide-lsp` tests failed intermittently (about 1 run in 4, more under load).

The main cause, requests from the other side starting before earlier notifications, is fixed on main by b5bc150; this adds a regression test for it in `ide-jsonrpc`, documents that `on_notification` must not wait for the remote side, and drops the 200 ms polling workaround in `ide-agent` that papered over the same race for `session/request_permission`.

Test-only races fixed: mock replies are held with a gate instead of fixed sleeps and timing asserts; the indexing-retry test ends indexing after the first reply; the crash test counts Ready/Crashed transitions instead of reading the last status; the mock records a notification and applies its effect under one lock; `eventually` waits up to a deadline; `tcp_server` reserves its port with a bound socket and waits for the server's start marker.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 22:15:47 +08:00
l0ng-ai b5bc1501a0 fix(jsonrpc): Start incoming requests after the notifications that preceded them
Requests from the other side were handed to the blocking pool as soon as
they were read, while notifications run in order on their own thread, so a
request could be handled before an earlier didOpen. Requests now start from
the same ordered queue.
2026-10-27 21:38:42 +08:00
l0ng-ai a065189516 fix(lsp): Launch jdtls with java and surface output outside the protocol (#102)
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
2026-10-27 20:44:09 +08:00
l0ng-ai 866af3d9cb fix(agents): Give child processes the login shell's environment
An app started from Finder or the Dock took only PATH from the login shell, so
variables exported in rc files never reached agents, language servers, run
configurations or debug targets. Claude Code configured for Bedrock through
CLAUDE_CODE_USE_BEDROCK / AWS_REGION in ~/.zshrc fell back to the Anthropic API
and failed with 403.

The shell's environment is read once at startup (in the background when PATH
comes from the cache) and kept in memory only, since it may hold secrets. Spawns
add the variables this process lacks before their own.
2026-10-27 17:16:47 +08:00
l0ng-ai e3dae02de7 feat(languages): Add Godot / GDScript support (#73)
Adds GDScript, Godot resource and shader file types with tree-sitter highlighting, the GDScript language server over TCP (a headless Godot editor started on demand), "Godot Project" / current-scene run configurations, and debugging through Godot's debug adapter.

Breakpoints set through symlinked paths (/tmp, /var on macOS) were reported verified but never hit; the adapter now sends resolved paths and maps stack frames back to the paths the IDE opened. The duplicate exit event Godot sends after disconnect is ignored.

Fixes #68

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 15:31:25 +08:00
l0ng-ai 2eaa6cb0c7 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.
2026-10-27 14:44:28 +08:00
l0ng-ai bb9486c758 fix(app): Stop console tools from opening cmd windows on Windows (#20)
Release builds use the GUI subsystem, so a console child spawned without
CREATE_NO_WINDOW gets its own console window. git, gh, docker, builds and
run configurations already set the flag; language servers, SDK and tool
probes, debug adapters, tool downloads, coverage export and perf did not.
Add ide_core::process::no_window and use it at every remaining spawn.

Fixes #16
2026-10-24 16:31:50 +08:00
l0ng-ai 9a2025b76e Initial open-source release
Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-22 18:55:10 +08:00