Commit Graph
941 Commits
Author SHA1 Message Date
l0ng-ai 4f74f22624 fix(ui): Size Select popups to the widest option and truncate the PR repo name
Virtualised list rows are absolutely positioned, so the popup only took the
trigger's width and cut short labels like "Merged". The Pull Requests header
now keeps the repository on one line with an ellipsis and a tooltip.
2026-10-24 10:02:13 +08:00
l0ng-ai 1309ce10e4 chore: v0.1.6 v0.1.6 2026-10-24 09:21:16 +08:00
l0ng-ai 49be259232 fix(ui): Show the full SDK name in selects and shorten Windows home paths
A long detail (an installation path) was not cut, so it pushed the option label out
(e.g. "Eclipse Adopti…", the Maven name hidden) and scrolled the popup sideways. The
label now keeps its width and the detail is cut with an ellipsis (full path in the
tooltip, detail text translated). Paths under C:/Users/<name> are shown as ~/…
2026-10-24 09:11:58 +08:00
l0ng-ai 6a8016b888 fix(vcs): Keep submodule entries out of Rollback and refresh the log of another repository
- Rollback no longer offers a submodule's own entry: it cannot be reverted from the
  enclosing repository (it did nothing while reporting "Rolled back 1 file"). Rolling
  back only that entry explains how to revert it instead.
- A selected change is rolled back alone; only folders take the changes below them, so
  selecting a submodule's entry no longer pulls in the uncommitted files inside it.
- The Git log loads the branches of the newly selected repository, so it reloads when
  that repository's refs move (a new branch showed up only after a manual refresh).
2026-10-24 09:11:58 +08:00
l0ng-ai b8f422d451 fix(vcs): Route a nested repository's own entry to the enclosing one and harden multi-root
Review fixes for several repositories in one project:

- A path equal to a nested repository's root (a submodule's entry, an untracked
  clone) belongs to the enclosing repository, in the backend and the Commit view.
  It was routed to the nested repository as ".", so Rollback ran `git restore` and
  `git clean` over the whole submodule and Commit staged everything in it.
- Repository-scoped commands take the repository root exactly and fail when it is
  gone instead of running in an enclosing repository; path-based ones resolve the
  file's repository (Project::with_repo_of).
- The rescan on a repository appearing or going watches `.git/HEAD`: the watcher
  never reports a `.git` path itself, so the old check never fired.
- Status skips a repository that cannot be read; refresh falls back to the primary
  repository when the selected one is gone instead of failing every time.
- Commit and Compare-with-Local diffs resolve repository-relative paths against the
  selected repository's root, not the project root.
- Update Project and Fetch go on after a failing repository and report the failures
  together; Update skips repositories with a detached HEAD or no upstream.
- The Push dialog leaves out a repository that cannot be read.
- Shelve and patches fail clearly for changes of a nested repository instead of
  leaving them out silently (they still support the main repository only).
- Fix the repository discovery test on Windows (path separators); Chinese text for
  the new strings.
2026-10-23 23:15:09 +08:00
l0ng-ai c868ec8b68 fix(java): Apply the Maven settings to jdtls and Lombok, find more Maven installs
Review fixes for the Project JDK / Maven settings:

- jdtls gets the user settings.xml as java.configuration.maven.userSettings, so the
  editor resolves dependencies through the same mirrors and servers as sync and builds.
- The configured local repository (else <localRepository> of the chosen settings.xml)
  is where the static POM model looks for parent POMs / BOMs and where the Lombok
  agent is looked for.
- Maven discovery finds mvn.cmd on PATH on Windows and the homes Maven Wrapper 3.3+
  downloads (dists/<name>/<hash> without a nested folder).
- A Project JDK pointing at the JDK's bin directory is accepted.
- Detected run configurations reload when language settings change, so Maven and
  Gradle runs use the new JDK, Maven home and options.
