Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ irm https://raw.githubusercontent.com/sunerpy/codegraph-rust/main/scripts/instal
codegraph init /path/to/project # create .codegraph/ and run the first index
codegraph search "<symbol>" -p /path/to/project # full-text symbol search (`query` is a legacy alias)
codegraph serve --mcp --path /path/to/project # MCP server (--path optional, defaults to cwd)
codegraph install --yes --init # wire detected agents + initialize cwd
```

---
Expand Down Expand Up @@ -114,6 +115,7 @@ VS Code, Copilot CLI, JetBrains):

```bash
codegraph install --yes # detects installed agents and wires them up
codegraph install --yes --init # one-shot unattended install + cwd index
```

**MCP tools you can call** (prefer these over grep/read for indexed source):
Expand Down Expand Up @@ -197,9 +199,12 @@ automatically):
```

**Default (no `-p`):** one config works for all your projects — each just needs
`codegraph index` first. The server resolves the project from the client's working
directory or `rootUri`/`workspaceFolders`/`roots`. When it can't resolve one,
`projectPath` is marked required per tool call.
an index first. The stdio server finds an indexed ancestor; from an unindexed
workspace root (`.git` or a workspace manifest), it also adopts exactly one
indexed child project. Multiple candidates are never guessed and are listed in
stderr/tool guidance; pass `projectPath` per call or pin `--path`. Client
`rootUri`/`workspaceFolders`/`roots` remain another adoption path. When no
default resolves, `projectPath` is marked required per tool call.
**Optional `-p <path>`:** pin to one fixed project
(e.g. `"args": ["serve", "--mcp", "-p", "/abs/path/to/project"]`).

Expand All @@ -211,10 +216,16 @@ Gemini CLI, Antigravity IDE, Kiro, Trae, Qoder, Zed, Zuno, VS Code

```bash
codegraph install --yes # auto-detect installed agents
codegraph install --yes --init # wire agents, then initialize cwd
codegraph install --target=claude,cursor --yes # explicit list
codegraph install --target=auto --local # project-local config
codegraph install --target=codex --local --yes # .codex/config.toml + AGENTS.md + local skill
```

Codex project-local configuration is applied only after the repository is
trusted in Codex. `install` never indexes implicitly; only explicit `--init`
does so, and `--print-config` always returns without writing or indexing.

Full MCP tool reference: [`docs/mcp.md`](docs/mcp.md).

---
Expand Down Expand Up @@ -279,7 +290,8 @@ stays live depends on whether the IDE expands `${workspaceFolder}`:
- **Kiro / Qoder** — global entry without `--path`; tools work read-only off the existing index. Run `codegraph init --target=kiro` (or `--target=qoder`) inside each project for live watch.
- **Zed** — global `settings.json` entry without `--path`. Run `codegraph init --target=zed` inside each project to write a `.zed/settings.json` with an absolute `--path` — the only way to give Zed a per-project path. The installer also writes `//`-commented HTTP and SSH alternatives for remote-development use.
- **Zuno** — global config is `$XDG_CONFIG_HOME/zuno/zuno.json[c]` (normally `~/.config/zuno/zuno.json[c]`); project config is `.zuno/zuno.json[c]`. The installer writes `mcp.codegraph` and migrates the older `mcp.codegraph-mcp-server` key without disturbing siblings or JSONC comments.
- **Other agents** (Claude Code, Codex CLI, opencode, Hermes, Gemini CLI, Antigravity) — their native MCP entry shape; live watch where the daemon can reach the project.
- **Codex CLI** — global install keeps `~/.codex/config.toml` + `~/.codex/AGENTS.md`; local install writes `.codex/config.toml`, project-root `AGENTS.md`, and `.agents/skills/codegraph`. Trust the project in Codex to activate its local layer.
- **Other agents** (Claude Code, opencode, Hermes, Gemini CLI, Antigravity) — their native MCP entry shape; live watch where the daemon can reach the project.

> **Zed Remote (SSH).** Zed runs MCP `context_servers` on the local client, not on
> the remote host. If codegraph tools return empty in a remote SSH session, use the
Expand Down
14 changes: 8 additions & 6 deletions crates/codegraph-cli/src/installer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,8 @@ fn resolve_skill_targets(

/// `codegraph skill install`. Writes the embedded skill into each resolved
/// target's skill directory, gating on `supports_skills` (NOT
/// `supports_location` — codex/antigravity support local skills even though
/// their MCP config is global-only).
/// `supports_location` — a target may expose skill locations independently
/// from its MCP config locations).
pub fn run_skill_install(args: SkillArgs) -> Result<()> {
let _ = args.yes;
let ctx = context_from_env()?;
Expand Down Expand Up @@ -913,10 +913,13 @@ mod tests {
}

#[test]
fn run_install_with_ctx_skips_unsupported_location() {
let (ctx, base) = temp_ctx("run-skip");
fn run_install_with_ctx_installs_codex_locally() {
let (ctx, base) = temp_ctx("run-codex-local");
let cwd = ctx.cwd.clone();
run_install_with_ctx(ctx.clone(), install_args("codex", "local")).unwrap();
assert!(!ctx.home.join(".codex").exists());
assert!(cwd.join(".codex/config.toml").exists());
assert!(cwd.join("AGENTS.md").exists());
let _ = fs::remove_dir_all(base);
}

Expand Down Expand Up @@ -978,8 +981,7 @@ mod tests {
let reports = uninstall_targets(&ctx, &[gemini, codex], Location::Local);
assert!(matches!(reports[0].status, UninstallStatus::Removed));
assert!(!reports[0].removed_paths.is_empty());
assert!(matches!(reports[1].status, UninstallStatus::Unsupported));
assert!(!reports[1].notes.is_empty());
assert!(matches!(reports[1].status, UninstallStatus::NotConfigured));

let again = uninstall_targets(&ctx, &[gemini], Location::Local);
assert!(matches!(again[0].status, UninstallStatus::NotConfigured));
Expand Down
Loading
Loading