mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-06 08:07:49 +00:00
* perf(vcs): filter the Git log with git log instead of a background search index The log built a persistent inverted index of every commit's message, authors and changed paths in the background, with a progress bar above the commit list, and walked trees itself to filter by path. Building it took minutes on large repositories, and filters were slow until it finished. - Text: plain text uses `git log --fixed-strings --grep` (with `--regexp-ignore-case` unless Match Case is on); text of 4+ hex digits also matches hash prefixes. Regex filters still match in-process. - Paths: `git log -- :(literal)<paths>` replaces the in-process path walk and its per-commit tree cache. It uses git's history simplification and, when the repository has a changed-path commit-graph, its Bloom filters. Glob characters in a path are literal. - Authors match against the commit metadata cache. - Removed the search tables, `index_log`, the `vcs_log_index` command and the indexing progress bar. The commit metadata cache stays. * docs(contributing): ask for screenshots only when a change alters what users see Removing a feature together with its UI, copy-only and non-visual changes now describe what was checked instead of attaching before/after screenshots. * fix(vcs): match case-insensitive non-ASCII Git log text in process git folds case only for ASCII under the C locale it runs with, so a case-insensitive filter like "ärger" missed "Ärger". Such text is now matched against commit messages directly. Path and text selection also ignore log.showSignature and log.follow from the user's config.
131 lines
7.8 KiB
Markdown
131 lines
7.8 KiB
Markdown
# OpenIDEA — contributor guide
|
||
|
||
Rust + Tauri 2 desktop IDE with full-featured, multi-language code intelligence.
|
||
Visual style: dark, low-contrast greys, one cool accent
|
||
(`src/styles/tokens.css` is the source of truth for colours and metrics).
|
||
|
||
## Layout
|
||
|
||
- `crates/ide-*` — backend crates; one domain each. Depend on `ide-core` for shared
|
||
types; never reach into another crate's internals.
|
||
- `src-tauri/` — glue only: `state.rs` (AppState / Project), `commands/<domain>.rs`
|
||
(thin typed IPC adapters), `events.rs`. No domain logic here.
|
||
- `src/bindings.ts` — generated by tauri-specta (`pnpm gen:bindings`). Never edit.
|
||
- `src/platform/` — ipc (`call`, `onIdeEvent`, `nextRequestId`), actions registry,
|
||
keymap + dispatcher, context keys / `when` clauses, project store.
|
||
- `src/workbench/contributions.ts` — extension points (tool windows, status items,
|
||
overlays, editor kinds) and cross-feature services (editor, tool windows, notifications).
|
||
- `src/ui/` — design-system primitives. `src/features/<name>/` — one feature each,
|
||
exporting `activate()` registered in `src/features/index.ts`.
|
||
- `languages/<id>.toml` — language definitions (detection, comments, LSP, DAP).
|
||
- `crates/ide-host` — the `openidea-server` binary for remote development and the
|
||
`openidea-plugin` CLI (plugin starter templates live in its `templates.rs`).
|
||
- `wit/` — plugin interface definitions; `plugins/` — sample and bundled plugins.
|
||
Plugin docs: `plugins/README.md`, `docs/plugins/themes.md`.
|
||
- `java/` — JDT LS extension bundles (`java-usages`, `kotlin-bridge`) and the patched
|
||
Lombok agent, embedded into the app by `ide-sdk` / `ide-tools`.
|
||
- `e2e/` — Playwright UI tests (`pnpm e2e`). `fixtures/` — sample projects per language
|
||
for manual and automated testing.
|
||
|
||
## Rules
|
||
|
||
- IPC coordinates: 0-based lines, **UTF-16** columns/offsets everywhere (`ide-core::text`).
|
||
- Every command returns `IdeResult<T>`; convert internal errors at the crate edge.
|
||
- Streaming → `tauri::ipc::Channel<T>`; cancellable → UI-allocated `RequestId` +
|
||
`cancel_request`. Backend → UI notifications → `IdeEvent` via `EventSink`.
|
||
- Long work never blocks the UI thread or a Tauri command thread: use
|
||
`spawn_blocking`/rayon, honour `CancellationToken`.
|
||
- Frontend features never import each other; communicate via actions, contributions
|
||
and services. All user-invocable behaviour is an action with a stable id; default
|
||
shortcuts live in `src/platform/keymaps/`.
|
||
- Styling: CSS Modules + tokens only (no hex literals in components). Inline SVG
|
||
icons from `src/ui/icons.tsx`, never emoji. Real `<button>`/`<input>`; `aria-label` on icon buttons.
|
||
- User-visible text goes through the text catalog: add every new string to both
|
||
`src/platform/locales/text/en.json` and `zh.json` (`textCatalog.test.ts` enforces it).
|
||
Other locales may lack entries; their UI shows the English text until a translator adds it.
|
||
- Keep comments sparse and purposeful; match surrounding style.
|
||
- For GUI verification, prefer Tauri MCP; use Computer Use only when Tauri MCP is
|
||
unavailable or cannot cover the required checks.
|
||
|
||
## Issues & PRs
|
||
|
||
Follow `CONTRIBUTING.md` and `.github/pull_request_template.md`: one problem per PR
|
||
(`Closes #<n>` when it resolves an issue), reproduce first, keep the diff focused, short plain description, and a
|
||
**How it was verified** section with commands run, results and, when the change alters what users
|
||
see, before/after screenshots (not for UI removed along with a feature, copy-only or non-visual changes).
|
||
Unclear product decisions → `needs-decision` and stop.
|
||
|
||
## Skills
|
||
|
||
Shared agent skills live in `.agents/skills/` (`.claude/skills/` links to them):
|
||
`verify` drives the running app through Tauri MCP and captures screenshot evidence;
|
||
`issue-fix` takes an issue from reproduction to one PR.
|
||
|
||
## Commands
|
||
|
||
- `pnpm tauri dev` — run the app with worktree isolation (Node 22.18+).
|
||
`pnpm dev:app` also enables the global Tauri API. `pnpm dev:status` reports
|
||
this worktree's running MCP bridges and actual ports.
|
||
- `pnpm build` — typecheck + bundle frontend.
|
||
- `cargo nextest run --workspace` (or `cargo test`), `cargo clippy --workspace --all-targets -- -D warnings`, `cargo fmt --all`.
|
||
- `cargo test -p ide-host --test language_smoke -- --ignored --exact <language>` — code intelligence
|
||
on `fixtures/` with that language's real server installed (CI: `Language smoke`, pinned versions).
|
||
- `pnpm smoke smoke/run.test.ts -t <language>` — run and test that language's fixture through the
|
||
run store and a real `openidea-server` (build it first: `cargo build -p ide-host --bin openidea-server`).
|
||
- `pnpm smoke smoke/debug.test.ts -t <language>` — debug that fixture's entry point the same way, with
|
||
the debugger the IDE installs (on macOS, CodeLLDB and Delve may need Developer Mode:
|
||
`sudo DevToolsSecurity -enable`).
|
||
- `pnpm test`, `pnpm e2e`, `pnpm lint`, `pnpm format:check`, `pnpm knip`, `pnpm typecheck`,
|
||
`pnpm gen:bindings`.
|
||
- `pnpm perf` (UI interaction latency / frames / leaks), `pnpm perf:rust` (criterion
|
||
benches vs budgets). Budgets: `perf/budgets.json`.
|
||
|
||
## Before opening a PR
|
||
|
||
Run what CI runs for the parts you touched:
|
||
|
||
- Rust: `cargo fmt --all --check`, `cargo clippy --workspace --all-targets -- -D warnings`,
|
||
`cargo nextest run --workspace`. After changing IPC types, run `pnpm gen:bindings` and
|
||
commit `src/bindings.ts`; CI fails if it differs.
|
||
- Frontend: `pnpm typecheck`, `pnpm lint`, `pnpm format:check`, `pnpm knip`, `pnpm test`,
|
||
`pnpm build`, and `pnpm e2e` for UI flows.
|
||
- UI or runtime behaviour: verify in the running app (`.agents/skills/verify`).
|
||
|
||
## Pitfalls
|
||
|
||
- Run a subset of frontend tests with `pnpm vitest run <path>`. `pnpm test -- <path>` ignores
|
||
the filter and runs the whole suite, which takes several minutes.
|
||
- Don't run clippy while iterating: `pnpm tauri dev` compiles anyway. Run
|
||
`cargo fmt --all` + `cargo clippy -p <crate> --all-targets -- -D warnings` once, right
|
||
before committing. A cold build cache can take around 5 minutes. Run long checks one at
|
||
a time, not chained in one shell call that may hit the 10-minute tool timeout.
|
||
- `pnpm tauri dev` does a full debug build. Clippy only checks the code, so a passing clippy
|
||
doesn't make the first launch fast.
|
||
|
||
## Parallel worktrees
|
||
|
||
Several worktrees can be developed and run side by side.
|
||
|
||
- Create one per task: `git worktree add ../<name> -b <branch> origin/main`, then
|
||
`pnpm install` in it.
|
||
- Launch with `pnpm tauri dev` / `pnpm dev:app`, not the raw `pnpm exec tauri dev` CLI. The
|
||
wrapper starts Vite on a worktree-derived port (advancing if occupied), passes its actual
|
||
URL to Tauri, and reports an existing launcher instead of starting another for the same
|
||
worktree. HMR uses the Vite port.
|
||
- Debug app identity, data, settings, logs and single-instance scope follow the canonical
|
||
worktree path captured at build time, independent of launch cwd. Launching the same debug
|
||
binary again focuses its existing instance and forwards its path argument. Different
|
||
worktrees and the installed release can coexist. `--release` uses normal release identity
|
||
and bypasses the development wrapper.
|
||
- MCP bridge ports are dynamic (9223–9322). Use `pnpm dev:status`, connect to the reported
|
||
port, verify identifier/cwd, and pass `appIdentifier: <port>` explicitly. Do not assume the
|
||
default MCP session belongs to this worktree.
|
||
- Keep each worktree's Cargo output directory separate; do not point `CARGO_TARGET_DIR` or
|
||
`target` symlinks at a shared directory.
|
||
- Each worktree's first build is cold (several minutes) and `cargo build` output takes
|
||
around 9 GB; tests, clippy and incremental builds add more. Avoid running several heavy builds on one machine at the same time.
|
||
- Stop only processes started for the current worktree/session. Never use broad
|
||
process-name kills such as `pkill openidea`.
|
||
- When done: stop that worktree's app and dev session, delete its build output, then
|
||
`git worktree remove ../<name>`.
|