- Chinese text for the new settings.
2026-10-23 23:15:09 +08:00
l0ng-ai 059a5193ff feat(vcs): Support several git repositories in one project (multi-root)
Only the repository containing the project root was known, so nested clones and
submodules (or a folder of side-by-side service repositories) showed no changes and
could not be committed or pushed. The project now has IDEA's VCS roots: the enclosing
repository plus those found below the project (scanned in the background, rescanned when
a .git appears or goes). Status covers all of them; path-based commands go to the file's
repository and repository-scoped ones take the selected repository.

The Commit view groups changes by repository and commits each one with included changes;
the branch widget names the selected repository and switches between them; Update Project
and Fetch run in every repository; Push lists every repository with outgoing commits; a
repository that stops in a merge or rebase is selected so Continue / Abort act on it.

Closes #12
2026-10-23 23:15:09 +08:00
l0ng-ai 0f7008391c feat(java): Add Project JDK and Maven home / settings.xml / local repository settings
The JDK was always picked automatically (JAVA_HOME, PATH, the usual install dirs, by the
module's Java version) and Maven was the project's mvnw or mvn on PATH, with no way to
override either. languages.java.jdk (Languages & Frameworks › Java › Project JDK) now sets
the default jdtls runtime, the JDK of Run/Debug and JAVA_HOME for Maven and Gradle;
languages.java.maven (Build Tools › Maven) sets the Maven home, -s and
-Dmaven.repo.local for sync, builds, tool-window goals and detected run configurations.
JDKs and Maven installations are detected for the pickers.

Closes #13
2026-10-23 23:15:09 +08:00
l0ng-ai c59f93988b feat(vcs): PyCharm-style Commit view and one shared message dialog
- workbench/messages: one promise-based ask/confirm/confirmChecked/showError
  host replaces the per-feature confirm dialogs (app, services, vcs,
  project tree, keymap, run, database, find, LSP choice popup).
- Commit tool window: Commit | Shelf | Stash tabs as the title, IDEA's
  toolbar (Update Project, View Options, Select Opened File), Unversioned
  collapsed, Commit / Commit and Push on one row, empty-message error.
- Commit Options popup: author, sign-off, before-commit checks, Git hooks;
  vcs_commit takes CommitOptions (--author, --no-verify).
- Remove from Recent Projects asks first; refused history rewrites show an
  error dialog.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-23 22:59:06 +08:00
l0ng-ai 76d33f0306 feat(ui): IDEA-style message dialogs, project widget popup and Chinese UI text
Message dialogs: `Dialog` gets an `icon` (question / info / warning / error)
that renders IDEA's alert layout: no title bar, a 32px icon, bold title,
text, checkbox under it. Every confirmation helper (prompt, VCS, services,
project tree, keymap, LSP choices, run, database, Replace All) uses it. Open
Project matches IDEA: "This Window" is the default and has focus. The Code
Analysis and TODO commit checks default to Review.

Project widget: the title bar project button opens a popup like IDEA's
ProjectWidget, with Open… / Clone Repository…, the projects open in other
windows (new `window_open_projects` command) and recent projects, filtered by
typing.

Chinese UI: UI text stays written in English and is translated through a
source-text catalog (`locales/text/zh.json`, about 2300 strings). The UI
primitives (buttons, checkboxes, selects, tabs, dialogs, menus, tooltips,
toasts, settings labels and hints) translate the strings they are given.
Action titles and categories are localised in the registry, and static JSX
text uses `<T>`, so text follows a locale switch without a reload. The
Settings window now syncs the locale too. Settings search matches both
languages.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-23 22:18:50 +08:00
l0ng-ai cd55bc8f7f chore: v0.1.5 v0.1.5 2026-10-23 21:38:02 +08:00
l0ng-ai deec86fab9 refactor(perf): Remove the Memory Usage settings page
It was a live metrics view, not a setting, and duplicated the memory
indicator's popup, its status bar toggle and Clear Caches.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-23 21:35:02 +08:00
l0ng-ai 29e89f2525 fix(app): Give the Settings window a plain loader and make the splash bar progress
The Settings window loads the same page as project windows, so it showed the
launch splash with the logo. It now shows only the bar, after 400 ms.

The bar's sliding animation was switched off under reduced motion, leaving a
static 40% fill. It is now a fake progress that eases towards ~90% and fills
to 100% before the splash fades out.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-23 21:31:57 +08:00
l0ng-ai b1bb4a69cd fix(app): Keep the dark theme's background under a fast window resize
splash.css painted html light and only switched body to dark, so the page
canvas showed the light colour wherever a live resize outran relayout.
Leave html unpainted so the canvas takes body's themed background.

Also set the webview's background (not just the native window's) on a
theme change; it otherwise kept the colour the window was created with.
2026-10-23 21:29:45 +08:00
l0ng-ai ee99b3641f fix(ui): Hide the focus outline around dropdown popups
The global :focus-visible rule loads after the module CSS and has the same
specificity, so it overrode `outline: none` on the focused listbox wrapper
and drew a square blue frame inside the Select popup.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-23 21:23:06 +08:00
l0ng-ai 19aee5f262 fix(app): Never show the webview's native context menu (#11)
Right-clicks the app doesn't handle itself, such as on code-lens or inlay
widgets inside the editor or in text fields, fell through to WebKit's own
menu, whose Reload item reloads the whole app. Block it everywhere; the
app's own menus already call preventDefault before this guard runs.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-23 20:02:58 +08:00
l0ng-ai acf6931017 fix(java): Run jdtls with a Lombok agent and show build errors at launch (#9)
* fix(java): Run jdtls with a Lombok agent and show build errors at launch

jdtls compiles with ECJ, which only generates Lombok members when the
server JVM runs -javaagent:lombok.jar. Nothing put it there, so @Data /
@Setter classes lost their accessors and Run launched stale classes
with "Unresolved compilation problem" stubs and no explanation.

- Projects whose build files mention Lombok get the newest jar: the
  IDE-managed one (new "Lombok (jdtls agent)" tool, latest release from
  Maven Central), else ~/.m2 (incl. settings.xml localRepository) or the
  Gradle cache. Each agent gets its own jdtls workspace so everything is
  rebuilt with it.
- Settings › Languages & Frameworks › Java › JVM options
  (java.jdt.ls.vmargs); a Lombok agent there wins.
- Run (and Debug, as a notification) list the first compile errors when
  the build has errors, plus a hint when Lombok is missing or older than
  1.18.34.

Fixes #3

* fix(java): Base the Lombok hint on the agent jdtls actually runs

A Lombok agent in Settings › Java › JVM options wins over the managed
and cached jars, but the launch hint still looked only at those: with
no cached jar it said Lombok was missing, and with an old cached one it
blamed that version although jdtls ran the user's. The hint and the
startup warning now use the user's agent (version from its file name).
2026-10-23 18:46:13 +08:00
l0ng-ai 555ea8901f chore: v0.1.4
Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
v0.1.4
2026-10-23 18:41:02 +08:00
l0ng-ai 769c1248d6 fix(app): Load the splash CSS from a file so release editors keep their styles (#10)
Release builds hash inline <style> blocks from index.html into the CSP.
With a hash present, style-src 'unsafe-inline' is ignored, so CodeMirror's
runtime-injected styles were blocked and the editor rendered blank (bare
line numbers, no text). Dev builds don't rewrite the CSP, so it only
showed in v0.1.3 release bundles.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-23 18:40:49 +08:00
l0ng-ai 61ab1851fa chore: Remove stale .ideal and .vscode folders 2026-10-23 17:48:52 +08:00
l0ng-ai c6a1a36676 chore: v0.1.3
Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
v0.1.3
2026-10-23 17:30:21 +08:00
l0ng-ai 6165cb0174 perf: Add a black-box comparison with other IDEs (#6)
perf/compare/bench.py launches each IDE in apps.toml on the same project
and measures it from the outside, the same way for each: time to the
project window, to CPU settling and to log markers; memory and CPU of the
whole process tree; idle CPU, exit time, cache and install size. Runs on
Windows, macOS and Linux with psutil; --wipe-caches measures a cold index.

README: a Benchmark section with the first results against IntelliJ IDEA.
2026-10-23 16:54:39 +08:00
l0ng-ai 79f6caeaa8 test: Count ignored names in the excluded-folders glob test (#8)
a66f01e adds files.ignoredNames to exclude_globs(), so the expected
length is file_excludes() + 1, not files.exclude + 1. The test failed on
every platform since.
2026-10-23 16:41:18 +08:00
l0ng-ai dbfe66a119 chore: Add generated IDE-state .gitignore files 2026-10-23 15:40:41 +08:00
l0ng-ai a66f01ec87 feat(files): Add Ignored Files and Folders setting, honoured everywhere
Name patterns the IDE treats as nonexistent (.DS_Store, __pycache__, *.pyc, VCS dirs, ...) were hard-coded in five places, and Git changes ignored none of them, so .DS_Store showed up as unversioned. files.ignoredNames (IDEA's default list) now drives the project view, navigation bar, index, watcher, Find in Files, inspections and the Git status.
2026-10-23 15:40:41 +08:00
l0ng-ai bf06ca7832 feat(app): Show a themed splash until the launch project opens
Project windows are created in setup with the saved theme's frame colour, and the splash covers the first render while the launch project opens, so a window no longer flashes white or the Welcome screen. Single-instance is now release-only so a dev build can run beside an installed release.
2026-10-23 15:40:41 +08:00
l0ng-ai 63a03d1c08 fix: Status refresh loop, double project open at startup, jdtls Java requirement (#5)
* fix: Stop the status refresh loop and the double project open at startup

Every status rewrote .git/index, even with nothing to persist: gix's
`write_changes` writes an empty change set too. The watcher reports
.git/index writes as VCS changes, so each status triggered the next one,
together with an ahead/behind walk. On a repository with a long history
(freqtrade, 33k commits behind upstream) that kept a core busy for as long
as the project was open. Write back only when `has_changes()`.

A project passed on the command line was opened twice: the launch and the
"reopen last project" restore ran concurrently, and the restore checked
for an open project before the launch had finished. The second open found
the index cache locked and indexed in memory only; with a different last
project, the window ended up on whichever finished last. The restore now
waits for the startup launch.

* fix(lsp): Run jdtls on the Java version its bundles need

jdtls's launcher checks for Java 21, and so did JDTLS_MIN_JAVA, but the
Eclipse platform a release ships moves on: 1.63 bundles
org.eclipse.core.filesystem with JavaSE-25, so on a JDK 21 the server died
resolving its bundles ("jdtls is not ready (Crashed)") and the error told
users to install the 21 they already had.

Read the requirement from the installed jdtls instead: the highest osgi.ee
capability / Bundle-RequiredExecutionEnvironment among its plugins'
manifests (cached per install), never below 21. The runtime choice, the
rescan while no JDK fits and the "needs JDK N" message use it.

Fixes #4
2026-10-23 15:20:36 +08:00
l0ng-ai 4be1b152ef fix(ui): Drop the inner focus outline on text and search fields
The global :focus-visible outline outranked the module's `outline: none`
by load order, drawing a second ring inside the framed field's own focus
ring (visible on the Settings search box).

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-23 14:52:13 +08:00
l0ng-ai fe498c4b64 chore: v0.1.2 v0.1.2 2026-10-23 11:40:03 +08:00
l0ng-ai 5e3e1f939d fix(lsp): Run jdtls on a JDK 21+ and offer Install in the server popup (#2)
* fix(lsp): Run jdtls on a JDK 21+ and offer Install in the server popup

jdtls refuses to start on Java < 21, and its launcher took whatever
JAVA_HOME / PATH pointed at, so it crash-looped with a Python traceback
when that was an older JDK (#1). Pick the first detected JDK 21+ and pass
it via JAVA_HOME; projects still compile against their own runtimes.
When none is found, report a clear message instead of launching, and
rescan on restart so a newly installed JDK is picked up. JDK detection
now also covers the java on PATH and Windows vendor directories.

The Language Servers status popup showed the manual install hint for
missing servers; it now has an Install button that runs tools.install,
which opens the Language Servers settings page for tools the IDE cannot
install itself.

Fixes #1

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu

* fix(lsp): Address review of the jdtls runtime check

- Cache the JDK scan and rescan at most every 10s while no JDK 21+ is
  found, refreshing the shared list instead of discarding it; skip
  duplicate Windows Program Files roots.
- Check `launch_error` in the manager (inside the blocking launch task)
  rather than in ProcessLauncher, and skip such servers in batch
  inspection.
- Keep the install hint visible next to the Install button; when the tool
  list failed to load, try the install so the error is reported.
- Don't let a server snapshot requested before a status event overwrite
  that newer status (left jdtls showing "Starting…" while missing).
2026-10-23 11:38:51 +08:00
l0ng-ai 3591b52034 docs: Add debugger screenshot 2026-10-23 09:01:29 +08:00
l0ng-ai dd9350e245 build(macos): Notarize the DMG and drop its license prompt; v0.1.1
Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
v0.1.1
2026-10-23 08:12:17 +08:00
l0ng-ai ce9d5cf067 test: Make the Rust suite pass on Windows
Use the Windows wrapper name for Maven, compare walked paths with `/`,
relax the own-process footprint floor, skip tests that assert Unix paths
or shells on Windows, and stop Git converting fixture line endings in CI.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-22 23:34:35 +08:00
l0ng-ai fecdb974ff test: Fix Unix-only assumptions in ide-build tests; run all tests in CI
The Gradle and Maven tests expected the Unix wrapper and command names, and
the canonical-root test uses Unix absolute paths. CI now reports every
failing test instead of stopping at the first few.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
v0.1.0
2026-10-22 22:42:11 +08:00
l0ng-ai 909225858c test(e2e): Run specs with the macOS keymap on every host; update stale specs
CI runs Chromium on Linux, where the workbench picked the Linux keymap and
the ⌘-shortcut specs failed. Present a macOS user agent and platform.
Settings and workbench specs now match the current page tree and stripes.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-22 22:09:08 +08:00
l0ng-ai 3110de8803 fix: Satisfy clippy 1.99 lints
Box the unknown-host-key error variant (result_large_err), decode semantic
tokens with as_chunks, and use `?` for the warning-prefix fallbacks.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-22 22:01:38 +08:00
l0ng-ai b16096acf5 build(macos): Add hardened-runtime entitlements for the plugin JIT
Signed builds run under the hardened runtime, where wasmtime needs JIT
and unsigned executable memory to compile plugins. Also set the minimum
macOS version to 11.0.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-22 21:27:41 +08:00
l0ng-ai 4850cdff5e docs: Embed the product tour as a playable video
Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-22 21:01:44 +08:00
l0ng-ai abbf5478e1 docs: Minimal README with a product tour video
Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-22 20:59:36 +08:00
l0ng-ai 5f6e2a9c85 fix(workbench): Reset project state when a window switches projects
Opening another project in the same window left the previous project's state in
module-level stores: Amend and the commit message carried over, debug sessions kept
running, and Git Log, usages, hierarchy, inspection, HTTP client, recent locations,
navigation history and notifications still showed the old project.

Reset each of them on a project root change, stop the old debug sessions, ask about
unsaved changes before leaving a project, close the settings window (it would apply
to the new project) and end the indexing task when a scan is cancelled.
2026-10-22 20:26:04 +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