|
| 1 | +--- |
| 2 | +name: ecp |
| 3 | +description: Symbol-level code analysis, blast-radius impact, cross-repo API contracts, AST-aware rename, route map for egent-code-plexus. When the question is structural (callers, definitions, impact), ecp is better than grep; for literal strings, config keys, vendored / generated code, or fs layout, grep is better. |
| 4 | +--- |
| 5 | + |
| 6 | +# ecp — egent-code-plexus CLI |
| 7 | + |
| 8 | +`ecp <cmd> [--repo <path>]`. `--repo` 預設 cwd;多 repo 模式必填。`ecp <cmd> --help` 查細節。 |
| 9 | + |
| 10 | +## Layer 1: Directives |
| 11 | + |
| 12 | +### Directive 1: Use the actual help output |
| 13 | +`ecp --help` is the top-level command map. |
| 14 | +`ecp admin --help` is the admin subcommand map. |
| 15 | + |
| 16 | +### Directive 2: Prefer the smallest command that fits |
| 17 | +If a task can be answered by the top-level help or a single subcommand help page, use that before reading broader reference. |
| 18 | + |
| 19 | +### Directive 3: Keep task-specific workflows separate |
| 20 | +Command syntax, review workflows, and broader repository guidance should live in separate guides instead of one large doc. |
| 21 | + |
| 22 | +## Layer 2: Tool Selection |
| 23 | + |
| 24 | +| When the task is | Command | |
| 25 | +|---|---| |
| 26 | +| ONE symbol → signature + body + 1-hop edges + callers + 1-hop impact | `ecp inspect <name> --repo .` | |
| 27 | +| ONE symbol → blast radius | `ecp impact <name> --direction up --repo .` | |
| 28 | +| PR-staged blast radius (diff vs base) | `ecp impact --baseline origin/main --repo .` | |
| 29 | +| Find symbol by name or concept | `ecp find "term" --repo .` (auto bm25/hybrid/vector; force via `--mode`) | |
| 30 | +| Arbitrary graph query / source body | `ecp cypher "MATCH ..." --repo .` (single-repo) | |
| 31 | +| AST-aware multi-file rename | `ecp rename <old> <new> --dry-run --repo .` | |
| 32 | +| HTTP route → handler → upstream callers | `ecp routes [<path>] --repo .` | |
| 33 | +| Cross-repo API contracts (routes / queue / RPC) | `ecp contracts --repo @all` (≥2 repos in group) | |
| 34 | +| HTTP consumer → Route shape drift | `ecp shape-check [--route <path>] --repo .` | |
| 35 | +| Binding / route / contract delta — edge view | `ecp diff --section <bindings\|routes\|contracts\|all> --baseline <ref> --repo .` | |
| 36 | +| Registry health / freshness / blind spots | `ecp coverage [--repo @all --detailed]` | |
| 37 | +| MCP server / install hooks / resolver bench | `ecp admin <sub>` (hidden namespace) | |
| 38 | +| Literal strings, config keys, vendored, generated, fs layout | grep / glob is better than ecp | |
| 39 | + |
| 40 | +`--direction` accepts up/down/both. Impact filters: `--kind --file_path --relation_types --depth --min-confidence --include-tests`. `ecp diff --baseline` accepts branch / tag / SHA / `HEAD~N` / `PR/<n>`; sections combine via `,`. |
| 41 | + |
| 42 | +## Layer 3: Decision Rules (when X, Y is better) |
| 43 | + |
| 44 | +| When | Preferred path | |
| 45 | +|---|---| |
| 46 | +| Looking up a symbol by name | `ecp find` / `ecp inspect` is better than grep + Read (single call → kind + location + signature + body) | |
| 47 | +| Want callers + callees + body in one shot | `ecp inspect <name>` is better than chaining `find` → `cypher` | |
| 48 | +| `find` / `inspect` returns empty but grep matches | Re-running is better than escalating (auto-ensure walks tree). Still empty → `ecp admin index --force --repo .`; else symbol genuinely absent | |
| 49 | +| Impact shows d=1 caller outside the diff | Stop + surface to user is better than silent edit (breakage risk) | |
| 50 | +| Impact returns >15 symbols OR auth / payments / migrations path | Surface risk + suggest test plan is better than blind apply | |
| 51 | +| Refactor crosses repo boundary | `ecp contracts --repo @all --unmatched-only` is better than per-repo scan (orphan consumers visible in one view) | |
| 52 | +| Reference is a string / config key / dynamic dispatch | grep is better than ecp (AST doesn't see strings) | |
| 53 | +| Just edited a file, re-querying same turn | Waiting ~500ms (watcher debounce) or `ecp admin index --force` is better than reading possibly-stale graph | |
| 54 | +| Renaming a symbol called via string assembly | Two-pass — `ecp rename --dry-run` for static + `ecp find "old"` for string sweep — is better than single rename | |
| 55 | +| Renaming touches `.md / .rst / .txt` | `ecp rename --markdown` is better than default (code-only) | |
| 56 | +| High-noise file (many keyword-named idents) | `ecp impact --high-trust-only=true` is better than default impact (filters noise-prone edges) | |
| 57 | + |
| 58 | +## Repo / graph resolution |
| 59 | + |
| 60 | +- `--repo <path>` → registry lookup → `~/.ecp/egent-code-plexus-<hash>/<branch-slug>/graph.bin`. Branch slug = HEAD with `/` → `__`. Day-to-day. |
| 61 | +- `--graph <abs>` → bypass registry (snapshot testing / registry slug mismatch). |
| 62 | +- `--repo @<group> / @all / csv` → cross-repo. Supported on `find / impact / contracts / coverage`. `cypher / inspect` are single-repo (multi-repo 報錯). |
| 63 | +- Group membership: `ecp admin group add <name> --repo <path>` / `ecp admin group list`. |
| 64 | +- Auto-ensure runs on every agent command; first query post-edit pays a ~30s-2min reindex; stderr `✓ Index refreshed (... in Xs)` is informational, not an error. |
| 65 | +- No checked-in graph in cwd → `--repo` is better than default `--graph .ecp/graph.bin` (cwd-relative legacy). |
| 66 | + |
| 67 | +## Output formats |
| 68 | + |
| 69 | +| Command | Default | Other | |
| 70 | +|---|---|---| |
| 71 | +| `inspect / coverage / contracts / routes` | toon | json | |
| 72 | +| `cypher` | json | toon, text | |
| 73 | +| `find / rename / impact` | text | json, toon | |
| 74 | +| `diff / shape-check` | text | json, toon | |
| 75 | + |
| 76 | +For agent → agent piping `toon` is better than json (compact key:value); for script parsing `json` is better; for human inspection `text` is better. |
| 77 | + |
| 78 | +## Cypher subset |
| 79 | + |
| 80 | +`MATCH (a:Kind)-[r:Rel]->(b:Kind) [WHERE ...] RETURN ...` |
| 81 | + |
| 82 | +WHERE: `AND / OR / NOT`, `= != < <= > >=`, `STARTS WITH / ENDS WITH / CONTAINS / =~ / IN [...]`. 支援 `COUNT(*)` / `DISTINCT` / `ORDER BY` / `SKIP` / `LIMIT` / `WITH` / `UNION` / 變長 `[:Rel*1..2]` / 反向 `<-[r:Rel]-`. |
| 83 | + |
| 84 | +**NodeKind** (case-sensitive): `Function Method Class Property Constructor Interface Const Variable Import Route Process Document Section EntryPoint File` |
| 85 | +**RelType** (CamelCase only — `HAS_METHOD` 報 `unknown RelType`): `Calls Extends Imports Implements HasMethod HasProperty Accesses HandlesRoute StepInProcess References Defines Fetches` |
| 86 | +**Node props**: `name uid kind filePath content` · **Edge props**: `rel_type confidence reason` |
| 87 | + |
| 88 | +`HasMethod` target kind 依語言:Python `def` 和 Rust 關聯 fn 是 `Function`;真 method 是 `Method`。`MATCH (c:Class)-[:HasMethod]->(m) RETURN m` 比 `:Method` filter 通用(涵蓋所有語言)。 |
| 89 | + |
| 90 | +## Cypher recipes |
| 91 | + |
| 92 | +```cypher |
| 93 | +-- 未被呼叫的 export |
| 94 | +MATCH (f:Function) WHERE NOT (()-[:Calls]->(f)) AND f.name STARTS WITH 'export_' |
| 95 | +RETURN f.name, f.filePath |
| 96 | +
|
| 97 | +-- Route 的 1-3 hop call chain |
| 98 | +MATCH path = (r:Route {name:'/api/x'})-[:HandlesRoute]->()-[:Calls*1..3]->(leaf) |
| 99 | +RETURN [n IN nodes(path) | n.name] |
| 100 | +``` |
0 commit comments