* feat(plugin): multi-line text input via ui.input-multiline
Adds host::input_multiline: a multi-line text dialog pre-filled with a
value, dismissed to none, confirmed with Cmd/Ctrl+Enter. Same rules as
input (command or event of a window, no capability, wait not charged).
Prompt::Input gains a multiline flag the frontend renders as a
textarea; the jobs fixture, SDK (wasm + mock), WIT and the plugin API
table are updated, and all plugin wasms rebuilt.
Fixes#1946
* chore: regenerate bindings after merging detail-provider rename
An in-app update restart inherits the old mount's entries alongside the
new one's: the restarted IDE's LD_LIBRARY_PATH holds both mounts, and
children (host curl downloading a language server) still load the old
image's bundled libraries.
appimage_env_fixes now drops ':'-separated entries under any
/tmp/.mount_* path, not just the current $APPDIR's: an entry under a
different mount is another image's, never the host's.
Fixes#1966
* fix(plugin): report missing files as not-found and add project exists/stat
read-file of a missing path now returns error::not-found in the host,
matching the SDK mock, instead of error::invalid. project gains
exists(path) for a cheap existence check (files and directories, hidden
and ignored included) and stat(path) for kind/size/modified, both
gated by project.read and refusing paths outside the root.
Fixes#1957
* chore: silence clippy in sandbox test and rebuild plugin components
- drop an unnecessary to_path_buf clippy flags on unix
- rebuild every checked-in plugin.wasm: the SDK and wit/ changed, so
their source fingerprints moved
* test(plugin): cover missing-file not-found and fix CRLF-only Windows failure
* fix(lsp): drop language servers whose workspace root was deleted (#1726)
A per-root server (e.g. a vtsls rooted at a nested tsconfig dir) is
spawned with its root as the process working directory. On Windows,
once that directory is deleted every spawn fails with os error 267 and
the crash backoff keeps respawning it, leaving a permanently 'Crashed'
entry in the Language Servers panel and a process tree that can never
work again.
- ensure_started: skip starting a server whose root no longer exists.
- on_instance_closed: after a crash, if the root is gone, drop the
server (LanguageServerRemoved) instead of retrying forever.
- restart: return a clear error when the panel restart is pressed for
a server whose root vanished.
- open_for_file_op: skip sampled candidates already deleted on disk.
Fixes#1726
* fix(lsp): drop dead-root servers claimed by ensure_started
A crash with the root still alive enters the restart backoff; if the root
is deleted during that sleep (or an open-file request arrives later),
ensure_started used to return early and leave a permanently "Crashed"
entry: no instance, no watcher, nothing re-arming it. Claim the Idle
server first (begin_start never claims a live one), then drop it when its
root is gone, mirroring on_instance_closed.
Adds root_deleted_during_crash_backoff_drops_the_server, which fails on
the previous code (server never removed) and passes with this fix.
Repo::gix() reopened the cached gitoxide handle only when config or packed-refs changed. An external git fetch/pull/repack writes new packs under objects/pack and moves refs, but never touches those files — so the ODB kept serving the snapshot taken at open, and refs whose tip lived only in the new pack failed to peel: branches vanished and status warned "Could not peel reference". Watch the pack directory's mtime too and reopen when it changes, so externally added objects become visible (issue #1919).
Fixes#1919
* fix(vfs): warn when the inotify watch limit leaves folders unwatched
When watch() hits the OS watch limit mid-tree (inotify ENOSPC/EMFILE), the affected directories were silently never watched: the project stayed stale with no hint. Record the failure on DirState and surface it through the new Watcher::unwatched_reason() — the host emits the 'sync may be slow' warning once the project opens and once on the first event batch after a late failure (deferred walk / update_watches).
Fixes#1915
* fix(vfs): latch the startup watch-limit warning so batches don't repeat it
Two inconsistencies with IDEA's Copy Reference (#1892):
- A language server may bake a signature into a callable's outline name
(jdtls returns DocumentSymbol.name = 'getUserById(int)', the params also
duplicated in detail). The reference then came out as
'pkg.UserService#getUserById(int)' instead of 'pkg.UserService#getUserById'.
Strip the '(…)' suffix for function/method/constructor symbols via a new
declaredName() helper, applied at both chain-mapping sites in
resolveReference.
- Kotlin and Scala joined the whole chain with '.', producing
'pkg.UserService.getUserById' where IDEA emits 'pkg.UserService#getUserById'.
Route them through the same jvmReference() as Java/Groovy so members are
separated from the type path by '#'.
Added tests for both cases and the signature stripping.
* fix(vcs): surface stage/unstage failures instead of swallowing them
The Commit tab's Stage/Unstage items ran the IPC call and only attached a
.finally(refreshNow) handler. call() rejects with IpcError on any backend
failure (require_trust, git add failure, path routing), so the rejection
went unhandled: no notification, no console line, and the UI silently
showed the file still unstaged — reported as 'Stage/Unstage doesn't
work' (#1890).
Route the four handlers through runOp(), the same helper every other
mutating VCS op uses: it logs the command to the Git console, shows an
error balloon with the backend's message on failure, and refreshes the
status afterwards (so the manual .finally is dropped).
This doesn't change the success path; it makes the failure visible, which
is what the reporter needed to diagnose the real backend error.
* fix(vcs): add text catalog entries for the stage/unstage op titles
Extends the VenvTool set with a "Conda Environment" option: the dialog
runs 'conda create -p <location> -y', pinning 'python=<major.minor>' from
the chosen base interpreter when it reports a version. An existing
conda-meta directory is refused before conda runs, and a missing conda
binary reports an install hint instead of a spawn failure.
Refs l0ng-ai/openidea#1724
* feat(sdk): create Python environments with uv and Poetry in Add Interpreter
Add a VenvTool parameter to sdk_python_create_venv so the Add Python
Interpreter dialog can build a new environment with virtualenv, uv or
Poetry, matching what the environment discovery already finds. Poetry
keeps envs in its own cache, so the dialog disables the location field
for it and resolves the interpreter via 'poetry env info --path'.
Fixesl0ng-ai/openidea#1776
* fix(i18n): update text catalogs for the new env-tool strings
The Add Interpreter dialog gained uv/Poetry labels and per-tool notes,
and its spinner text changed from 'Creating virtual environment' to
'Creating environment'. Add the new zh entries and rename the stale
key in every catalog so the text-catalog test passes.
* fix(run): use system python per OS and pytest templates, detect pixi envs
Gutter/context pytest configs on Windows used `python3`, which is not a
command there; fall back to `python` on Windows. Gutter-created pytest
configs now also inherit "Edit configuration templates... > pytest"
values via a template cache populated with the run configurations.
Pixi environments (`.pixi/envs/<env>`) are detected as the project's
Python: as run-configuration env (`PyEnv::Pixi`, tools via
`pixi run` or the env's own executables), as the project interpreter
for scripts/tests and the debugger, and as selectable SDKs, so the
interpreter picked in the IDE feeds completion.
Fixesl0ng-ai/openidea#1885
* fix(run): drop the pytest template's own target in gutter configs
testConfigFor always appends the gutter file, so a target stored on the
template would run twice (template target plus the file). The gutter file is
the target. Also corrects pixi_env's doc comment to the implemented name
order.
Removing a recent project from the title-bar project switcher opened the
Remove confirmation under the still-open switcher popup, which covers the
dialog (the popup layer sits above dialogs). askRemoveRecent and recentMenu
now take a closer, and the switcher passes its own close so the
confirmation lands on top (#1883).
* fix(clipboard): write file names as the copied files' text flavor (#1878)
Ctrl+C on project-view files now pastes the file names into editors and
chat boxes, not the absolute paths. The file list itself (CF_HDROP /
file URLs) still carries the full paths, so pasting into Explorer or a
terminal that reads files keeps working as before. Paths without a file
name (a drive root) keep their whole path.
* test(clipboard): exercise the no-file-name fallback portably
C:/ is a root only on Windows; the Unix and macOS runners read its
file_name as "C:". Use the real filesystem root, which has no file
name on any platform.
Ctrl+C copies the selected changes' file names, Ctrl+Shift+C their
absolute paths, as IDEA does; the context menu gains Copy File Name
beside Copy Path. Applies to every changes tree (Commit tool window,
Git window's Local Changes, Commit dialog) and to the unversioned
group's files too.
* fix(vcs): open Commit dialog diffs in a front window (#1863)
In the modal Commit dialog, activating a changed file opened its diff in an
editor tab behind the dialog, invisible until the dialog closed. Open it in a
front Dialog stacked above instead (IntelliJ's diff window): Esc, the close
button or the close-tab chord returns to the Commit dialog with its message,
selection and options intact.
The dialog reuses DiffEditor with an embedded DiffData, so the full viewer
toolbar (prev/next difference, split/unified, ignore whitespace, highlighting)
is there. Chain navigation (F7 / Shift+F7 past an edge, diff.nextFile /
prevFile) now goes through a new onNeighbour hook instead of openDiff: an
embedded host swaps its own content rather than opening a hidden tab. Only
one diff window is kept, as in IDEA.
* fix(vcs): open the Commit dialog menu's Show Diff in a front window
The dialog-mode context menu still used the global vcs.showDiff action, which
opens an editor tab behind the modal Commit dialog. Route it through the same
front diff dialog as double-click.
run.test.ts's afterEach kills openidea-server and removes its home
directory, but a language server's own process (jdtls's JVM) outlives
the server and keeps writing .metadata underneath it, so the removal
races its writes (ENOTEMPTY). Retries only narrow the window: three
occurrences after the retry bump prove the JVM can linger past them.
The server now spawns detached (its own process group, which its
children inherit), and close() reaps the whole group after the server
exits (SIGKILL + gone-poll on POSIX, taskkill /T /F on Windows), so
the directory removal can't race anyone. debug.test.ts's teardown now
awaits close() too.
The Changes pane took a fixed column next to every agent conversation, including tasks that changed nothing. It is now shown while the task has changes (so it appears when the agent first edits a file) and toggled from a Changes button with the file count in the task header; once toggled, the choice is kept per task.
Co-authored-by: a-rookie-of-C-language <[email protected]>
The merge view blamed both side panes against HEAD, so lines that only exist on the merged branch showed as Not Committed Yet. vcs_blame takes an optional revision (validated, passed to git blame --contents -); the merge view blames Yours on HEAD and Theirs on MERGE_HEAD (swapped during a rebase).
Co-authored-by: a-rookie-of-C-language <[email protected]>
The Push dialog had a fixed size and listed every repository's outgoing commits flat. Dialog gains a resizable option (corner grip, clamped to the viewport, numeric width as the minimum), both Push dialogs use it with the commit list filling the body, and the multi-repository Push dialog shows each repository as a collapsible group (clicking the row still toggles its checkbox).
Fixes#397
Co-authored-by: a-rookie-of-C-language <[email protected]>
Settings opens in its own window with its own state, so reinstalling a tool from a reopened Settings while an earlier install was still running failed with 'already being installed' and showed no progress or Cancel. A second request for the same tool now joins the running install: it receives its live log and result, and cancelling from either request stops it. JDK downloads and uninstalls keep failing fast when busy.
Co-authored-by: a-rookie-of-C-language <[email protected]>
Reload All Maven Projects re-synced only the IDE's build model; jdtls kept its old import, so artifacts that became resolvable meanwhile (mvn install into ~/.m2) stayed missing until its workspace was cleared. After a successful Maven sync, jdtls now receives java/projectConfigurationsUpdate for every project's pom.xml (only if it is already running; failures are logged and don't fail the reload).
Fixes#436
Co-authored-by: a-rookie-of-C-language <[email protected]>
Services listed run configurations only while their session was alive (or when their whole type was added), so after a restart only Spring Boot configurations were back. Configurations that ran are now remembered per project and listed under their type, dimmed until they run again; ids of deleted configurations are ignored.
Fixes#388
Co-authored-by: a-rookie-of-C-language <[email protected]>
The file watcher dropped events for a directory that matched an exclude or .gitignore rule together with its contents, so a target/ or node_modules/ created by a build never appeared in the Project view. The directory's own create/remove now passes through (it shows as excluded/ignored) while its contents stay filtered. Scrollbar lane marks also recompute on viewport changes, since unmeasured line heights shift as more of the document is measured.
Refs #383
Co-authored-by: a-rookie-of-C-language <[email protected]>
The frameless Windows window has no native resize borders, so it couldn't be resized from its edges. Invisible hit areas along the edges and corners start a native resize drag (minimum size and snapping handled by the system); they're omitted while the window is maximized or full screen. Not verified on a real Windows machine.
Refs #410
Co-authored-by: a-rookie-of-C-language <[email protected]>
Compare With… was only in the Project view menu and needed the OS file dialog. The editor context menu (with Compare with Clipboard) and the editor tab menu now offer it too, and outside the desktop app (remote development, browser) a browser file picker supplies the file, compared as text.
Co-authored-by: a-rookie-of-C-language <[email protected]>
Builds and run configurations started a bare mvn / gradle through the app's own PATH, which can be minimal when the app isn't launched from a shell, so launchers installed by mise, asdf or Homebrew weren't found. Bare names now resolve through the configuration's PATH override or the IDE search path (login shell PATH plus version-manager shims) on every platform, for build processes and run configurations alike.
Co-authored-by: a-rookie-of-C-language <[email protected]>
Adds a Scroll to End button to the terminal pane (shown on hover/focus). It reflects whether the viewport follows new output, turns off when you scroll up and back on at the bottom, and clicking it jumps to the end.
Co-authored-by: a-rookie-of-C-language <[email protected]>
A module can activate its parents' profiles with -P, but the Maven model listed only the profiles declared in the module's own POM. Profiles are now collected from the POM and its ancestors (with their activeByDefault state).
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]>
Run console output is flushed on requestAnimationFrame, which stops while the page is hidden, so output from a run in a hidden window piled up and replayed when it was shown again. Pending flushes now move to a 100 ms timeout while hidden and back to rAF when visible.
Co-authored-by: a-rookie-of-C-language <[email protected]>
Opaque diff line and word backgrounds painted over CodeMirror's selection layer, so selected text in a diff was invisible. Text-area diff colours are now translucent mixes of the same tokens (gutters stay opaque), and the left pane's changed text uses the deleted colour.
Co-authored-by: a-rookie-of-C-language <[email protected]>
Repositories created with --object-format=sha256 failed to open because gix was built with SHA-1 only; ide-vcs and ide-vfs now enable gix's sha256 feature. Also adds the missing run.updateApplication entry to the VS Code macOS keymap.
Co-authored-by: a-rookie-of-C-language <[email protected]>
Goal configurations saved from the Maven tool window kept the literal mvn / mvn.cmd, which could not start when Maven lives in a configured home or a version manager's shims. Saved configurations with a bare mvn launcher now take the configured Maven; custom paths and the wrapper are left alone.
Co-authored-by: a-rookie-of-C-language <[email protected]>
When the build files changed since the last sync, the cached effective-POM plugins and resolved dependencies replaced what the POMs declare now, so a just-added dependency never appeared until Reload. The cache is now applied only when the build files are unchanged; a non-verbose cache still marks the model stale without discarding its data.
Co-authored-by: a-rookie-of-C-language <[email protected]>
Names in Settings › Ignored files and folders were hidden only when untracked; their tracked or staged changes still showed in the change list. They are now filtered too, except conflicts, so a merge can't stall on a hidden file.
Co-authored-by: a-rookie-of-C-language <[email protected]>
Each DAP output event copied the whole console array and re-rendered every buffered line, so a debuggee writing continuously to stdout froze the window after tens of thousands of lines. Output is now queued and applied once per animation frame (merged per session and category), the buffer is capped (50,000 entries, plus the console buffer-size setting), and the Debug console renders only the visible rows.
Refs #377
Co-authored-by: a-rookie-of-C-language <[email protected]>
Git no longer asks for the HTTPS user name and password on every fetch, pull and push. The password prompt offers "Remember for this host"; the credential is saved in the app's secret store (next to the saved SSH passwords, never in git's global configuration) only after the git command that used it succeeds, and a stored credential the server rejects is forgotten so the next command asks again. Settings › Version Control › Git lists saved credentials and forgets them.
Each git child gets its own id, passed to the askpass helper, so concurrent commands never save or forget each other's credentials. ide-vcs reports command completion through an observer installed at start-up instead of depending on ide-ssh. Credentials are keyed by scheme, host and port, and only git's authentication errors (Authentication failed, HTTP 401/403 responses, invalid username or password) forget a stored credential.
Fixes#272
Co-authored-by: a-rookie-of-C-language <[email protected]>
Add Configuration had no pytest template although detected and implicit pytest configurations already used the pytest kind. A pytest type now offers Command, Runner arguments, Target and pytest options, and opens existing pytest configurations in that form: pytest itself, `uv/poetry run pytest`, `python -m pytest` (also behind an interpreter prefix such as `uv run python -m pytest`), venv `bin/pytest` and Windows `Scripts\\pytest.exe`. Fields are translated.
Fixes#266
Co-authored-by: a-rookie-of-C-language <[email protected]>
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 <[email protected]>