Files
wehub-resource-sync 26382a7ac6
CI / Test (macos-latest) (push) Waiting to run
CI / Test (windows-latest) (push) Waiting to run
CI / Build (no embeddings / no ORT) (push) Waiting to run
CI / Format (push) Waiting to run
CI / Cookbook (Node) (push) Waiting to run
CI / Pi Extension (Node) (push) Waiting to run
CI / Rust SDK (lean-ctx-client) (push) Waiting to run
CI / Embed SDK (lean-ctx-sdk) (push) Waiting to run
CI / Python SDK (leanctx) (push) Waiting to run
CI / Hermes Plugin (Python) (push) Waiting to run
CI / SDK Conformance Matrix (push) Waiting to run
CI / Coverage (push) Waiting to run
CI / cargo-deny (push) Waiting to run
CI / Adversarial Safety (push) Waiting to run
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
JetBrains Plugin / Actionlint (push) Waiting to run
CI / Benchmarks (push) Waiting to run
CI / Output-Quality Gate (eval A/B) (push) Waiting to run
CI / Documentation (push) Waiting to run
CI / CI Green (push) Blocked by required conditions
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (rust) (push) Waiting to run
JetBrains Plugin / Validation (push) Waiting to run
JetBrains Plugin / Build (push) Waiting to run
JetBrains Plugin / Test (push) Blocked by required conditions
Security Check / Security Scan (push) Waiting to run
CI / Test (ubuntu-latest) (push) Has started running
CI / Clippy (push) Has started running
chore: import upstream snapshot with attribution
2026-07-13 12:35:30 +08:00

