Some servers reuse one `$/progress` token for concurrent work (PHPantom sends begin, begin, end, end). The second begin overwrote the first task, which never got a done event and stayed at 0% in the background tasks popup. A begin on a token with a live task now ends that task first. The progress map keeps one entry per token, so busy status and idle waits count as before.
Co-authored-by: lleviathe <[email protected]>
Indexed markers (Edges.markers) were always drawn with the navigation glyph,
so a plugin couldn't tell its marker kinds apart. A [[contributes.markerIcons]]
entry can now claim them by key prefix (`markers`), with an optional
`tooltip` shown above the targets. The host matches the longest prefix and
sends the declaration id with each marker; the editor resolves the icon and
the translated tooltip from the projected declaration. Manifest only, under
the existing API 1.3 gate of markerIcons.
Closes#2194
Native Codex sessions never requested `skills/list` or published available commands, so slash completion showed no skills. New, resumed and forked sessions now publish enabled skills as `$<name>`, and `skills/changed` refreshes them. Failed or unsupported requests stay silent.
The Maven and Gradle tool windows disappeared in a workspace, because detection only inspected the workspace metadata folder. They now discover builds in every linked project; models, caches, Maven profile choices, refreshes and run directories use the owning project, and Java reload notifications target its build files. CMake already handled linked projects. Spring's endpoint filter is unchanged.
Fixes#932
Plugin tool windows could only target the primary split of their dock, because the view was never registered as secondary. An optional secondary = true on [[contributes.views]], gated to plugin API 1.3, places a view in Left Bottom, Right Bottom or Bottom Right. Existing plugins stay where they are, and a user's saved layout wins.
Co-authored-by: dengliu <[email protected]>
Launch and attach were cut off after 60 seconds, so a slow interpreter start failed with "debug adapter did not answer launch in time". They now wait for the adapter's result: an adapter error or a closed connection still fails startup, Stop cancels it without an error, and other request deadlines stay.
Fixes#1773
An installed JDK that cannot run, such as an Intel-only JDK on Apple silicon, was registered as a project runtime and could crash Java language server initialization even with a working JDK selected. Each JDK's executable is now probed before selection, off the UI thread and outside the cache lock; unusable JDKs are left out, working Java 8 runtimes stay, and macOS bundle paths are accepted. An explicit choice that cannot run reports its actual executable. Since JDT keeps VM installs in its workspace, a project with an excluded JDK gets one fresh workspace; everyone else keeps their path.
Fixes#1668
Run and Debug now share one Java preparation path: save documents, build with the configured policy, resolve the module classpath and JDK, and stop on a failed build. Incremental Make is the default; Rebuild, NoBuild and Build-no-error-check are persisted on the run configuration, and the form offers only what a build tool supports. Delegated Gradle goes through the same path, Debug reports save failures, Maven snapshots honour Rebuild, and scoped diagnostics are retained so incremental Maven cannot erase compilation errors.
Co-authored-by: misswell <[email protected]>
A child that stopped reading its input could freeze the whole window, because terminal input was written synchronously on the UI thread. Terminal, Run and debug stdin now share a per-session ordered writer queue bounded to 4 MiB and 1,024 writes. An overflow rejects the whole write and shows an error; closing or killing a session discards pending input without waiting for the child, and an explicit stdin EOF drains accepted writes first.
Refs #2160
Fixes found while verifying Ruby debugging. An entry point with no arguments reached Ruby's single-string exec in rdbg, so spaces and shell syntax were interpreted; it now goes through ruby -S -- and stays literal. rdbg sends no DAP output or process events, so its output streams are forwarded and drained at shutdown, and the launched process group is terminated on Stop or a failed start; attach leaves the process alone. Bundler lookup respects BUNDLE_GEMFILE and gems.rb, gem discovery uses the configuration's environment, and the missing debug gem message is translated.
Refs #2170
Co-authored-by: krmbzds <[email protected]>
A lone Alt press always opened or focused the main menu, with no way to
turn it off. Add `appearance.mainMenuAlt` (default on, mirroring IDEA's
ide.windows.main.menu.focus.on.alt) in Appearance > UI options; when off,
Alt key combinations keep working but pressing Alt alone does nothing.
Closesl0ng-ai/openidea#1155
Ruby files, `rails server`, Rake tasks, RSpec and Minitest configurations
can be debugged with rdbg, using the project's Ruby. In a Bundler project
it runs through the bundle; if the bundle lacks the `debug` gem, debugging
stops with an error asking to add `gem "debug"` to the Gemfile.
Reload Changed Classes ran an uncancellable JDT build with a fresh token. The UI now allocates a request id, offers Cancel Hot Swap Build and treats cancellation as cancelled rather than a failed reload; overlapping reloads no longer overwrite the active request. A cancelled build can write class files without publishing their build deltas, so java-debug cannot recover them on the next build: after a cancel, Hot Swap reports that the session needs a restart rather than claiming success with classes left out.
Co-authored-by: misswell <[email protected]>
Four ide-agent tests failed on a Windows machine with a normal setup: skill discovery walked up from a temp project into the real profile's skills, and a fixture repo inherited the global core.autocrlf. The fixtures now bound the walk at the project and turn autocrlf off.
Co-authored-by: panda-student <[email protected]>
Adds Maven toolchains file (-t) and active profiles (-P) settings, emitted before the goals. They combine with the Maven tool window's profile checkboxes, a configuration's own -t or -P overrides them, and repeated launches do not duplicate them. The settings do not reach jdtls's import: no toolchains file or explicit profile deactivation there.
Co-authored-by: misswell <[email protected]>
Adding projects to a workspace took one folder at a time. Choosing a folder that is not itself a project now scans below it, up to four levels and a shared entry budget, without following symlinks or descending into a project and skipping dependency, output and hidden directories. The projects found appear in a checklist with linked ones disabled; a folder with none is added as before. The scan is cancellable and runs in both the create and manage dialogs.
Fixes#2102
Claude Code reports its slash commands only after a session starts, so New Task listed only skills on disk. When the native provider has no remembered commands, a CLI process now runs only the initialize request, with a five-second timeout, shared by concurrent calls, and its result goes into the existing per-project store. A failed attempt keeps the disk list and is not repeated. No prompt or session is created.
ACP and other native providers still report commands after a session starts.
Fixes#2144
The shared twelve-result cap hid commands late in the order, and commands and skills looked the same. Command records now carry a source (stored tasks default to command; disk skills and Codex $skills are marked as skills), and the popup shows every match under Commands and Skills headers in the existing virtualized list, with keyboard selection skipping headers. File completion keeps its cap.
Fixes#2145
Serve the open projects to MCP clients and the IDE's agents: files, search, symbols, problems, edits through IDE documents, run and build with confirmation in the project's window, and Git status and diff.
Co-authored-by: haruka <[email protected]>
Co-authored-by: imacross <[email protected]>
Go files showed no semantic colours because gopls semantic tokens were not requested, and Color Scheme had no Go page.
gopls is now initialised with semantic tokens, constants, package variables and package references get Go-specific roles, and Color Scheme has a Go page with a preview.
Siblings covered: Go-specific attributes inherit from Language Defaults, Reset restores them, Chinese labels show in the Color Scheme tree, and a user's own gopls settings are kept.
Co-authored-by: shohruh-genius <[email protected]>
Kotlin files showed declarations, parameters, fields, annotations, KDoc and escapes in generic lexer colours, because the CodeMirror mode alone drove their highlighting.
Kotlin now gets supplemental backend marks from its tree-sitter grammar, which take precedence over lexer marks while LSP semantic marks stay innermost. The semantic provider also maps the mutable and operator-declaration tokens.
Siblings covered: other grammars keep their parameter colours, and constructor default values are highlighted as values.
Co-authored-by: shohruh-genius <[email protected]>
jdtls reports diagnostics for every imported project, so a module launch was treated as having compile errors because of unrelated sibling modules or its own test sources.
Launch errors now count only the launched module and the modules on its classpath, and application launches ignore test sources. A build with errors becomes a success only when the scope is known and nothing in it fails; if the classpath cannot be resolved, all errors are kept. What a launch does with reported errors is unchanged.
Siblings covered: symlinked and Windows-cased paths, Gradle and Maven output folders, and module paths.
Co-authored-by: misswell <[email protected]>
Removing a worktree could delete the folder the window had open: only the main worktree was blocked, so a linked worktree opened as the project, or one containing the project, went after one confirmation, and Force Remove discarded its changes.
`vcs_remove_worktree` now compares canonical paths and refuses a target that is the project root or an ancestor of it, with or without force, before running git. Worktrees below the project root stay removable, including a project opened on a parent folder.
Sibling covered: the Worktrees tab disables Remove for such a worktree and says why.
Any agent error containing the substring "auth" was replaced by generic sign-in guidance and the agent's own message was dropped, so a real failure could not be told apart and errors about an "author" looked like a sign-in problem.
Sign-in failures are now recognised by ACP's auth-required code or by whole authentication words and phrases. The guidance keeps the agent's text after it, and the code and message are logged. A Registry agent that advertises a terminal login now gets that command for the exact binary being launched.
Siblings covered: session creation, prompts and the native Codex adapter all use the same check.
Refs #2080
Adds Install/Uninstall 'openidea' Command actions. macOS uses the bundle launcher, Windows a user PATH wrapper and named pipe, and Linux the executable/AppImage path with a PATH hint. Files, folders, positions and `diff` go to the running app or start it.
Closes#1286
Co-authored-by: jaw52 <[email protected]>
Reverts #2112. The app icon, its platform sizes and the source SVGs go back to the
version with the light rounded-square backing.
Co-authored-by: Claude <[email protected]>
Laravel ships a first-party language server (laravel/lsp, the one behind
the official VS Code/Zed/Sublime extensions) that answers hover,
definition and completion inside config('…'), route('…') and view('…')
calls — places Intelephense returns null.
Register it in languages/php.toml after Intelephense and the phpactor
fallback (Intelephense keeps hover, rename and symbols for PHP code),
gated by require-root-marker on artisan so it only starts in Laravel
projects — the same pattern angular-language-server uses for
angular.json.
Add a ToolSpec so Settings › Language Servers can install it: GitHub
releases carry plain per-platform binaries (server-v*-<arch>-<os>[.exe]),
which Method::Release + ArchiveKind::Raw already handle; the versioned
asset name lands in bin/ via the usual link/wrapper step. laravel-lsp
runs the project's PHP, so needs stays empty (PHP detection is the
project interpreter's job).
Closes#2100
* fix(icons): drop the light rounded-square backing from the app icon
The source SVGs drew an #EAE7E0 rounded rect behind the mark, which shows
as a pale border/frame around the icon on dark taskbars and in the app
window chrome. Remove the backing rect from both openidea.svg and
openidea-windows.svg, enlarge the mark to fill the canvas (scale 1.55 and
1.8 respectively), and regenerate the raster set with the tauri icon
toolchain.
Closes#2111
* fix(run): skip the drive prefix when canonicalizing verbatim roots
canonical_path walks a path component by component so it can compare a
not-yet-created base with existing sources. On Windows, a verbatim root
(\?\D:\...) puts a bare \?\D: Prefix component first; canonicalizing
that prefix alone fails with ERROR_INVALID_FUNCTION (GetFinalPathNameByHandle
has no directory form for a bare drive), aborting prepare() before any
work — the verbatim-roots test fails on windows-latest.
Skip Component::Prefix: the drive prefix has nothing to canonicalize, and
the RootDir right after it resolves the drive itself.
This fixes the same upstream-main failure tracked in #2057/#2096, scoped
to this branch so the icon change doesn't inherit a red job.
The client only auto-approved permission requests for Cursor's openidea.cursor.approval=bypass setting. Agents whose current mode is full-access / bypassPermissions / yolo, or whose permissions option is on, still showed permission cards while the composer displayed Full Access.\n\nTreat those selected settings as approval bypasses, matching the composer's bypassDefaults. Re-evaluate pending requests when the setting arrives late or changes while a request waits.\n\nCloses #1702
Flatten the agent conversation into a dense tool-window layout and show command approvals as an inline strip with the request's own command (shell wrapper unwrapped), standard buttons and no horizontal overflow.
views.open-log-tab(key, title, process-log) (SDK host::open_log_tab) opens the read-only log tab a web view opens with open-log-tab, from a command or event of a window, reusing the Services pane's process-log.
The host checks the process grant and limits when called and remembers what each key runs in that window; the tab starts it by key (plugin_log_tab_spawn) through the web-view PTY checks: pinned program, trusted project, session cap, lifecycle and grant revocation. Remote windows report that these tabs aren't available there yet.
- workspace.symbols becomes the project method project.symbols(query, limit), like find-files; the Rust SDK's Project::symbols is unchanged, components built against the previous main need a rebuild.
- The open-log-tab web message names its arguments args, as pty-spawn and the services process-log do; baseArgs is refused with log-error rather than ignored.
- Document the hover, semantic-tokens and diagnostics provider exports and their worlds.
Refs #1907
Add Python Interpreter → Existing environment: Browse picks the environment folder, which is resolved right away (pyvenv.cfg, bin/python or Scripts\python.exe) and added to the interpreter list as "Python X.Y (<env name>)", then remembered. Picking the folder rather than the executable keeps the environment's identity, since the native file picker resolves the venv's python symlink to the base interpreter. Works for `python -m venv` and uv environments; a broken environment shows an error instead of being added. Probing runs off the command thread.
Co-authored-by: Inf1mum <[email protected]>
Refs #1538
Show History on a repository with many branches and tags failed on Windows with os error 206 ("文件名或扩展名过长"): default-scope history passed HEAD and every branch/tag tip as argv revisions, and the command line overflowed the ~32K limit. Revisions now count toward the same argv budget as pathspecs; when they overflow, revisions, `--` and paths go through `git log --stdin`. The same bound applies to every history walk in ide-vcs, including the shallow-clone `rev-list`. Small inputs produce the same command as before. Verified on macOS with 1500 tags on a deeply nested file and folder; Windows wasn't run natively.
Co-authored-by: Inf1mum <[email protected]>
Closes#1720
Plugins can declare searchable multi-page settings (API 1.3): pages under the plugin in Settings, groups, string lists, editable tables and command buttons, while single-schema plugins keep working. A command button applies pending edits first and runs against the selected Global/Project layer (also remotely); Reset keeps other pages' edits, and invalid table/list edits never replace saved rows. Field and page order come from the schema without changing serde_json's map ordering elsewhere in the app.
Co-authored-by: arnaud-ritti <[email protected]>
Related #1947
Uninstall keeps a plugin registered but stopped until its private data, secrets and package are cleaned up; a failure is shown and Uninstall can be retried, also after a restart (a durable cleanup record outside the package restores the target). While cleanup is pending, enable, reload, consent, permission changes, reinstall, replacement and rollback are refused. Secret-deletion errors are reported, and cleanup never follows a symlinked ancestor outside plugin storage. The SDK mock checks private-path components and rejects traversal independently of filesystem grants.
Co-authored-by: arnaud-ritti <[email protected]>
A plugin web view can open an editor tab with its own title, language (or file name for detection), content and toolbar actions (API 1.3). Clicking an action sends `{ action, content }` back to the plugin, which replies with new content and/or a status message, or left/right content shown in the IDE's diff viewer. The tab follows the editor document lifecycle: modified marker, close-with-changes prompt, read-only, and saves whose reply arrives after newer edits (or that the plugin rejects) keep the document dirty.
Co-authored-by: dengliu <[email protected]>
A tool-window web view can declare `header = "none"` (API 1.3) to render its own header. The host then replaces the standard header with corner actions (Options, Hide) once the frame has loaded, and tells the frame the corner inset to keep free (CSS variables) so the actions don't cover the plugin's controls. Views without the declaration, and the loading and error states of every view, keep the standard header.
Co-authored-by: dengliu <[email protected]>
Closes#1943
Find Usages and Rename use document-indexer definitions and references next to language-server results. An indexed rename previews every name anchor and applies through the existing atomic workspace edit with grouped undo, guarded by index synchronization, canonical paths and document snapshots; a superseded rename preparation can't revive an obsolete session. Language-server Find Usages and Rename are unchanged. Released WIT is unchanged.
Co-authored-by: arnaud-ritti <[email protected]>
Closes#1948
Plugins receive debounced batches of files created, changed and removed outside the editor in open projects, as SDK `Event::FilesChanged` (delivered through `other("files-changed", …)`, so released WIT is unchanged), under the `events` capability and the plugin's path filters. Activation on these events requires API 1.3. Batches are coalesced per plugin through its actor, survive cancellation without losing deltas, and are dropped when the project or host shuts down.
Co-authored-by: arnaud-ritti <[email protected]>
Refs #1083
A dev container's ports can be forwarded: the Ports tool window shows in a dev container window, `forwardPorts` of devcontainer.json are forwarded on open (keeping the local number when free, falling back otherwise), and ports forwarded by hand are restored per folder and configuration. Each forwarded connection is a loopback listener whose connections run `docker exec … openidea-server --connect localhost <port>` through the container's own network, so no published ports or extra tools in the image are needed. The container tunnel lives in `ide-remote::container_tunnel`; tunnels own their connections and Docker children, so stopping a forward, closing the window or losing the connection leaves no listeners or processes behind (the same ownership fix applies to SSH forwards).
Co-authored-by: andreabasile <[email protected]>
Closes#1947
Adds API 1.3 `fs.plugin-dir`: a persistent owner-only directory per plugin (0700 directories / 0600 files on Unix, owner-only ACL on Windows), separate from the packaged code, storage and secrets. The plugin reads and writes under it without fs.* grants, can open files there in the editor and pass their paths to approved programs; editor saves keep the protection, restart keeps the content, uninstall removes it. Traversal and symlink escapes into other plugins' directories are rejected (real-Wasm regressions).
Co-authored-by: arnaud-ritti <[email protected]>
Whole-line copies and cuts paste above the caret line from every paste entry point (shortcut, menu, history, plain text), including a copied blank line. Paste from History opens a dialog with filter, multi-select, delete and preview. Copy Path/Reference (⇧⌘C) opens a chooser for absolute path, file name, content-root/source-root paths, path with line and reference. Text pasted into a string literal is escaped (Smart Keys setting; Paste as Plain Text bypasses it), and missing imports are added after a paste (Auto Import setting: Ask / Always / Never).
Tasks can be renamed from the list and the tab; an explicitly submitted name is kept. Rerunning the first turn asks before clearing the conversation and resets nested subagent history. Codex questions use the shared question card and keep their ids, so identical questions keep separate answers.
Co-authored-by: panda-student <[email protected]>
`/opt/tool` has no drive letter, so Windows rejects it as non-absolute before the API 1.3 gate the test checks. `~/tool` parses on every platform.
Co-authored-by: a-rookie-of-C-language <[email protected]>
A retired language-server instance could still act after a replacement started: its close or failed startup published Down (a false "restart failed"), and stop/supervisor cleanup cleared the replacement's diagnostics and progress. Retirement now commits state, status, phase and cleanup together for its own generation, with event callbacks ordered outside state locks, and ordinary diagnostics and task events go through the same retirement queue. Verified on macOS with failing-before/passing-after tests and repeated real-server restarts.
Co-authored-by: arnaud-ritti <[email protected]>
The plugin process-environment test looked for Git only on a Windows user PATH, so it failed before reaching its assertions when Git was on the system PATH. It now pins a temporary, deliberately unspawnable file, so both process APIs must reject environment overrides before anything runs, and it uses the platform's key comparison when picking a second inherited variable.
Co-authored-by: arnaud-ritti <[email protected]>
A diagnostics test assumed a cold plugin actor would enter its provider within 10 ms, which failed on slower CI. The fixture is prewarmed and uses synchronous entry gates, so the tests tell a skipped request from a provider that started and hold the provider past the unchanged deadline; adds a test that cancelling a running provider doesn't affect another window's command.
Co-authored-by: arnaud-ritti <[email protected]>