262 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Contributing to lean-ctx
Thanks for your interest in lean-ctx — contributions are welcome.
## Spec-driven workflow (non-trivial changes)
lean-ctx develops non-trivial features **spec-anchored** (review-gated SDD):
```text
spec → plan → tasks → implement (impact-first) → verify → evidence
```
1. **Spec**`specs/NNN-<slug>/spec.md` (copy `specs/_template/`); `NNN` = tracking
issue iid, acceptance criteria in EARS. One feature = one dir.
2. **Plan** — draft in your agent's plan mode (e.g. Cursor Plan Mode `Shift+Tab`),
then distill the approved approach into `specs/NNN-<slug>/plan.md`.
Review before coding.
3. **Tasks**`specs/NNN-<slug>/tasks.md`: atomic, individually testable.
4. **Implement** — impact-first: run `ctx_impact` (or `lean-ctx graph impact <file>`)
before editing `rust/src/**` and verify the affected tests.
5. **Verify**`scripts/preflight.sh fast` + the affected tests.
6. **Evidence** — cite the spec in commits (`refs specs/NNN-<slug>`), link issue #NNN.
Skip the full loop for trivial fixes; use it for features, contracts, and anything
touching the tool/CLI surface. See `specs/README.md`.
## Quick start (core Rust binary)
### Prerequisites
- Rust (stable) via [rustup](https://rustup.rs/)
- Git
- A C toolchain (`cc`, plus `cmake` for `aws-lc`) — several dependencies
(jemalloc, `aws-lc`, …) build from source
### Setup
```bash
git clone https://github.com/yvgude/lean-ctx.git
cd lean-ctx/rust
cargo build
cargo test
```
### Quality bar (required)
```bash
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
cargo test --release
```
### Pre-push gate (CI parity)
`make setup-hooks` wires a pre-push hook that runs `scripts/preflight.sh fast`
the deterministic CI jobs (fmt, clippy, rustdoc, generated-docs drift, Windows
cross-compile) mirrored locally so you catch them in seconds, not after a 50-min
matrix. It is **change-aware**: a docs-only push (README, CHANGELOG, `*.md`,
website, …) skips the Rust gates entirely, while CI still runs every job as the
source of truth. Run the full gate (everything + `cargo test --lib`, ignoring the
diff) with `make preflight`. Bypass once with `SKIP_PREFLIGHT=1 git push`.
A change to contract code (`proxy/`, `tools/`, `config/schema/`) that ships no
test signal triggers a **no-test advisory**; export
`LEAN_CTX_PREFLIGHT_STRICT_TESTS=1` to make it blocking.
## Building across worktrees & disk usage
lean-ctx pulls in a **heavy native-dependency tree** (jemalloc, an `aws-lc`
crypto build, tree-sitter grammars, …), so a debug build is larger than the Rust
source alone suggests. A couple of things worth knowing so it doesn't surprise
your disk:
- **Each `git worktree` gets its own `target/`.** Keep several PR checkouts open
and Cargo compiles the full native tree *per worktree*, sharing nothing
between them.
- **`target/debug` never garbage-collects.** Stale incremental units and old
dependency versions accumulate, so one heavily-rebuilt `target/` can reach
**tens of GB** (vs. ~2 GB for a clean build).
### A shared compilation cache (recommended)
[`sccache`](https://github.com/mozilla/sccache) deduplicates dependency compiles
across worktrees and branches, without the build-lock contention a shared
`CARGO_TARGET_DIR` introduces:
```bash
cargo install sccache
export RUSTC_WRAPPER=sccache # add to your shell profile
```
> A single shared `CARGO_TARGET_DIR` also dedups, but Cargo holds a per-target
> build lock, so concurrent builds across worktrees **serialize**.
### Prune stale artifacts
[`cargo-sweep`](https://github.com/holmgr/cargo-sweep) drops build artifacts past
a cutoff so `target/` can't grow without bound:
```bash
cargo install cargo-sweep
cargo sweep --time 7 # remove artifacts unused for > 7 days
```
### Reclaim space fast
`target/` is always safe to delete — it's pure build output and regenerates on
the next build:
```bash
cargo clean # this checkout's target/
du -sh target # check current size
```
Debug info is the bulk of that size: this repo sets
`[profile.dev] debug = "line-tables-only"`, which keeps `file:line` in panics and
backtraces while dropping full variable-level data. Set `debug = 2` in a local
profile override if you need to step-debug.
## Cookbook / SDK / extensions (optional)
If you contribute to `cookbook/` or `packages/`, youll also need:
- Node.js (>= 22.12.0)
- npm
```bash
cd cookbook
npm ci
npm test
```
## Repo structure
```text
lean-ctx/
├─ rust/ # core binary (CLI + MCP server + shell hook)
│ ├─ src/
│ │ ├─ main.rs # CLI entry point
│ │ ├─ lib.rs # library entry point (shared core)
│ │ ├─ mcp_stdio.rs # MCP stdio transport
│ │ ├─ server/ # MCP server state + dispatch
│ │ ├─ tools/ # MCP tool handlers (ctx_read, ctx_shell, ...)
│ │ ├─ core/ # cache, compression, patterns/, memory, graphs, ...
│ │ ├─ cli/ # CLI subcommands (setup, init, read, ...)
│ │ └─ hooks/ # editor/agent installers (Cursor, Claude Code, ...)
│ └─ tests/ # integration/e2e/adversarial tests
├─ cookbook/ # real examples + lean-ctx-client
├─ packages/ # editor integrations (VSCode, Chrome, JetBrains, ...)
├─ docs/ # repo docs (developer-facing)
└─ website/generated/ # generated schemas (tool + TDD schema)
```
## Common contribution types
### Add a shell compression pattern
1. Add a new module in `rust/src/core/patterns/<tool>.rs`
2. Implement:
```rust
pub fn compress(command: &str, output: &str) -> Option<String>
```
3. Register the module + routing in `rust/src/core/patterns/mod.rs` (`try_specific_pattern`)
4. Add tests (unit tests in the module or integration tests in `rust/tests/`)
5. Run the quality checks above
Tip: open a ticket via the [New Compression Pattern](.github/ISSUE_TEMPLATE/compression_pattern.md) template and include raw output + expected compressed output.
### Add or update an MCP tool
- Core handler logic lives in `rust/src/tools/ctx_*.rs` — keep it pure and
deterministic (#498). See `ctx_explore.rs` for the citation-returning
exploration pattern (BM25 + static graph + AST, bounded turns, no session writes).
- The MCP adapter (implements `McpTool`) lives in `rust/src/tools/registered/ctx_*.rs`:
schema via `tool_def`, arg parsing, `ToolOutput`. Register it in
`rust/src/server/registry.rs` and bump the count SSOT in `rust/src/server/mod.rs`
(`test_registry_tool_count_ssot`).
- For a CLI surface, add `rust/src/cli/<name>_cmd.rs` and route it in
`rust/src/cli/dispatch/mod.rs` (+ `dispatch/help.rs`).
- Regenerate and commit the SSOT artifacts:
`cargo run --example gen_mcp_manifest --features dev-tools` and
`cargo run --example gen_docs --features dev-tools`.
- If you change the public tool surface, also update `LEANCTX_FEATURE_CATALOG.md`
(SSOT snapshot). The `entrypoints_wired`, `mcp_manifest_up_to_date` and
`reference_docs_drift` tests gate the wiring end to end.
### Add an addon to the registry
An addon entry in `rust/data/addon_registry.json` ships **executable trust** to
every user (a `stdio` addon runs code on their machine; an `http` addon receives
their context). Registry submissions are therefore reviewed like a security
change, not a docs change. See the
[addon manifest contract](docs/contracts/addon-manifest-v1.md#security-model).
**Your submission must:**
1. Use a unique slug `[a-z0-9-]` and fill `author`, `homepage`, `license`,
`description` (the CI validator rejects installable entries that don't).
2. **Pin the upstream.** No `latest`, no `npx/uvx`-without-a-version. The exact
command + version must be reproducible.
3. Not shell out (`sh -c`, `bash -c`), fetch-and-exec (`curl`, `wget`), or use a
non-HTTPS `url`. The validator flags all of these.
4. Point `homepage` at **public, inspectable source** for the MCP server.
5. Default to the **community** tier (`verified` stays `false`) — verification is
conferred by review, never self-asserted.
Run the validator locally — it runs in CI on every change to the registry:
```bash
cd rust && cargo test --lib addons::registry
```
**Maintainer review checklist (binding):**
- [ ] Source is public and the MCP server's behaviour matches its description.
- [ ] Command/args/url are pinned and reproducible; no shell/fetch primitives.
- [ ] `env` / `headers` carry no embedded secrets; any required secret is the
user's to supply, documented on the homepage.
- [ ] License is a real SPDX id and compatible with redistribution of the entry.
- [ ] `verified = true` requires **two** maintainer approvals **and** a clean
run with **no** `warn`/`danger` finding. Otherwise it stays community-tier.
- [ ] When in doubt, merge as a **listed** entry (no `[mcp]` block) first.
### Docs & examples
- Prefer real, runnable examples (no mock data)
- If you add a new example app, add it under `cookbook/examples/` and ensure it talks to a real `lean-ctx serve` instance
## Issues
- If your issue was closed but the problem persists, comment `/reopen` on it — as the original author, this reopens the issue automatically (GitHub itself does not let authors reopen maintainer-closed issues). The command is matched anywhere in your comment, so "Please `/reopen`" works too; issues closed as *not planned* stay a maintainer call
- Issues closed as *not planned* are maintainer decisions and are not reopened automatically; a comment is still welcome
## Pull requests
- Keep PRs focused (one theme per PR)
- Include a short test plan (commands you ran)
- If relevant, include a small “before/after” token-savings snippet
## Contributor License Agreement (CLA)
Before your first pull request can be merged, you need to sign our
[Contributor License Agreement](CLA.md). It is a one-time, automated step: the
CLA Assistant bot comments on your PR, and you sign by replying:
> I have read the CLA Document and I hereby sign the CLA
The CLA keeps lean-ctx Apache-2.0 for everyone while allowing the maintainer to
relicense (e.g. for the hosted/commercial offering). The free, open-source
runtime for individual developers stays free — that commitment is written into
the CLA itself (§8).
## License
lean-ctx is distributed under the Apache License 2.0; by contributing, your
contributions are licensed to the public under the same terms (see the [CLA](CLA.md)
for the full grant).