mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-11-12 08:41:34 +00:00
fix(claude-skills): inline identity contract and sync shipped copies
This commit is contained in:
parent
df73552178
commit
6772350105
20 changed files with 612 additions and 535 deletions
|
|
@ -15,31 +15,35 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|||
|
||||
## Bind the repository first
|
||||
|
||||
A root cause traced in the wrong repository is a wrong root cause. Call
|
||||
`list_repos {}`. With one indexed repository, use the examples below as
|
||||
written. With more than one, pass `repo` explicitly on every call — an omitted
|
||||
`repo` errors, or silently resolves to a configured default — and stop and ask
|
||||
if the intended repository is ambiguous. This matters most for `cypher`, whose
|
||||
statement carries no in-band hint of which database it ran against. See
|
||||
`references/repository-identity.md`.
|
||||
A root cause traced in the wrong repository is a wrong root cause.
|
||||
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask. This matters most for `cypher`, whose
|
||||
statement carries no in-band hint of which database it ran against.
|
||||
|
||||
A stale index describes the code from before your bug, so refresh before
|
||||
trusting a trace, and state the repository and index freshness with the
|
||||
diagnosis.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo (and worktree)
|
||||
1. query({search_query: "<error or symptom>"[, repo: "<repo>"]}) → Find related execution flows
|
||||
2. context({name: "<suspect>"[, repo: "<repo>"]}) → See callers/callees/processes
|
||||
0. list_repos {} → Bind repo
|
||||
1. query({search_query: "<error or symptom>"}) → Find related execution flows
|
||||
2. context({name: "<suspect>"}) → See callers/callees/processes
|
||||
3. READ gitnexus://repo/{name}/process/{name} → Trace execution flow
|
||||
4. cypher({statement: "MATCH path..."[, repo: "<repo>"]}) → Custom traces if needed
|
||||
4. cypher({statement: "MATCH path..."}) → Custom traces if needed
|
||||
```
|
||||
|
||||
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in the bound checkout.
|
||||
> A stale index describes the code before your bug; refresh before trusting a trace.
|
||||
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||
|
||||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when total > 1, ask if ambiguous
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] Understand the symptom (error message, unexpected behavior)
|
||||
- [ ] query for error text or related code
|
||||
- [ ] Identify the suspect function from returned processes
|
||||
|
|
@ -58,7 +62,7 @@ statement carries no in-band hint of which database it ran against. See
|
|||
| Wrong return value | `context` on the function → trace callees for data flow |
|
||||
| Intermittent failure | `context` → look for external calls, async deps |
|
||||
| Performance issue | `context` → find symbols with many callers (hot paths) |
|
||||
| Recent regression | `detect_changes` to see what your changes affect — pass `worktree` if your changes are in a linked worktree |
|
||||
| Recent regression | `detect_changes` to see what your changes affect — pass `worktree` for a linked worktree |
|
||||
| "How does A reach B?" | `trace` between the two symbols — shortest call chain in one call |
|
||||
|
||||
## Tools
|
||||
|
|
@ -84,11 +88,9 @@ context({name: "validatePayment", repo: "my-app"})
|
|||
Cypher text itself names no repository, so the result is unattributable without
|
||||
it:
|
||||
|
||||
```
|
||||
cypher({repo: "my-app", statement: `
|
||||
```cypher
|
||||
MATCH path = (a)-[:CodeRelation {type: 'CALLS'}*1..2]->(b:Function {name: "validatePayment"})
|
||||
RETURN [n IN nodes(path) | n.name] AS chain
|
||||
`})
|
||||
```
|
||||
|
||||
**trace** — shortest call chain between two symbols ("how does A reach B?"), one call instead of chaining `context` hops:
|
||||
|
|
|
|||
|
|
@ -1,86 +0,0 @@
|
|||
# Repository and worktree identity
|
||||
|
||||
This file is the shared identity contract for the per-repository GitNexus
|
||||
skills. `gitnexus-exploring`, `gitnexus-debugging`, `gitnexus-impact-analysis`
|
||||
and `gitnexus-refactoring` carry byte-identical copies so each skill works
|
||||
without relying on another skill's install.
|
||||
|
||||
Two independent questions must be answered before any graph or diff result can
|
||||
be trusted, and a wrong answer to either produces a well-formed report about
|
||||
code you were not asking about:
|
||||
|
||||
- **`repo` — which indexed project.** Every graph tool (`query`, `context`,
|
||||
`impact`, `trace`, `rename`, `cypher`, `explain`, `pdg_query`) runs against
|
||||
exactly one registered repository's database. Registered repositories are
|
||||
independent stores, so the failure is never leakage between them; it is
|
||||
selecting the wrong one.
|
||||
- **`worktree` — which checkout of that project.** Diff-based tools
|
||||
(`detect_changes`) shell out to `git diff` and need a working directory.
|
||||
Linked worktrees share one object store but hold different files and
|
||||
different uncommitted changes.
|
||||
|
||||
## Preflight
|
||||
|
||||
Run once per task, before the first tool call:
|
||||
|
||||
1. Call `list_repos {}` and read `total`.
|
||||
2. If `total` is 1, use that repository; the `repo` argument may be omitted and
|
||||
examples stay as written.
|
||||
3. If `total` is greater than 1, resolve the intended repository and pass
|
||||
`repo` explicitly on **every** subsequent call. Do not infer it from the
|
||||
current working directory, and do not let the server pick: an omitted `repo`
|
||||
normally errors, but under an MCP policy with a configured default it
|
||||
resolves silently to that default.
|
||||
4. If the intended repository cannot be resolved, stop and ask. An ambiguous
|
||||
identity is not a detail to settle later — every result below it inherits
|
||||
the ambiguity.
|
||||
5. If the target repository is absent from `list_repos`, it is not indexed.
|
||||
Index it rather than querying a neighbour that happens to share symbol
|
||||
names.
|
||||
|
||||
`list_repos` is paginated (`limit` default 50, max 200). Page with
|
||||
`offset: pagination.nextOffset` until `hasMore` is false before concluding a
|
||||
repository is absent; `total` is the true count regardless of page size.
|
||||
|
||||
## Worktree
|
||||
|
||||
The server auto-detects a linked worktree only when it was launched from inside
|
||||
that worktree. When the server runs from the canonical root and your changes
|
||||
are in a linked worktree, pass `worktree: "<absolute path>"` to
|
||||
`detect_changes` explicitly.
|
||||
|
||||
Omitting it runs `git diff` in the wrong checkout, which reports zero changed
|
||||
symbols. That zero is indistinguishable in shape from a genuine clean result
|
||||
and reads as a passed check. Confirm the checkout you are editing is the
|
||||
checkout that was diffed before treating any empty change set as evidence.
|
||||
|
||||
## Index freshness
|
||||
|
||||
Identity includes *when*. A correctly bound repository whose index predates the
|
||||
code answers about the old code. Check the staleness signal — `query`,
|
||||
`context`, `impact` and `cypher` attach a `staleness` field with
|
||||
`commitsBehind` when the index is behind HEAD — and refresh with
|
||||
`node .gitnexus/run.cjs analyze --index-only` in the target checkout before
|
||||
trusting results. If `.gitnexus/run.cjs` is missing, fall back to the installed
|
||||
`gitnexus` CLI, then `npx gitnexus`.
|
||||
|
||||
## Echo before claiming
|
||||
|
||||
State the bound identity before reporting conclusions:
|
||||
|
||||
```
|
||||
Repository: <name> (<path>) Worktree: <path> Index: <commit>, <n> behind HEAD
|
||||
```
|
||||
|
||||
Where the identity is partly unresolved, say which part and do not describe the
|
||||
result as a complete graph-backed answer. This mirrors the provenance rule in
|
||||
`gitnexus-review`: the graph and the diff must describe the same code, and a
|
||||
reader must be able to tell from the output whether they did.
|
||||
|
||||
## Scope
|
||||
|
||||
Bind identity for any task that reads or writes a specific repository. Skip it
|
||||
only for questions about GitNexus itself that touch no repository data. When
|
||||
one task legitimately spans two repositories, bind each explicitly and label
|
||||
which repository each result came from; never blend results from different
|
||||
repositories into a single undifferentiated list.
|
||||
|
|
@ -15,35 +15,36 @@ description: "Use when the user asks how code works, wants to understand archite
|
|||
|
||||
## Bind the repository first
|
||||
|
||||
Step 1 discovers what is indexed; the calls after it must say which of those
|
||||
they mean. With one indexed repository, use the examples below as written. With
|
||||
more than one, pass `repo` explicitly on every call — an omitted `repo` errors,
|
||||
or silently resolves to a configured default — and stop and ask if the intended
|
||||
repository is ambiguous. See `references/repository-identity.md`.
|
||||
Step 1 discovers what is indexed; every call after it must say which of those
|
||||
it means. With one indexed repository, use the examples below as written. With
|
||||
more than one, pass `repo` on every call: an omitted `repo` normally errors,
|
||||
but under an MCP policy with a configured default it resolves to that default
|
||||
silently. If you cannot tell which repository is meant, stop and ask. Report
|
||||
the bound repository and index freshness alongside your explanation.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
1. list_repos {} or READ gitnexus://repos → Discover indexed repos; bind one
|
||||
1. list_repos {} or READ gitnexus://repos → Discover indexed repos
|
||||
2. READ gitnexus://repo/{name}/context → Codebase overview, check staleness
|
||||
3. query({search_query: "<what you want to understand>"[, repo: "<repo>"]}) → Find related execution flows
|
||||
4. context({name: "<symbol>"[, repo: "<repo>"]}) → Deep dive on specific symbol
|
||||
3. query({search_query: "<what you want to understand>"}) → Find related execution flows
|
||||
4. context({name: "<symbol>"}) → Deep dive on specific symbol
|
||||
5. READ gitnexus://repo/{name}/process/{name} → Trace full execution flow
|
||||
```
|
||||
|
||||
> If step 2 says "Index is stale" → run `node .gitnexus/run.cjs analyze` in the bound checkout.
|
||||
> If step 2 says "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||
|
||||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when total > 1, ask if ambiguous
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] READ gitnexus://repo/{name}/context
|
||||
- [ ] query for the concept you want to understand
|
||||
- [ ] Review returned processes (execution flows)
|
||||
- [ ] context on key symbols for callers/callees
|
||||
- [ ] READ process resource for full execution traces
|
||||
- [ ] Read source files for implementation details
|
||||
- [ ] State the repository and index freshness alongside the explanation
|
||||
- [ ] State the repository and index freshness with the explanation
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
|
@ -81,7 +82,7 @@ with a single one.
|
|||
|
||||
```
|
||||
1. list_repos {} → total: 1 (my-app) — bind it
|
||||
READ gitnexus://repo/my-app/context → 918 symbols, 45 processes, index current
|
||||
READ gitnexus://repo/my-app/context → 918 symbols, 45 processes
|
||||
2. query({search_query: "payment processing"})
|
||||
→ CheckoutFlow: processPayment → validateCard → chargeStripe
|
||||
→ RefundFlow: initiateRefund → calculateRefund → processRefund
|
||||
|
|
|
|||
|
|
@ -1,86 +0,0 @@
|
|||
# Repository and worktree identity
|
||||
|
||||
This file is the shared identity contract for the per-repository GitNexus
|
||||
skills. `gitnexus-exploring`, `gitnexus-debugging`, `gitnexus-impact-analysis`
|
||||
and `gitnexus-refactoring` carry byte-identical copies so each skill works
|
||||
without relying on another skill's install.
|
||||
|
||||
Two independent questions must be answered before any graph or diff result can
|
||||
be trusted, and a wrong answer to either produces a well-formed report about
|
||||
code you were not asking about:
|
||||
|
||||
- **`repo` — which indexed project.** Every graph tool (`query`, `context`,
|
||||
`impact`, `trace`, `rename`, `cypher`, `explain`, `pdg_query`) runs against
|
||||
exactly one registered repository's database. Registered repositories are
|
||||
independent stores, so the failure is never leakage between them; it is
|
||||
selecting the wrong one.
|
||||
- **`worktree` — which checkout of that project.** Diff-based tools
|
||||
(`detect_changes`) shell out to `git diff` and need a working directory.
|
||||
Linked worktrees share one object store but hold different files and
|
||||
different uncommitted changes.
|
||||
|
||||
## Preflight
|
||||
|
||||
Run once per task, before the first tool call:
|
||||
|
||||
1. Call `list_repos {}` and read `total`.
|
||||
2. If `total` is 1, use that repository; the `repo` argument may be omitted and
|
||||
examples stay as written.
|
||||
3. If `total` is greater than 1, resolve the intended repository and pass
|
||||
`repo` explicitly on **every** subsequent call. Do not infer it from the
|
||||
current working directory, and do not let the server pick: an omitted `repo`
|
||||
normally errors, but under an MCP policy with a configured default it
|
||||
resolves silently to that default.
|
||||
4. If the intended repository cannot be resolved, stop and ask. An ambiguous
|
||||
identity is not a detail to settle later — every result below it inherits
|
||||
the ambiguity.
|
||||
5. If the target repository is absent from `list_repos`, it is not indexed.
|
||||
Index it rather than querying a neighbour that happens to share symbol
|
||||
names.
|
||||
|
||||
`list_repos` is paginated (`limit` default 50, max 200). Page with
|
||||
`offset: pagination.nextOffset` until `hasMore` is false before concluding a
|
||||
repository is absent; `total` is the true count regardless of page size.
|
||||
|
||||
## Worktree
|
||||
|
||||
The server auto-detects a linked worktree only when it was launched from inside
|
||||
that worktree. When the server runs from the canonical root and your changes
|
||||
are in a linked worktree, pass `worktree: "<absolute path>"` to
|
||||
`detect_changes` explicitly.
|
||||
|
||||
Omitting it runs `git diff` in the wrong checkout, which reports zero changed
|
||||
symbols. That zero is indistinguishable in shape from a genuine clean result
|
||||
and reads as a passed check. Confirm the checkout you are editing is the
|
||||
checkout that was diffed before treating any empty change set as evidence.
|
||||
|
||||
## Index freshness
|
||||
|
||||
Identity includes *when*. A correctly bound repository whose index predates the
|
||||
code answers about the old code. Check the staleness signal — `query`,
|
||||
`context`, `impact` and `cypher` attach a `staleness` field with
|
||||
`commitsBehind` when the index is behind HEAD — and refresh with
|
||||
`node .gitnexus/run.cjs analyze --index-only` in the target checkout before
|
||||
trusting results. If `.gitnexus/run.cjs` is missing, fall back to the installed
|
||||
`gitnexus` CLI, then `npx gitnexus`.
|
||||
|
||||
## Echo before claiming
|
||||
|
||||
State the bound identity before reporting conclusions:
|
||||
|
||||
```
|
||||
Repository: <name> (<path>) Worktree: <path> Index: <commit>, <n> behind HEAD
|
||||
```
|
||||
|
||||
Where the identity is partly unresolved, say which part and do not describe the
|
||||
result as a complete graph-backed answer. This mirrors the provenance rule in
|
||||
`gitnexus-review`: the graph and the diff must describe the same code, and a
|
||||
reader must be able to tell from the output whether they did.
|
||||
|
||||
## Scope
|
||||
|
||||
Bind identity for any task that reads or writes a specific repository. Skip it
|
||||
only for questions about GitNexus itself that touch no repository data. When
|
||||
one task legitimately spans two repositories, bind each explicitly and label
|
||||
which repository each result came from; never blend results from different
|
||||
repositories into a single undifferentiated list.
|
||||
|
|
@ -17,37 +17,55 @@ description: "Use when the user wants to know what will break if they change som
|
|||
## Bind the repository first
|
||||
|
||||
Impact analysis is the gate that authorizes an edit, so it must answer for the
|
||||
repository you are about to edit. Call `list_repos {}`. With one indexed
|
||||
repository, use the examples below as written. With more than one, pass `repo`
|
||||
explicitly on every call — an omitted `repo` errors, or silently resolves to a
|
||||
configured default — and stop and ask if the intended repository is ambiguous.
|
||||
Pass `worktree` to `detect_changes` when your changes live in a linked worktree
|
||||
the server was not launched from. See `references/repository-identity.md`.
|
||||
repository you are about to edit.
|
||||
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask — every result below an ambiguous
|
||||
identity inherits the ambiguity. `list_repos` is paginated, so page with
|
||||
`offset: pagination.nextOffset` until `hasMore` is false before concluding a
|
||||
repository is absent.
|
||||
|
||||
`detect_changes` takes `worktree` when your changes are in a linked worktree
|
||||
the MCP server was not launched from. The server auto-detects a worktree only
|
||||
when it was launched from inside one; otherwise `git diff` runs in the wrong
|
||||
checkout and reports zero changed symbols — a false clean check that carries
|
||||
none of the degradation flags described below. In the CLI fallbacks, `--repo .`
|
||||
means the current checkout; pass the intended repository path instead when you
|
||||
are not standing in it.
|
||||
|
||||
State the bound identity with your risk report:
|
||||
|
||||
```
|
||||
Repository: <name> (<path>) Worktree: <path> Index: <commit>, <n> behind HEAD
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo (and worktree)
|
||||
1. impact({target: "X", direction: "upstream"[, repo: "<repo>"]}) or `node .gitnexus/run.cjs impact "X" --direction upstream --repo <path>`
|
||||
1. impact({target: "X", direction: "upstream"}) or `node .gitnexus/run.cjs impact "X" --direction upstream --repo .`
|
||||
2. READ gitnexus://repo/{name}/processes → Check affected execution flows
|
||||
3. detect_changes({scope: "all"[, repo: "<repo>"][, worktree: "<path>"]}) or `node .gitnexus/run.cjs detect-changes --scope all --repo <path>`
|
||||
4. Assess risk and report to user, echoing the bound repo/worktree/index
|
||||
3. detect_changes({scope: "all"}) or `node .gitnexus/run.cjs detect-changes --scope all --repo .`
|
||||
4. Assess risk and report to user, echoing repo/worktree/index identity
|
||||
```
|
||||
|
||||
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in the bound checkout.
|
||||
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||
> If `.gitnexus/run.cjs` is missing, replace `node .gitnexus/run.cjs` with `npx gitnexus` in the fallback commands.
|
||||
|
||||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when total > 1, ask if ambiguous
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] impact({target, direction: "upstream"}) or CLI fallback to find dependents
|
||||
- [ ] Review d=1 items first (these WILL BREAK)
|
||||
- [ ] Check high-confidence (>0.8) dependencies
|
||||
- [ ] READ processes to check affected execution flows
|
||||
- [ ] detect_changes({scope: "all"}) or CLI fallback for pre-commit check
|
||||
- [ ] Confirm the checkout you edited is the checkout that was diffed
|
||||
- [ ] Assess risk level and report, stating repo/worktree/index freshness
|
||||
- [ ] Assess risk level and report, stating repo/worktree/index identity
|
||||
```
|
||||
|
||||
## Understanding Output
|
||||
|
|
@ -77,7 +95,7 @@ treating the symbol as safe to change or delete.
|
|||
|
||||
## Tools
|
||||
|
||||
**impact** — the primary tool for symbol blast radius. If MCP is unavailable, use `node .gitnexus/run.cjs impact <symbol> --direction upstream --repo <path>` instead:
|
||||
**impact** — the primary tool for symbol blast radius. If MCP is unavailable, use `node .gitnexus/run.cjs impact <symbol> --direction upstream --repo .` instead:
|
||||
|
||||
```
|
||||
impact({
|
||||
|
|
@ -96,27 +114,28 @@ impact({
|
|||
- authRouter (src/routes/auth.ts:22) [CALLS, 95%]
|
||||
```
|
||||
|
||||
**detect_changes** — git-diff based impact analysis. If MCP is unavailable, use `node .gitnexus/run.cjs detect-changes --scope all --repo <path>` instead:
|
||||
**detect_changes** — git-diff based impact analysis. If MCP is unavailable, use `node .gitnexus/run.cjs detect-changes --scope all --repo .` instead:
|
||||
|
||||
```
|
||||
detect_changes({scope: "all", repo: "my-app", worktree: "/abs/path/to/checkout"})
|
||||
detect_changes({scope: "all"})
|
||||
|
||||
→ Changed: 5 symbols in 3 files
|
||||
→ Affected: LoginFlow, TokenRefresh, APIMiddlewarePipeline
|
||||
→ Risk: MEDIUM
|
||||
```
|
||||
|
||||
`repo` is required once more than one repository is indexed. `worktree` is
|
||||
needed when your changes are in a linked worktree the MCP server was not
|
||||
launched from — omit it there and `git diff` runs in the wrong checkout,
|
||||
reporting zero changed symbols for a tree full of edits.
|
||||
Add `repo` once more than one repository is indexed, and `worktree: "<abs
|
||||
path>"` when your changes are in a linked worktree the server was not launched
|
||||
from.
|
||||
|
||||
`partial: true` (a graph query failed) or `truncated: true` (the changed-symbol
|
||||
listing was capped) means the result is short of the truth, and reads like
|
||||
`UNKNOWN` above: a zero there means unseen, not unaffected. A wrong-worktree
|
||||
zero carries none of those flags and looks exactly like a clean result, so
|
||||
confirm the checkout you edited is the checkout that was diffed. Re-run it
|
||||
rather than tick the pre-commit check.
|
||||
`UNKNOWN` above: a zero there means unseen, not unaffected. Re-run it rather
|
||||
than tick the pre-commit check.
|
||||
|
||||
A wrong-worktree zero carries neither flag and is shape-identical to a genuine
|
||||
clean result, so confirm the checkout you edited is the one that was diffed
|
||||
before treating an empty change set as a passed check.
|
||||
|
||||
## Example: "What breaks if I change validateUser?"
|
||||
|
||||
|
|
@ -124,8 +143,7 @@ rather than tick the pre-commit check.
|
|||
0. list_repos {}
|
||||
→ total: 2 (my-app, billing-api) — both define validateUser, so bind explicitly
|
||||
|
||||
1. impact({target: "validateUser", repo: "my-app", direction: "upstream"})
|
||||
or `node .gitnexus/run.cjs impact "validateUser" --direction upstream --repo /abs/path/my-app`
|
||||
1. impact({target: "validateUser", repo: "my-app", direction: "upstream"}) or `node .gitnexus/run.cjs impact "validateUser" --direction upstream --repo .`
|
||||
→ d=1: loginHandler, apiMiddleware (WILL BREAK)
|
||||
→ d=2: authRouter, sessionManager (LIKELY AFFECTED)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,86 +0,0 @@
|
|||
# Repository and worktree identity
|
||||
|
||||
This file is the shared identity contract for the per-repository GitNexus
|
||||
skills. `gitnexus-exploring`, `gitnexus-debugging`, `gitnexus-impact-analysis`
|
||||
and `gitnexus-refactoring` carry byte-identical copies so each skill works
|
||||
without relying on another skill's install.
|
||||
|
||||
Two independent questions must be answered before any graph or diff result can
|
||||
be trusted, and a wrong answer to either produces a well-formed report about
|
||||
code you were not asking about:
|
||||
|
||||
- **`repo` — which indexed project.** Every graph tool (`query`, `context`,
|
||||
`impact`, `trace`, `rename`, `cypher`, `explain`, `pdg_query`) runs against
|
||||
exactly one registered repository's database. Registered repositories are
|
||||
independent stores, so the failure is never leakage between them; it is
|
||||
selecting the wrong one.
|
||||
- **`worktree` — which checkout of that project.** Diff-based tools
|
||||
(`detect_changes`) shell out to `git diff` and need a working directory.
|
||||
Linked worktrees share one object store but hold different files and
|
||||
different uncommitted changes.
|
||||
|
||||
## Preflight
|
||||
|
||||
Run once per task, before the first tool call:
|
||||
|
||||
1. Call `list_repos {}` and read `total`.
|
||||
2. If `total` is 1, use that repository; the `repo` argument may be omitted and
|
||||
examples stay as written.
|
||||
3. If `total` is greater than 1, resolve the intended repository and pass
|
||||
`repo` explicitly on **every** subsequent call. Do not infer it from the
|
||||
current working directory, and do not let the server pick: an omitted `repo`
|
||||
normally errors, but under an MCP policy with a configured default it
|
||||
resolves silently to that default.
|
||||
4. If the intended repository cannot be resolved, stop and ask. An ambiguous
|
||||
identity is not a detail to settle later — every result below it inherits
|
||||
the ambiguity.
|
||||
5. If the target repository is absent from `list_repos`, it is not indexed.
|
||||
Index it rather than querying a neighbour that happens to share symbol
|
||||
names.
|
||||
|
||||
`list_repos` is paginated (`limit` default 50, max 200). Page with
|
||||
`offset: pagination.nextOffset` until `hasMore` is false before concluding a
|
||||
repository is absent; `total` is the true count regardless of page size.
|
||||
|
||||
## Worktree
|
||||
|
||||
The server auto-detects a linked worktree only when it was launched from inside
|
||||
that worktree. When the server runs from the canonical root and your changes
|
||||
are in a linked worktree, pass `worktree: "<absolute path>"` to
|
||||
`detect_changes` explicitly.
|
||||
|
||||
Omitting it runs `git diff` in the wrong checkout, which reports zero changed
|
||||
symbols. That zero is indistinguishable in shape from a genuine clean result
|
||||
and reads as a passed check. Confirm the checkout you are editing is the
|
||||
checkout that was diffed before treating any empty change set as evidence.
|
||||
|
||||
## Index freshness
|
||||
|
||||
Identity includes *when*. A correctly bound repository whose index predates the
|
||||
code answers about the old code. Check the staleness signal — `query`,
|
||||
`context`, `impact` and `cypher` attach a `staleness` field with
|
||||
`commitsBehind` when the index is behind HEAD — and refresh with
|
||||
`node .gitnexus/run.cjs analyze --index-only` in the target checkout before
|
||||
trusting results. If `.gitnexus/run.cjs` is missing, fall back to the installed
|
||||
`gitnexus` CLI, then `npx gitnexus`.
|
||||
|
||||
## Echo before claiming
|
||||
|
||||
State the bound identity before reporting conclusions:
|
||||
|
||||
```
|
||||
Repository: <name> (<path>) Worktree: <path> Index: <commit>, <n> behind HEAD
|
||||
```
|
||||
|
||||
Where the identity is partly unresolved, say which part and do not describe the
|
||||
result as a complete graph-backed answer. This mirrors the provenance rule in
|
||||
`gitnexus-review`: the graph and the diff must describe the same code, and a
|
||||
reader must be able to tell from the output whether they did.
|
||||
|
||||
## Scope
|
||||
|
||||
Bind identity for any task that reads or writes a specific repository. Skip it
|
||||
only for questions about GitNexus itself that touch no repository data. When
|
||||
one task legitimately spans two repositories, bind each explicitly and label
|
||||
which repository each result came from; never blend results from different
|
||||
repositories into a single undifferentiated list.
|
||||
|
|
@ -17,72 +17,72 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|||
|
||||
Refactoring writes to disk. `rename` with `dry_run: false` edits files in
|
||||
whichever repository was resolved, so binding identity here is a safety gate,
|
||||
not bookkeeping. Call `list_repos {}`. With one indexed repository, use the
|
||||
examples below as written. With more than one, pass `repo` explicitly on every
|
||||
call — an omitted `repo` errors, or silently resolves to a configured default —
|
||||
and stop and ask if the intended repository is ambiguous. Pass `worktree` to
|
||||
`detect_changes` when you are editing a linked worktree the server was not
|
||||
launched from. See `references/repository-identity.md`.
|
||||
not bookkeeping.
|
||||
|
||||
Never run `rename` with `dry_run: false` until the preview in the same bound
|
||||
repository has been reviewed.
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask. Never run `rename` with
|
||||
`dry_run: false` until the preview in the same bound repository has been
|
||||
reviewed — its returned `file_path` values show which checkout is about to be
|
||||
written, so read them as a confirmation of identity.
|
||||
|
||||
`detect_changes` takes `worktree` when you are editing a linked worktree the
|
||||
MCP server was not launched from; otherwise `git diff` runs in the wrong
|
||||
checkout and reports nothing changed, which reads as a verified refactor.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo (and worktree)
|
||||
1. impact({target: "X", direction: "upstream"[, repo: "<repo>"]}) → Map all dependents
|
||||
2. query({search_query: "X"[, repo: "<repo>"]}) → Find execution flows involving X
|
||||
3. context({name: "X"[, repo: "<repo>"]}) → See all incoming/outgoing refs
|
||||
1. impact({target: "X", direction: "upstream"}) → Map all dependents
|
||||
2. query({search_query: "X"}) → Find execution flows involving X
|
||||
3. context({name: "X"}) → See all incoming/outgoing refs
|
||||
4. Plan update order: interfaces → implementations → callers → tests
|
||||
```
|
||||
|
||||
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in the bound checkout.
|
||||
> A stale index under a rename means edits planned against code that has moved.
|
||||
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||
|
||||
## Checklists
|
||||
|
||||
### Rename Symbol
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when total > 1, ask if ambiguous
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] rename({symbol_name: "oldName", new_name: "newName", dry_run: true}) — preview all edits
|
||||
- [ ] Confirm the previewed file paths are in the bound repository/worktree
|
||||
- [ ] Review graph edits (high confidence) and text_search edits (review carefully)
|
||||
- [ ] If satisfied: rename({..., dry_run: false}) — apply edits
|
||||
- [ ] detect_changes({scope: "all"}) — verify only expected files changed
|
||||
- [ ] detect_changes() — verify only expected files changed
|
||||
- [ ] Run tests for affected processes
|
||||
```
|
||||
|
||||
### Extract Module
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when total > 1, ask if ambiguous
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] context({name: target}) — see all incoming/outgoing refs
|
||||
- [ ] impact({target, direction: "upstream"}) — find all external callers
|
||||
- [ ] Define new module interface
|
||||
- [ ] Extract code, update imports
|
||||
- [ ] detect_changes({scope: "all"}) — verify affected scope
|
||||
- [ ] detect_changes() — verify affected scope
|
||||
- [ ] Run tests for affected processes
|
||||
```
|
||||
|
||||
### Split Function/Service
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when total > 1, ask if ambiguous
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] context({name: target}) — understand all callees
|
||||
- [ ] Group callees by responsibility
|
||||
- [ ] impact({target, direction: "upstream"}) — map callers to update
|
||||
- [ ] Create new functions/services
|
||||
- [ ] Update callers
|
||||
- [ ] detect_changes({scope: "all"}) — verify affected scope
|
||||
- [ ] detect_changes() — verify affected scope
|
||||
- [ ] Run tests for affected processes
|
||||
```
|
||||
|
||||
Each `detect_changes` above takes `worktree` when the checkout you edited is
|
||||
not the one the MCP server was launched from. Without it the diff runs in the
|
||||
wrong tree and reports nothing changed, which reads as a verified refactor.
|
||||
|
||||
## Tools
|
||||
|
||||
**rename** — automated multi-file rename:
|
||||
|
|
@ -94,10 +94,6 @@ rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app
|
|||
→ Changes: [{file_path, edits: [{line, old_text, new_text, confidence}]}]
|
||||
```
|
||||
|
||||
Read the returned `file_path` values as a confirmation of identity: they show
|
||||
which checkout is about to be written. If they are not the paths you intend,
|
||||
stop — do not re-run with `dry_run: false`.
|
||||
|
||||
**impact** — map all dependents first:
|
||||
|
||||
```
|
||||
|
|
@ -109,7 +105,7 @@ impact({target: "validateUser", repo: "my-app", direction: "upstream"})
|
|||
**detect_changes** — verify your changes after refactoring:
|
||||
|
||||
```
|
||||
detect_changes({scope: "all", repo: "my-app", worktree: "/abs/path/to/checkout"})
|
||||
detect_changes({scope: "all"})
|
||||
→ Changed: 8 files, 12 symbols
|
||||
→ Affected processes: LoginFlow, TokenRefresh
|
||||
→ Risk: MEDIUM
|
||||
|
|
@ -117,19 +113,17 @@ detect_changes({scope: "all", repo: "my-app", worktree: "/abs/path/to/checkout"}
|
|||
|
||||
`partial: true` (a graph query failed) or `truncated: true` (the changed-symbol
|
||||
listing was capped) means the result is short of the truth: a short or empty
|
||||
list is not proof that only the expected files changed. A wrong-worktree zero
|
||||
carries neither flag and is indistinguishable from a clean verification, so
|
||||
confirm the diffed checkout is the one you edited. Re-run it rather than treat
|
||||
the refactor as verified.
|
||||
list is not proof that only the expected files changed. Re-run it rather than
|
||||
treat the refactor as verified.
|
||||
|
||||
**cypher** — custom reference queries. Pass `repo` alongside the statement; the
|
||||
Cypher text names no repository:
|
||||
A wrong-worktree zero carries neither flag and is indistinguishable from a
|
||||
clean verification, so confirm the diffed checkout is the one you edited.
|
||||
|
||||
```
|
||||
cypher({repo: "my-app", statement: `
|
||||
**cypher** — custom reference queries:
|
||||
|
||||
```cypher
|
||||
MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "validateUser"})
|
||||
RETURN caller.name, caller.filePath ORDER BY caller.filePath
|
||||
`})
|
||||
```
|
||||
|
||||
## Risk Rules
|
||||
|
|
@ -140,7 +134,7 @@ RETURN caller.name, caller.filePath ORDER BY caller.filePath
|
|||
| Cross-area refs | Use detect_changes after to verify scope |
|
||||
| String/dynamic refs | query to find them |
|
||||
| External/public API | Version and deprecate properly |
|
||||
| Same symbol name in another indexed repo | Bind `repo` explicitly; verify previewed paths before applying |
|
||||
| Same name in another indexed repo | Bind `repo`; verify previewed paths before applying |
|
||||
|
||||
## Example: Rename `validateUser` to `authenticateUser`
|
||||
|
||||
|
|
@ -148,16 +142,13 @@ RETURN caller.name, caller.filePath ORDER BY caller.filePath
|
|||
0. list_repos {}
|
||||
→ total: 2 (my-app, billing-api) — both define validateUser, so bind explicitly
|
||||
|
||||
1. rename({symbol_name: "validateUser", new_name: "authenticateUser",
|
||||
repo: "my-app", dry_run: true})
|
||||
1. rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: true})
|
||||
→ 12 edits: 10 graph (safe), 2 text_search (review)
|
||||
→ Files: validator.ts, login.ts, middleware.ts, config.json...
|
||||
→ Paths are under /abs/path/my-app — the intended checkout ✓
|
||||
|
||||
2. Review text_search edits (config.json: dynamic reference!)
|
||||
|
||||
3. rename({symbol_name: "validateUser", new_name: "authenticateUser",
|
||||
repo: "my-app", dry_run: false})
|
||||
3. rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: false})
|
||||
→ Applied 12 edits across 8 files
|
||||
|
||||
4. detect_changes({scope: "all", repo: "my-app"})
|
||||
|
|
|
|||
|
|
@ -1,86 +0,0 @@
|
|||
# Repository and worktree identity
|
||||
|
||||
This file is the shared identity contract for the per-repository GitNexus
|
||||
skills. `gitnexus-exploring`, `gitnexus-debugging`, `gitnexus-impact-analysis`
|
||||
and `gitnexus-refactoring` carry byte-identical copies so each skill works
|
||||
without relying on another skill's install.
|
||||
|
||||
Two independent questions must be answered before any graph or diff result can
|
||||
be trusted, and a wrong answer to either produces a well-formed report about
|
||||
code you were not asking about:
|
||||
|
||||
- **`repo` — which indexed project.** Every graph tool (`query`, `context`,
|
||||
`impact`, `trace`, `rename`, `cypher`, `explain`, `pdg_query`) runs against
|
||||
exactly one registered repository's database. Registered repositories are
|
||||
independent stores, so the failure is never leakage between them; it is
|
||||
selecting the wrong one.
|
||||
- **`worktree` — which checkout of that project.** Diff-based tools
|
||||
(`detect_changes`) shell out to `git diff` and need a working directory.
|
||||
Linked worktrees share one object store but hold different files and
|
||||
different uncommitted changes.
|
||||
|
||||
## Preflight
|
||||
|
||||
Run once per task, before the first tool call:
|
||||
|
||||
1. Call `list_repos {}` and read `total`.
|
||||
2. If `total` is 1, use that repository; the `repo` argument may be omitted and
|
||||
examples stay as written.
|
||||
3. If `total` is greater than 1, resolve the intended repository and pass
|
||||
`repo` explicitly on **every** subsequent call. Do not infer it from the
|
||||
current working directory, and do not let the server pick: an omitted `repo`
|
||||
normally errors, but under an MCP policy with a configured default it
|
||||
resolves silently to that default.
|
||||
4. If the intended repository cannot be resolved, stop and ask. An ambiguous
|
||||
identity is not a detail to settle later — every result below it inherits
|
||||
the ambiguity.
|
||||
5. If the target repository is absent from `list_repos`, it is not indexed.
|
||||
Index it rather than querying a neighbour that happens to share symbol
|
||||
names.
|
||||
|
||||
`list_repos` is paginated (`limit` default 50, max 200). Page with
|
||||
`offset: pagination.nextOffset` until `hasMore` is false before concluding a
|
||||
repository is absent; `total` is the true count regardless of page size.
|
||||
|
||||
## Worktree
|
||||
|
||||
The server auto-detects a linked worktree only when it was launched from inside
|
||||
that worktree. When the server runs from the canonical root and your changes
|
||||
are in a linked worktree, pass `worktree: "<absolute path>"` to
|
||||
`detect_changes` explicitly.
|
||||
|
||||
Omitting it runs `git diff` in the wrong checkout, which reports zero changed
|
||||
symbols. That zero is indistinguishable in shape from a genuine clean result
|
||||
and reads as a passed check. Confirm the checkout you are editing is the
|
||||
checkout that was diffed before treating any empty change set as evidence.
|
||||
|
||||
## Index freshness
|
||||
|
||||
Identity includes *when*. A correctly bound repository whose index predates the
|
||||
code answers about the old code. Check the staleness signal — `query`,
|
||||
`context`, `impact` and `cypher` attach a `staleness` field with
|
||||
`commitsBehind` when the index is behind HEAD — and refresh with
|
||||
`node .gitnexus/run.cjs analyze --index-only` in the target checkout before
|
||||
trusting results. If `.gitnexus/run.cjs` is missing, fall back to the installed
|
||||
`gitnexus` CLI, then `npx gitnexus`.
|
||||
|
||||
## Echo before claiming
|
||||
|
||||
State the bound identity before reporting conclusions:
|
||||
|
||||
```
|
||||
Repository: <name> (<path>) Worktree: <path> Index: <commit>, <n> behind HEAD
|
||||
```
|
||||
|
||||
Where the identity is partly unresolved, say which part and do not describe the
|
||||
result as a complete graph-backed answer. This mirrors the provenance rule in
|
||||
`gitnexus-review`: the graph and the diff must describe the same code, and a
|
||||
reader must be able to tell from the output whether they did.
|
||||
|
||||
## Scope
|
||||
|
||||
Bind identity for any task that reads or writes a specific repository. Skip it
|
||||
only for questions about GitNexus itself that touch no repository data. When
|
||||
one task legitimately spans two repositories, bind each explicitly and label
|
||||
which repository each result came from; never blend results from different
|
||||
repositories into a single undifferentiated list.
|
||||
|
|
@ -13,9 +13,25 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|||
- "This endpoint returns 500"
|
||||
- Investigating bugs, errors, or unexpected behavior
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
A root cause traced in the wrong repository is a wrong root cause.
|
||||
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask. This matters most for `cypher`, whose
|
||||
statement carries no in-band hint of which database it ran against.
|
||||
|
||||
A stale index describes the code from before your bug, so refresh before
|
||||
trusting a trace, and state the repository and index freshness with the
|
||||
diagnosis.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo
|
||||
1. query({search_query: "<error or symptom>"}) → Find related execution flows
|
||||
2. context({name: "<suspect>"}) → See callers/callees/processes
|
||||
3. READ gitnexus://repo/{name}/process/{name} → Trace execution flow
|
||||
|
|
@ -27,6 +43,7 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] Understand the symptom (error message, unexpected behavior)
|
||||
- [ ] query for error text or related code
|
||||
- [ ] Identify the suspect function from returned processes
|
||||
|
|
@ -34,6 +51,7 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|||
- [ ] Trace execution flow via process resource if applicable
|
||||
- [ ] cypher for custom call chain traces if needed
|
||||
- [ ] Read source files to confirm root cause
|
||||
- [ ] State the repository and index freshness with the diagnosis
|
||||
```
|
||||
|
||||
## Debugging Patterns
|
||||
|
|
@ -44,7 +62,7 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|||
| Wrong return value | `context` on the function → trace callees for data flow |
|
||||
| Intermittent failure | `context` → look for external calls, async deps |
|
||||
| Performance issue | `context` → find symbols with many callers (hot paths) |
|
||||
| Recent regression | `detect_changes` to see what your changes affect |
|
||||
| Recent regression | `detect_changes` to see what your changes affect — pass `worktree` for a linked worktree |
|
||||
| "How does A reach B?" | `trace` between the two symbols — shortest call chain in one call |
|
||||
|
||||
## Tools
|
||||
|
|
@ -52,7 +70,7 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|||
**query** — find code related to error:
|
||||
|
||||
```
|
||||
query({search_query: "payment validation error"})
|
||||
query({search_query: "payment validation error", repo: "my-app"})
|
||||
→ Processes: CheckoutFlow, ErrorHandling
|
||||
→ Symbols: validatePayment, handlePaymentError, PaymentException
|
||||
```
|
||||
|
|
@ -60,13 +78,15 @@ query({search_query: "payment validation error"})
|
|||
**context** — full context for a suspect:
|
||||
|
||||
```
|
||||
context({name: "validatePayment"})
|
||||
context({name: "validatePayment", repo: "my-app"})
|
||||
→ Incoming calls: processCheckout, webhookHandler
|
||||
→ Outgoing calls: verifyCard, fetchRates (external API!)
|
||||
→ Processes: CheckoutFlow (step 3/7)
|
||||
```
|
||||
|
||||
**cypher** — custom call chain traces:
|
||||
**cypher** — custom call chain traces. Pass `repo` alongside the statement; the
|
||||
Cypher text itself names no repository, so the result is unattributable without
|
||||
it:
|
||||
|
||||
```cypher
|
||||
MATCH path = (a)-[:CodeRelation {type: 'CALLS'}*1..2]->(b:Function {name: "validatePayment"})
|
||||
|
|
@ -76,7 +96,7 @@ RETURN [n IN nodes(path) | n.name] AS chain
|
|||
**trace** — shortest call chain between two symbols ("how does A reach B?"), one call instead of chaining `context` hops:
|
||||
|
||||
```
|
||||
trace({ from: "processCheckout", to: "fetchRates" })
|
||||
trace({ from: "processCheckout", to: "fetchRates", repo: "my-app" })
|
||||
→ status: ok, hopCount: 3
|
||||
→ hops: processCheckout → validatePayment → verifyCard → fetchRates
|
||||
→ edges: CALLS (1.0), CALLS (0.95), CALLS (1.0)
|
||||
|
|
@ -87,15 +107,22 @@ When no path exists, `trace` reports the furthest reachable node — exactly whe
|
|||
## Example: "Payment endpoint returns 500 intermittently"
|
||||
|
||||
```
|
||||
1. query({search_query: "payment error handling"})
|
||||
0. list_repos {}
|
||||
→ total: 2 (my-app, billing-api) — bind my-app explicitly on every call
|
||||
|
||||
1. query({search_query: "payment error handling", repo: "my-app"})
|
||||
→ Processes: CheckoutFlow, ErrorHandling
|
||||
→ Symbols: validatePayment, handlePaymentError
|
||||
|
||||
2. context({name: "validatePayment"})
|
||||
2. context({name: "validatePayment", repo: "my-app"})
|
||||
→ Outgoing calls: verifyCard, fetchRates (external API!)
|
||||
|
||||
3. READ gitnexus://repo/my-app/process/CheckoutFlow
|
||||
→ Step 3: validatePayment → calls fetchRates (external)
|
||||
|
||||
4. Root cause: fetchRates calls external API without proper timeout
|
||||
Repository: my-app Index: current
|
||||
```
|
||||
|
||||
With a single indexed repository, step 0 returns `total: 1` and the `repo`
|
||||
argument drops out of every call above.
|
||||
|
|
|
|||
|
|
@ -13,10 +13,19 @@ description: "Use when the user asks how code works, wants to understand archite
|
|||
- "Where is the database logic?"
|
||||
- Understanding code you haven't seen before
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
Step 1 discovers what is indexed; every call after it must say which of those
|
||||
it means. With one indexed repository, use the examples below as written. With
|
||||
more than one, pass `repo` on every call: an omitted `repo` normally errors,
|
||||
but under an MCP policy with a configured default it resolves to that default
|
||||
silently. If you cannot tell which repository is meant, stop and ask. Report
|
||||
the bound repository and index freshness alongside your explanation.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
1. READ gitnexus://repos → Discover indexed repos
|
||||
1. list_repos {} or READ gitnexus://repos → Discover indexed repos
|
||||
2. READ gitnexus://repo/{name}/context → Codebase overview, check staleness
|
||||
3. query({search_query: "<what you want to understand>"}) → Find related execution flows
|
||||
4. context({name: "<symbol>"}) → Deep dive on specific symbol
|
||||
|
|
@ -28,12 +37,14 @@ description: "Use when the user asks how code works, wants to understand archite
|
|||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] READ gitnexus://repo/{name}/context
|
||||
- [ ] query for the concept you want to understand
|
||||
- [ ] Review returned processes (execution flows)
|
||||
- [ ] context on key symbols for callers/callees
|
||||
- [ ] READ process resource for full execution traces
|
||||
- [ ] Read source files for implementation details
|
||||
- [ ] State the repository and index freshness with the explanation
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
|
@ -50,7 +61,7 @@ description: "Use when the user asks how code works, wants to understand archite
|
|||
**query** — find execution flows related to a concept:
|
||||
|
||||
```
|
||||
query({search_query: "payment processing"})
|
||||
query({search_query: "payment processing", repo: "my-app"})
|
||||
→ Processes: CheckoutFlow, RefundFlow, WebhookHandler
|
||||
→ Symbols grouped by flow with file locations
|
||||
```
|
||||
|
|
@ -58,16 +69,20 @@ query({search_query: "payment processing"})
|
|||
**context** — 360-degree view of a symbol:
|
||||
|
||||
```
|
||||
context({name: "validateUser"})
|
||||
context({name: "validateUser", repo: "my-app"})
|
||||
→ Incoming calls: loginHandler, apiMiddleware
|
||||
→ Outgoing calls: checkToken, getUserById
|
||||
→ Processes: LoginFlow (step 2/5), TokenRefresh (step 1/3)
|
||||
```
|
||||
|
||||
`repo` is required once more than one repository is indexed, and may be omitted
|
||||
with a single one.
|
||||
|
||||
## Example: "How does payment processing work?"
|
||||
|
||||
```
|
||||
1. READ gitnexus://repo/my-app/context → 918 symbols, 45 processes
|
||||
1. list_repos {} → total: 1 (my-app) — bind it
|
||||
READ gitnexus://repo/my-app/context → 918 symbols, 45 processes
|
||||
2. query({search_query: "payment processing"})
|
||||
→ CheckoutFlow: processPayment → validateCard → chargeStripe
|
||||
→ RefundFlow: initiateRefund → calculateRefund → processRefund
|
||||
|
|
@ -75,4 +90,8 @@ context({name: "validateUser"})
|
|||
→ Incoming: checkoutHandler, webhookHandler
|
||||
→ Outgoing: validateCard, chargeStripe, saveTransaction
|
||||
4. Read src/payments/processor.ts for implementation details
|
||||
5. Answer, noting: Repository my-app, index current
|
||||
```
|
||||
|
||||
Had step 1 returned two repositories, every call above would carry
|
||||
`repo: "my-app"`.
|
||||
|
|
|
|||
|
|
@ -14,13 +14,42 @@ description: "Use when the user wants to know what will break if they change som
|
|||
- Before making non-trivial code changes
|
||||
- Before committing — to understand what your changes affect
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
Impact analysis is the gate that authorizes an edit, so it must answer for the
|
||||
repository you are about to edit.
|
||||
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask — every result below an ambiguous
|
||||
identity inherits the ambiguity. `list_repos` is paginated, so page with
|
||||
`offset: pagination.nextOffset` until `hasMore` is false before concluding a
|
||||
repository is absent.
|
||||
|
||||
`detect_changes` takes `worktree` when your changes are in a linked worktree
|
||||
the MCP server was not launched from. The server auto-detects a worktree only
|
||||
when it was launched from inside one; otherwise `git diff` runs in the wrong
|
||||
checkout and reports zero changed symbols — a false clean check that carries
|
||||
none of the degradation flags described below. In the CLI fallbacks, `--repo .`
|
||||
means the current checkout; pass the intended repository path instead when you
|
||||
are not standing in it.
|
||||
|
||||
State the bound identity with your risk report:
|
||||
|
||||
```
|
||||
Repository: <name> (<path>) Worktree: <path> Index: <commit>, <n> behind HEAD
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo (and worktree)
|
||||
1. impact({target: "X", direction: "upstream"}) or `node .gitnexus/run.cjs impact "X" --direction upstream --repo .`
|
||||
2. READ gitnexus://repo/{name}/processes → Check affected execution flows
|
||||
3. detect_changes({scope: "all"}) or `node .gitnexus/run.cjs detect-changes --scope all --repo .`
|
||||
4. Assess risk and report to user
|
||||
4. Assess risk and report to user, echoing repo/worktree/index identity
|
||||
```
|
||||
|
||||
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||
|
|
@ -29,12 +58,14 @@ description: "Use when the user wants to know what will break if they change som
|
|||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] impact({target, direction: "upstream"}) or CLI fallback to find dependents
|
||||
- [ ] Review d=1 items first (these WILL BREAK)
|
||||
- [ ] Check high-confidence (>0.8) dependencies
|
||||
- [ ] READ processes to check affected execution flows
|
||||
- [ ] detect_changes({scope: "all"}) or CLI fallback for pre-commit check
|
||||
- [ ] Assess risk level and report to user
|
||||
- [ ] Confirm the checkout you edited is the checkout that was diffed
|
||||
- [ ] Assess risk level and report, stating repo/worktree/index identity
|
||||
```
|
||||
|
||||
## Understanding Output
|
||||
|
|
@ -69,6 +100,7 @@ treating the symbol as safe to change or delete.
|
|||
```
|
||||
impact({
|
||||
target: "validateUser",
|
||||
repo: "my-app", // required once >1 repository is indexed
|
||||
direction: "upstream",
|
||||
minConfidence: 0.8,
|
||||
maxDepth: 3
|
||||
|
|
@ -92,15 +124,26 @@ detect_changes({scope: "all"})
|
|||
→ Risk: MEDIUM
|
||||
```
|
||||
|
||||
Add `repo` once more than one repository is indexed, and `worktree: "<abs
|
||||
path>"` when your changes are in a linked worktree the server was not launched
|
||||
from.
|
||||
|
||||
`partial: true` (a graph query failed) or `truncated: true` (the changed-symbol
|
||||
listing was capped) means the result is short of the truth, and reads like
|
||||
`UNKNOWN` above: a zero there means unseen, not unaffected. Re-run it rather
|
||||
than tick the pre-commit check.
|
||||
|
||||
A wrong-worktree zero carries neither flag and is shape-identical to a genuine
|
||||
clean result, so confirm the checkout you edited is the one that was diffed
|
||||
before treating an empty change set as a passed check.
|
||||
|
||||
## Example: "What breaks if I change validateUser?"
|
||||
|
||||
```
|
||||
1. impact({target: "validateUser", direction: "upstream"}) or `node .gitnexus/run.cjs impact "validateUser" --direction upstream --repo .`
|
||||
0. list_repos {}
|
||||
→ total: 2 (my-app, billing-api) — both define validateUser, so bind explicitly
|
||||
|
||||
1. impact({target: "validateUser", repo: "my-app", direction: "upstream"}) or `node .gitnexus/run.cjs impact "validateUser" --direction upstream --repo .`
|
||||
→ d=1: loginHandler, apiMiddleware (WILL BREAK)
|
||||
→ d=2: authRouter, sessionManager (LIKELY AFFECTED)
|
||||
|
||||
|
|
@ -108,4 +151,8 @@ than tick the pre-commit check.
|
|||
→ LoginFlow and TokenRefresh touch validateUser
|
||||
|
||||
3. Risk: 2 direct callers, 2 processes = MEDIUM
|
||||
Repository: my-app (/abs/path/my-app) Worktree: same Index: current
|
||||
```
|
||||
|
||||
With a single indexed repository, step 0 returns `total: 1` and the `repo`
|
||||
argument drops out of every call above.
|
||||
|
|
|
|||
|
|
@ -13,9 +13,29 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|||
- "Move this to a new file"
|
||||
- Any task involving renaming, extracting, splitting, or restructuring code
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
Refactoring writes to disk. `rename` with `dry_run: false` edits files in
|
||||
whichever repository was resolved, so binding identity here is a safety gate,
|
||||
not bookkeeping.
|
||||
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask. Never run `rename` with
|
||||
`dry_run: false` until the preview in the same bound repository has been
|
||||
reviewed — its returned `file_path` values show which checkout is about to be
|
||||
written, so read them as a confirmation of identity.
|
||||
|
||||
`detect_changes` takes `worktree` when you are editing a linked worktree the
|
||||
MCP server was not launched from; otherwise `git diff` runs in the wrong
|
||||
checkout and reports nothing changed, which reads as a verified refactor.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo (and worktree)
|
||||
1. impact({target: "X", direction: "upstream"}) → Map all dependents
|
||||
2. query({search_query: "X"}) → Find execution flows involving X
|
||||
3. context({name: "X"}) → See all incoming/outgoing refs
|
||||
|
|
@ -29,7 +49,9 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|||
### Rename Symbol
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] rename({symbol_name: "oldName", new_name: "newName", dry_run: true}) — preview all edits
|
||||
- [ ] Confirm the previewed file paths are in the bound repository/worktree
|
||||
- [ ] Review graph edits (high confidence) and text_search edits (review carefully)
|
||||
- [ ] If satisfied: rename({..., dry_run: false}) — apply edits
|
||||
- [ ] detect_changes() — verify only expected files changed
|
||||
|
|
@ -39,6 +61,7 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|||
### Extract Module
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] context({name: target}) — see all incoming/outgoing refs
|
||||
- [ ] impact({target, direction: "upstream"}) — find all external callers
|
||||
- [ ] Define new module interface
|
||||
|
|
@ -50,6 +73,7 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|||
### Split Function/Service
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] context({name: target}) — understand all callees
|
||||
- [ ] Group callees by responsibility
|
||||
- [ ] impact({target, direction: "upstream"}) — map callers to update
|
||||
|
|
@ -64,7 +88,7 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|||
**rename** — automated multi-file rename:
|
||||
|
||||
```
|
||||
rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true})
|
||||
rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: true})
|
||||
→ 12 edits across 8 files
|
||||
→ 10 graph edits (high confidence), 2 text_search edits (review)
|
||||
→ Changes: [{file_path, edits: [{line, old_text, new_text, confidence}]}]
|
||||
|
|
@ -73,7 +97,7 @@ rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true
|
|||
**impact** — map all dependents first:
|
||||
|
||||
```
|
||||
impact({target: "validateUser", direction: "upstream"})
|
||||
impact({target: "validateUser", repo: "my-app", direction: "upstream"})
|
||||
→ d=1: loginHandler, apiMiddleware, testUtils
|
||||
→ Affected Processes: LoginFlow, TokenRefresh
|
||||
```
|
||||
|
|
@ -92,6 +116,9 @@ listing was capped) means the result is short of the truth: a short or empty
|
|||
list is not proof that only the expected files changed. Re-run it rather than
|
||||
treat the refactor as verified.
|
||||
|
||||
A wrong-worktree zero carries neither flag and is indistinguishable from a
|
||||
clean verification, so confirm the diffed checkout is the one you edited.
|
||||
|
||||
**cypher** — custom reference queries:
|
||||
|
||||
```cypher
|
||||
|
|
@ -107,20 +134,28 @@ RETURN caller.name, caller.filePath ORDER BY caller.filePath
|
|||
| Cross-area refs | Use detect_changes after to verify scope |
|
||||
| String/dynamic refs | query to find them |
|
||||
| External/public API | Version and deprecate properly |
|
||||
| Same name in another indexed repo | Bind `repo`; verify previewed paths before applying |
|
||||
|
||||
## Example: Rename `validateUser` to `authenticateUser`
|
||||
|
||||
```
|
||||
1. rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true})
|
||||
0. list_repos {}
|
||||
→ total: 2 (my-app, billing-api) — both define validateUser, so bind explicitly
|
||||
|
||||
1. rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: true})
|
||||
→ 12 edits: 10 graph (safe), 2 text_search (review)
|
||||
→ Files: validator.ts, login.ts, middleware.ts, config.json...
|
||||
|
||||
2. Review text_search edits (config.json: dynamic reference!)
|
||||
|
||||
3. rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: false})
|
||||
3. rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: false})
|
||||
→ Applied 12 edits across 8 files
|
||||
|
||||
4. detect_changes({scope: "all"})
|
||||
4. detect_changes({scope: "all", repo: "my-app"})
|
||||
→ Affected: LoginFlow, TokenRefresh
|
||||
→ Risk: MEDIUM — run tests for these flows
|
||||
Repository: my-app (/abs/path/my-app) Worktree: same Index: current
|
||||
```
|
||||
|
||||
With a single indexed repository, step 0 returns `total: 1` and the `repo`
|
||||
argument drops out of every call above.
|
||||
|
|
|
|||
|
|
@ -1,20 +1,37 @@
|
|||
---
|
||||
name: gitnexus-debugging
|
||||
description: Trace bugs through call chains using knowledge graph
|
||||
description: "Use when the user is debugging a bug, tracing an error, or asking why something fails. Examples: \"Why is X failing?\", \"Where does this error come from?\", \"Trace this bug\""
|
||||
---
|
||||
|
||||
# Debugging with GitNexus
|
||||
|
||||
## When to Use
|
||||
|
||||
- "Why is this function failing?"
|
||||
- "Trace where this error comes from"
|
||||
- "Who calls this method?"
|
||||
- "This endpoint returns 500"
|
||||
- Investigating bugs, errors, or unexpected behavior
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
A root cause traced in the wrong repository is a wrong root cause.
|
||||
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask. This matters most for `cypher`, whose
|
||||
statement carries no in-band hint of which database it ran against.
|
||||
|
||||
A stale index describes the code from before your bug, so refresh before
|
||||
trusting a trace, and state the repository and index freshness with the
|
||||
diagnosis.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo
|
||||
1. query({search_query: "<error or symptom>"}) → Find related execution flows
|
||||
2. context({name: "<suspect>"}) → See callers/callees/processes
|
||||
3. READ gitnexus://repo/{name}/process/{name} → Trace execution flow
|
||||
|
|
@ -26,6 +43,7 @@ description: Trace bugs through call chains using knowledge graph
|
|||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] Understand the symptom (error message, unexpected behavior)
|
||||
- [ ] query for error text or related code
|
||||
- [ ] Identify the suspect function from returned processes
|
||||
|
|
@ -33,45 +51,52 @@ description: Trace bugs through call chains using knowledge graph
|
|||
- [ ] Trace execution flow via process resource if applicable
|
||||
- [ ] cypher for custom call chain traces if needed
|
||||
- [ ] Read source files to confirm root cause
|
||||
- [ ] State the repository and index freshness with the diagnosis
|
||||
```
|
||||
|
||||
## Debugging Patterns
|
||||
|
||||
| Symptom | GitNexus Approach |
|
||||
|---------|-------------------|
|
||||
| Error message | `query` for error text → `context` on throw sites |
|
||||
| Wrong return value | `context` on the function → trace callees for data flow |
|
||||
| Intermittent failure | `context` → look for external calls, async deps |
|
||||
| Performance issue | `context` → find symbols with many callers (hot paths) |
|
||||
| Recent regression | `detect_changes` to see what your changes affect |
|
||||
| Symptom | GitNexus Approach |
|
||||
| -------------------- | ---------------------------------------------------------- |
|
||||
| Error message | `query` for error text → `context` on throw sites |
|
||||
| Wrong return value | `context` on the function → trace callees for data flow |
|
||||
| Intermittent failure | `context` → look for external calls, async deps |
|
||||
| Performance issue | `context` → find symbols with many callers (hot paths) |
|
||||
| Recent regression | `detect_changes` to see what your changes affect — pass `worktree` for a linked worktree |
|
||||
| "How does A reach B?" | `trace` between the two symbols — shortest call chain in one call |
|
||||
|
||||
## Tools
|
||||
|
||||
**query** — find code related to error:
|
||||
|
||||
```
|
||||
query({search_query: "payment validation error"})
|
||||
query({search_query: "payment validation error", repo: "my-app"})
|
||||
→ Processes: CheckoutFlow, ErrorHandling
|
||||
→ Symbols: validatePayment, handlePaymentError, PaymentException
|
||||
```
|
||||
|
||||
**context** — full context for a suspect:
|
||||
|
||||
```
|
||||
context({name: "validatePayment"})
|
||||
context({name: "validatePayment", repo: "my-app"})
|
||||
→ Incoming calls: processCheckout, webhookHandler
|
||||
→ Outgoing calls: verifyCard, fetchRates (external API!)
|
||||
→ Processes: CheckoutFlow (step 3/7)
|
||||
```
|
||||
|
||||
**cypher** — custom call chain traces:
|
||||
**cypher** — custom call chain traces. Pass `repo` alongside the statement; the
|
||||
Cypher text itself names no repository, so the result is unattributable without
|
||||
it:
|
||||
|
||||
```cypher
|
||||
MATCH path = (a)-[:CodeRelation {type: 'CALLS'}*1..2]->(b:Function {name: "validatePayment"})
|
||||
RETURN [n IN nodes(path) | n.name] AS chain
|
||||
```
|
||||
|
||||
**trace** — shortest call chain between two symbols ("how does A reach B?"), one call instead of chaining `context` hops:
|
||||
|
||||
```
|
||||
trace({ from: "processCheckout", to: "fetchRates" })
|
||||
trace({ from: "processCheckout", to: "fetchRates", repo: "my-app" })
|
||||
→ status: ok, hopCount: 3
|
||||
→ hops: processCheckout → validatePayment → verifyCard → fetchRates
|
||||
→ edges: CALLS (1.0), CALLS (0.95), CALLS (1.0)
|
||||
|
|
@ -82,15 +107,22 @@ When no path exists, `trace` reports the furthest reachable node — exactly whe
|
|||
## Example: "Payment endpoint returns 500 intermittently"
|
||||
|
||||
```
|
||||
1. query({search_query: "payment error handling"})
|
||||
0. list_repos {}
|
||||
→ total: 2 (my-app, billing-api) — bind my-app explicitly on every call
|
||||
|
||||
1. query({search_query: "payment error handling", repo: "my-app"})
|
||||
→ Processes: CheckoutFlow, ErrorHandling
|
||||
→ Symbols: validatePayment, handlePaymentError
|
||||
|
||||
2. context({name: "validatePayment"})
|
||||
2. context({name: "validatePayment", repo: "my-app"})
|
||||
→ Outgoing calls: verifyCard, fetchRates (external API!)
|
||||
|
||||
3. READ gitnexus://repo/my-app/process/CheckoutFlow
|
||||
→ Step 3: validatePayment → calls fetchRates (external)
|
||||
|
||||
4. Root cause: fetchRates calls external API without proper timeout
|
||||
Repository: my-app Index: current
|
||||
```
|
||||
|
||||
With a single indexed repository, step 0 returns `total: 1` and the `repo`
|
||||
argument drops out of every call above.
|
||||
|
|
|
|||
|
|
@ -1,21 +1,31 @@
|
|||
---
|
||||
name: gitnexus-exploring
|
||||
description: Navigate unfamiliar code using GitNexus knowledge graph
|
||||
description: "Use when the user asks how code works, wants to understand architecture, trace execution flows, or explore unfamiliar parts of the codebase. Examples: \"How does X work?\", \"What calls this function?\", \"Show me the auth flow\""
|
||||
---
|
||||
|
||||
# Exploring Codebases with GitNexus
|
||||
|
||||
## When to Use
|
||||
|
||||
- "How does authentication work?"
|
||||
- "What's the project structure?"
|
||||
- "Show me the main components"
|
||||
- "Where is the database logic?"
|
||||
- Understanding code you haven't seen before
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
Step 1 discovers what is indexed; every call after it must say which of those
|
||||
it means. With one indexed repository, use the examples below as written. With
|
||||
more than one, pass `repo` on every call: an omitted `repo` normally errors,
|
||||
but under an MCP policy with a configured default it resolves to that default
|
||||
silently. If you cannot tell which repository is meant, stop and ask. Report
|
||||
the bound repository and index freshness alongside your explanation.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
1. READ gitnexus://repos → Discover indexed repos
|
||||
1. list_repos {} or READ gitnexus://repos → Discover indexed repos
|
||||
2. READ gitnexus://repo/{name}/context → Codebase overview, check staleness
|
||||
3. query({search_query: "<what you want to understand>"}) → Find related execution flows
|
||||
4. context({name: "<symbol>"}) → Deep dive on specific symbol
|
||||
|
|
@ -27,44 +37,52 @@ description: Navigate unfamiliar code using GitNexus knowledge graph
|
|||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] READ gitnexus://repo/{name}/context
|
||||
- [ ] query for the concept you want to understand
|
||||
- [ ] Review returned processes (execution flows)
|
||||
- [ ] context on key symbols for callers/callees
|
||||
- [ ] READ process resource for full execution traces
|
||||
- [ ] Read source files for implementation details
|
||||
- [ ] State the repository and index freshness with the explanation
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
| Resource | What you get |
|
||||
|----------|-------------|
|
||||
| `gitnexus://repo/{name}/context` | Stats, staleness warning (~150 tokens) |
|
||||
| `gitnexus://repo/{name}/clusters` | All functional areas with cohesion scores (~300 tokens) |
|
||||
| `gitnexus://repo/{name}/cluster/{name}` | Area members with file paths (~500 tokens) |
|
||||
| `gitnexus://repo/{name}/process/{name}` | Step-by-step execution trace (~200 tokens) |
|
||||
| Resource | What you get |
|
||||
| --------------------------------------- | ------------------------------------------------------- |
|
||||
| `gitnexus://repo/{name}/context` | Stats, staleness warning (~150 tokens) |
|
||||
| `gitnexus://repo/{name}/clusters` | All functional areas with cohesion scores (~300 tokens) |
|
||||
| `gitnexus://repo/{name}/cluster/{name}` | Area members with file paths (~500 tokens) |
|
||||
| `gitnexus://repo/{name}/process/{name}` | Step-by-step execution trace (~200 tokens) |
|
||||
|
||||
## Tools
|
||||
|
||||
**query** — find execution flows related to a concept:
|
||||
|
||||
```
|
||||
query({search_query: "payment processing"})
|
||||
query({search_query: "payment processing", repo: "my-app"})
|
||||
→ Processes: CheckoutFlow, RefundFlow, WebhookHandler
|
||||
→ Symbols grouped by flow with file locations
|
||||
```
|
||||
|
||||
**context** — 360-degree view of a symbol:
|
||||
|
||||
```
|
||||
context({name: "validateUser"})
|
||||
context({name: "validateUser", repo: "my-app"})
|
||||
→ Incoming calls: loginHandler, apiMiddleware
|
||||
→ Outgoing calls: checkToken, getUserById
|
||||
→ Processes: LoginFlow (step 2/5), TokenRefresh (step 1/3)
|
||||
```
|
||||
|
||||
`repo` is required once more than one repository is indexed, and may be omitted
|
||||
with a single one.
|
||||
|
||||
## Example: "How does payment processing work?"
|
||||
|
||||
```
|
||||
1. READ gitnexus://repo/my-app/context → 918 symbols, 45 processes
|
||||
1. list_repos {} → total: 1 (my-app) — bind it
|
||||
READ gitnexus://repo/my-app/context → 918 symbols, 45 processes
|
||||
2. query({search_query: "payment processing"})
|
||||
→ CheckoutFlow: processPayment → validateCard → chargeStripe
|
||||
→ RefundFlow: initiateRefund → calculateRefund → processRefund
|
||||
|
|
@ -72,4 +90,8 @@ context({name: "validateUser"})
|
|||
→ Incoming: checkoutHandler, webhookHandler
|
||||
→ Outgoing: validateCard, chargeStripe, saveTransaction
|
||||
4. Read src/payments/processor.ts for implementation details
|
||||
5. Answer, noting: Repository my-app, index current
|
||||
```
|
||||
|
||||
Had step 1 returned two repositories, every call above would carry
|
||||
`repo: "my-app"`.
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
---
|
||||
name: gitnexus-impact-analysis
|
||||
description: Analyze blast radius before making code changes
|
||||
description: "Use when the user wants to know what will break if they change something, or needs safety analysis before editing code. Examples: \"Is it safe to change X?\", \"What depends on this?\", \"What will break?\""
|
||||
---
|
||||
|
||||
# Impact Analysis with GitNexus
|
||||
|
||||
## When to Use
|
||||
|
||||
- "Is it safe to change this function?"
|
||||
- "What will break if I modify X?"
|
||||
- "Show me the blast radius"
|
||||
|
|
@ -13,13 +14,42 @@ description: Analyze blast radius before making code changes
|
|||
- Before making non-trivial code changes
|
||||
- Before committing — to understand what your changes affect
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
Impact analysis is the gate that authorizes an edit, so it must answer for the
|
||||
repository you are about to edit.
|
||||
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask — every result below an ambiguous
|
||||
identity inherits the ambiguity. `list_repos` is paginated, so page with
|
||||
`offset: pagination.nextOffset` until `hasMore` is false before concluding a
|
||||
repository is absent.
|
||||
|
||||
`detect_changes` takes `worktree` when your changes are in a linked worktree
|
||||
the MCP server was not launched from. The server auto-detects a worktree only
|
||||
when it was launched from inside one; otherwise `git diff` runs in the wrong
|
||||
checkout and reports zero changed symbols — a false clean check that carries
|
||||
none of the degradation flags described below. In the CLI fallbacks, `--repo .`
|
||||
means the current checkout; pass the intended repository path instead when you
|
||||
are not standing in it.
|
||||
|
||||
State the bound identity with your risk report:
|
||||
|
||||
```
|
||||
Repository: <name> (<path>) Worktree: <path> Index: <commit>, <n> behind HEAD
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo (and worktree)
|
||||
1. impact({target: "X", direction: "upstream"}) or `node .gitnexus/run.cjs impact "X" --direction upstream --repo .`
|
||||
2. READ gitnexus://repo/{name}/processes → Check affected execution flows
|
||||
3. detect_changes({scope: "all"}) or `node .gitnexus/run.cjs detect-changes --scope all --repo .`
|
||||
4. Assess risk and report to user
|
||||
4. Assess risk and report to user, echoing repo/worktree/index identity
|
||||
```
|
||||
|
||||
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||
|
|
@ -28,31 +58,31 @@ description: Analyze blast radius before making code changes
|
|||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] impact({target, direction: "upstream"}) or CLI fallback to find dependents
|
||||
- [ ] Review d=1 items first (these WILL BREAK)
|
||||
- [ ] Check high-confidence (>0.8) dependencies
|
||||
- [ ] READ processes to check affected execution flows
|
||||
- [ ] detect_changes({scope: "all"}) or CLI fallback for pre-commit check
|
||||
- [ ] Assess risk level and report to user
|
||||
- [ ] Confirm the checkout you edited is the checkout that was diffed
|
||||
- [ ] Assess risk level and report, stating repo/worktree/index identity
|
||||
```
|
||||
|
||||
> `partial: true` (a graph query failed) or `truncated: true` (the changed-symbol listing was capped) means the result is short of the truth: a zero there means unseen, not unaffected. Re-run it rather than tick the pre-commit check.
|
||||
|
||||
## Understanding Output
|
||||
|
||||
| Depth | Risk Level | Meaning |
|
||||
|-------|-----------|---------|
|
||||
| d=1 | **WILL BREAK** | Direct callers/importers |
|
||||
| d=2 | LIKELY AFFECTED | Indirect dependencies |
|
||||
| d=3 | MAY NEED TESTING | Transitive effects |
|
||||
| Depth | Risk Level | Meaning |
|
||||
| ----- | ---------------- | ------------------------ |
|
||||
| d=1 | **WILL BREAK** | Direct callers/importers |
|
||||
| d=2 | LIKELY AFFECTED | Indirect dependencies |
|
||||
| d=3 | MAY NEED TESTING | Transitive effects |
|
||||
|
||||
## Risk Assessment
|
||||
|
||||
| Affected | Risk |
|
||||
|----------|------|
|
||||
| <5 symbols, few processes | LOW |
|
||||
| 5-15 symbols, 2-5 processes | MEDIUM |
|
||||
| >15 symbols or many processes | HIGH |
|
||||
| Affected | Risk |
|
||||
| ------------------------------ | -------- |
|
||||
| <5 symbols, few processes | LOW |
|
||||
| 5-15 symbols, 2-5 processes | MEDIUM |
|
||||
| >15 symbols or many processes | HIGH |
|
||||
| Critical path (auth, payments) | CRITICAL |
|
||||
| **Zero callers found** | **UNKNOWN** |
|
||||
|
||||
|
|
@ -66,9 +96,11 @@ treating the symbol as safe to change or delete.
|
|||
## Tools
|
||||
|
||||
**impact** — the primary tool for symbol blast radius. If MCP is unavailable, use `node .gitnexus/run.cjs impact <symbol> --direction upstream --repo .` instead:
|
||||
|
||||
```
|
||||
impact({
|
||||
target: "validateUser",
|
||||
repo: "my-app", // required once >1 repository is indexed
|
||||
direction: "upstream",
|
||||
minConfidence: 0.8,
|
||||
maxDepth: 3
|
||||
|
|
@ -83,6 +115,7 @@ impact({
|
|||
```
|
||||
|
||||
**detect_changes** — git-diff based impact analysis. If MCP is unavailable, use `node .gitnexus/run.cjs detect-changes --scope all --repo .` instead:
|
||||
|
||||
```
|
||||
detect_changes({scope: "all"})
|
||||
|
||||
|
|
@ -91,10 +124,26 @@ detect_changes({scope: "all"})
|
|||
→ Risk: MEDIUM
|
||||
```
|
||||
|
||||
Add `repo` once more than one repository is indexed, and `worktree: "<abs
|
||||
path>"` when your changes are in a linked worktree the server was not launched
|
||||
from.
|
||||
|
||||
`partial: true` (a graph query failed) or `truncated: true` (the changed-symbol
|
||||
listing was capped) means the result is short of the truth, and reads like
|
||||
`UNKNOWN` above: a zero there means unseen, not unaffected. Re-run it rather
|
||||
than tick the pre-commit check.
|
||||
|
||||
A wrong-worktree zero carries neither flag and is shape-identical to a genuine
|
||||
clean result, so confirm the checkout you edited is the one that was diffed
|
||||
before treating an empty change set as a passed check.
|
||||
|
||||
## Example: "What breaks if I change validateUser?"
|
||||
|
||||
```
|
||||
1. impact({target: "validateUser", direction: "upstream"}) or `node .gitnexus/run.cjs impact "validateUser" --direction upstream --repo .`
|
||||
0. list_repos {}
|
||||
→ total: 2 (my-app, billing-api) — both define validateUser, so bind explicitly
|
||||
|
||||
1. impact({target: "validateUser", repo: "my-app", direction: "upstream"}) or `node .gitnexus/run.cjs impact "validateUser" --direction upstream --repo .`
|
||||
→ d=1: loginHandler, apiMiddleware (WILL BREAK)
|
||||
→ d=2: authRouter, sessionManager (LIKELY AFFECTED)
|
||||
|
||||
|
|
@ -102,4 +151,8 @@ detect_changes({scope: "all"})
|
|||
→ LoginFlow and TokenRefresh touch validateUser
|
||||
|
||||
3. Risk: 2 direct callers, 2 processes = MEDIUM
|
||||
Repository: my-app (/abs/path/my-app) Worktree: same Index: current
|
||||
```
|
||||
|
||||
With a single indexed repository, step 0 returns `total: 1` and the `repo`
|
||||
argument drops out of every call above.
|
||||
|
|
|
|||
|
|
@ -1,20 +1,41 @@
|
|||
---
|
||||
name: gitnexus-refactoring
|
||||
description: Plan safe refactors using blast radius and dependency mapping
|
||||
description: "Use when the user wants to rename, extract, split, move, or restructure code safely. Examples: \"Rename this function\", \"Extract this into a module\", \"Refactor this class\", \"Move this to a separate file\""
|
||||
---
|
||||
|
||||
# Refactoring with GitNexus
|
||||
|
||||
## When to Use
|
||||
|
||||
- "Rename this function safely"
|
||||
- "Extract this into a module"
|
||||
- "Split this service"
|
||||
- "Move this to a new file"
|
||||
- Any task involving renaming, extracting, splitting, or restructuring code
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
Refactoring writes to disk. `rename` with `dry_run: false` edits files in
|
||||
whichever repository was resolved, so binding identity here is a safety gate,
|
||||
not bookkeeping.
|
||||
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask. Never run `rename` with
|
||||
`dry_run: false` until the preview in the same bound repository has been
|
||||
reviewed — its returned `file_path` values show which checkout is about to be
|
||||
written, so read them as a confirmation of identity.
|
||||
|
||||
`detect_changes` takes `worktree` when you are editing a linked worktree the
|
||||
MCP server was not launched from; otherwise `git diff` runs in the wrong
|
||||
checkout and reports nothing changed, which reads as a verified refactor.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo (and worktree)
|
||||
1. impact({target: "X", direction: "upstream"}) → Map all dependents
|
||||
2. query({search_query: "X"}) → Find execution flows involving X
|
||||
3. context({name: "X"}) → See all incoming/outgoing refs
|
||||
|
|
@ -23,13 +44,14 @@ description: Plan safe refactors using blast radius and dependency mapping
|
|||
|
||||
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||
|
||||
> Every `detect_changes()` below: `partial: true` (a graph query failed) or `truncated: true` (the changed-symbol listing was capped) means the result is short of the truth — a short or empty list is not proof that only the expected files changed. Re-run it rather than treat the refactor as verified.
|
||||
|
||||
## Checklists
|
||||
|
||||
### Rename Symbol
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] rename({symbol_name: "oldName", new_name: "newName", dry_run: true}) — preview all edits
|
||||
- [ ] Confirm the previewed file paths are in the bound repository/worktree
|
||||
- [ ] Review graph edits (high confidence) and text_search edits (review carefully)
|
||||
- [ ] If satisfied: rename({..., dry_run: false}) — apply edits
|
||||
- [ ] detect_changes() — verify only expected files changed
|
||||
|
|
@ -37,7 +59,9 @@ description: Plan safe refactors using blast radius and dependency mapping
|
|||
```
|
||||
|
||||
### Extract Module
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] context({name: target}) — see all incoming/outgoing refs
|
||||
- [ ] impact({target, direction: "upstream"}) — find all external callers
|
||||
- [ ] Define new module interface
|
||||
|
|
@ -47,7 +71,9 @@ description: Plan safe refactors using blast radius and dependency mapping
|
|||
```
|
||||
|
||||
### Split Function/Service
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] context({name: target}) — understand all callees
|
||||
- [ ] Group callees by responsibility
|
||||
- [ ] impact({target, direction: "upstream"}) — map callers to update
|
||||
|
|
@ -60,21 +86,24 @@ description: Plan safe refactors using blast radius and dependency mapping
|
|||
## Tools
|
||||
|
||||
**rename** — automated multi-file rename:
|
||||
|
||||
```
|
||||
rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true})
|
||||
rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: true})
|
||||
→ 12 edits across 8 files
|
||||
→ 10 graph edits (high confidence), 2 text_search edits (review)
|
||||
→ Changes: [{file_path, edits: [{line, old_text, new_text, confidence}]}]
|
||||
```
|
||||
|
||||
**impact** — map all dependents first:
|
||||
|
||||
```
|
||||
impact({target: "validateUser", direction: "upstream"})
|
||||
impact({target: "validateUser", repo: "my-app", direction: "upstream"})
|
||||
→ d=1: loginHandler, apiMiddleware, testUtils
|
||||
→ Affected Processes: LoginFlow, TokenRefresh
|
||||
```
|
||||
|
||||
**detect_changes** — verify your changes after refactoring:
|
||||
|
||||
```
|
||||
detect_changes({scope: "all"})
|
||||
→ Changed: 8 files, 12 symbols
|
||||
|
|
@ -82,7 +111,16 @@ detect_changes({scope: "all"})
|
|||
→ Risk: MEDIUM
|
||||
```
|
||||
|
||||
`partial: true` (a graph query failed) or `truncated: true` (the changed-symbol
|
||||
listing was capped) means the result is short of the truth: a short or empty
|
||||
list is not proof that only the expected files changed. Re-run it rather than
|
||||
treat the refactor as verified.
|
||||
|
||||
A wrong-worktree zero carries neither flag and is indistinguishable from a
|
||||
clean verification, so confirm the diffed checkout is the one you edited.
|
||||
|
||||
**cypher** — custom reference queries:
|
||||
|
||||
```cypher
|
||||
MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "validateUser"})
|
||||
RETURN caller.name, caller.filePath ORDER BY caller.filePath
|
||||
|
|
@ -90,26 +128,34 @@ RETURN caller.name, caller.filePath ORDER BY caller.filePath
|
|||
|
||||
## Risk Rules
|
||||
|
||||
| Risk Factor | Mitigation |
|
||||
|-------------|------------|
|
||||
| Many callers (>5) | Use rename for automated updates |
|
||||
| Cross-area refs | Use detect_changes after to verify scope |
|
||||
| String/dynamic refs | query to find them |
|
||||
| External/public API | Version and deprecate properly |
|
||||
| Risk Factor | Mitigation |
|
||||
| ------------------- | ----------------------------------------- |
|
||||
| Many callers (>5) | Use rename for automated updates |
|
||||
| Cross-area refs | Use detect_changes after to verify scope |
|
||||
| String/dynamic refs | query to find them |
|
||||
| External/public API | Version and deprecate properly |
|
||||
| Same name in another indexed repo | Bind `repo`; verify previewed paths before applying |
|
||||
|
||||
## Example: Rename `validateUser` to `authenticateUser`
|
||||
|
||||
```
|
||||
1. rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true})
|
||||
0. list_repos {}
|
||||
→ total: 2 (my-app, billing-api) — both define validateUser, so bind explicitly
|
||||
|
||||
1. rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: true})
|
||||
→ 12 edits: 10 graph (safe), 2 text_search (review)
|
||||
→ Files: validator.ts, login.ts, middleware.ts, config.json...
|
||||
|
||||
2. Review text_search edits (config.json: dynamic reference!)
|
||||
|
||||
3. rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: false})
|
||||
3. rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: false})
|
||||
→ Applied 12 edits across 8 files
|
||||
|
||||
4. detect_changes({scope: "all"})
|
||||
4. detect_changes({scope: "all", repo: "my-app"})
|
||||
→ Affected: LoginFlow, TokenRefresh
|
||||
→ Risk: MEDIUM — run tests for these flows
|
||||
Repository: my-app (/abs/path/my-app) Worktree: same Index: current
|
||||
```
|
||||
|
||||
With a single indexed repository, step 0 returns `total: 1` and the `repo`
|
||||
argument drops out of every call above.
|
||||
|
|
|
|||
|
|
@ -13,9 +13,25 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|||
- "This endpoint returns 500"
|
||||
- Investigating bugs, errors, or unexpected behavior
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
A root cause traced in the wrong repository is a wrong root cause.
|
||||
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask. This matters most for `cypher`, whose
|
||||
statement carries no in-band hint of which database it ran against.
|
||||
|
||||
A stale index describes the code from before your bug, so refresh before
|
||||
trusting a trace, and state the repository and index freshness with the
|
||||
diagnosis.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo
|
||||
1. query({search_query: "<error or symptom>"}) → Find related execution flows
|
||||
2. context({name: "<suspect>"}) → See callers/callees/processes
|
||||
3. READ gitnexus://repo/{name}/process/{name} → Trace execution flow
|
||||
|
|
@ -27,6 +43,7 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] Understand the symptom (error message, unexpected behavior)
|
||||
- [ ] query for error text or related code
|
||||
- [ ] Identify the suspect function from returned processes
|
||||
|
|
@ -34,6 +51,7 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|||
- [ ] Trace execution flow via process resource if applicable
|
||||
- [ ] cypher for custom call chain traces if needed
|
||||
- [ ] Read source files to confirm root cause
|
||||
- [ ] State the repository and index freshness with the diagnosis
|
||||
```
|
||||
|
||||
## Debugging Patterns
|
||||
|
|
@ -44,7 +62,7 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|||
| Wrong return value | `context` on the function → trace callees for data flow |
|
||||
| Intermittent failure | `context` → look for external calls, async deps |
|
||||
| Performance issue | `context` → find symbols with many callers (hot paths) |
|
||||
| Recent regression | `detect_changes` to see what your changes affect |
|
||||
| Recent regression | `detect_changes` to see what your changes affect — pass `worktree` for a linked worktree |
|
||||
| "How does A reach B?" | `trace` between the two symbols — shortest call chain in one call |
|
||||
|
||||
## Tools
|
||||
|
|
@ -52,7 +70,7 @@ description: "Use when the user is debugging a bug, tracing an error, or asking
|
|||
**query** — find code related to error:
|
||||
|
||||
```
|
||||
query({search_query: "payment validation error"})
|
||||
query({search_query: "payment validation error", repo: "my-app"})
|
||||
→ Processes: CheckoutFlow, ErrorHandling
|
||||
→ Symbols: validatePayment, handlePaymentError, PaymentException
|
||||
```
|
||||
|
|
@ -60,13 +78,15 @@ query({search_query: "payment validation error"})
|
|||
**context** — full context for a suspect:
|
||||
|
||||
```
|
||||
context({name: "validatePayment"})
|
||||
context({name: "validatePayment", repo: "my-app"})
|
||||
→ Incoming calls: processCheckout, webhookHandler
|
||||
→ Outgoing calls: verifyCard, fetchRates (external API!)
|
||||
→ Processes: CheckoutFlow (step 3/7)
|
||||
```
|
||||
|
||||
**cypher** — custom call chain traces:
|
||||
**cypher** — custom call chain traces. Pass `repo` alongside the statement; the
|
||||
Cypher text itself names no repository, so the result is unattributable without
|
||||
it:
|
||||
|
||||
```cypher
|
||||
MATCH path = (a)-[:CodeRelation {type: 'CALLS'}*1..2]->(b:Function {name: "validatePayment"})
|
||||
|
|
@ -76,7 +96,7 @@ RETURN [n IN nodes(path) | n.name] AS chain
|
|||
**trace** — shortest call chain between two symbols ("how does A reach B?"), one call instead of chaining `context` hops:
|
||||
|
||||
```
|
||||
trace({ from: "processCheckout", to: "fetchRates" })
|
||||
trace({ from: "processCheckout", to: "fetchRates", repo: "my-app" })
|
||||
→ status: ok, hopCount: 3
|
||||
→ hops: processCheckout → validatePayment → verifyCard → fetchRates
|
||||
→ edges: CALLS (1.0), CALLS (0.95), CALLS (1.0)
|
||||
|
|
@ -87,15 +107,22 @@ When no path exists, `trace` reports the furthest reachable node — exactly whe
|
|||
## Example: "Payment endpoint returns 500 intermittently"
|
||||
|
||||
```
|
||||
1. query({search_query: "payment error handling"})
|
||||
0. list_repos {}
|
||||
→ total: 2 (my-app, billing-api) — bind my-app explicitly on every call
|
||||
|
||||
1. query({search_query: "payment error handling", repo: "my-app"})
|
||||
→ Processes: CheckoutFlow, ErrorHandling
|
||||
→ Symbols: validatePayment, handlePaymentError
|
||||
|
||||
2. context({name: "validatePayment"})
|
||||
2. context({name: "validatePayment", repo: "my-app"})
|
||||
→ Outgoing calls: verifyCard, fetchRates (external API!)
|
||||
|
||||
3. READ gitnexus://repo/my-app/process/CheckoutFlow
|
||||
→ Step 3: validatePayment → calls fetchRates (external)
|
||||
|
||||
4. Root cause: fetchRates calls external API without proper timeout
|
||||
Repository: my-app Index: current
|
||||
```
|
||||
|
||||
With a single indexed repository, step 0 returns `total: 1` and the `repo`
|
||||
argument drops out of every call above.
|
||||
|
|
|
|||
|
|
@ -13,10 +13,19 @@ description: "Use when the user asks how code works, wants to understand archite
|
|||
- "Where is the database logic?"
|
||||
- Understanding code you haven't seen before
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
Step 1 discovers what is indexed; every call after it must say which of those
|
||||
it means. With one indexed repository, use the examples below as written. With
|
||||
more than one, pass `repo` on every call: an omitted `repo` normally errors,
|
||||
but under an MCP policy with a configured default it resolves to that default
|
||||
silently. If you cannot tell which repository is meant, stop and ask. Report
|
||||
the bound repository and index freshness alongside your explanation.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
1. READ gitnexus://repos → Discover indexed repos
|
||||
1. list_repos {} or READ gitnexus://repos → Discover indexed repos
|
||||
2. READ gitnexus://repo/{name}/context → Codebase overview, check staleness
|
||||
3. query({search_query: "<what you want to understand>"}) → Find related execution flows
|
||||
4. context({name: "<symbol>"}) → Deep dive on specific symbol
|
||||
|
|
@ -28,12 +37,14 @@ description: "Use when the user asks how code works, wants to understand archite
|
|||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] READ gitnexus://repo/{name}/context
|
||||
- [ ] query for the concept you want to understand
|
||||
- [ ] Review returned processes (execution flows)
|
||||
- [ ] context on key symbols for callers/callees
|
||||
- [ ] READ process resource for full execution traces
|
||||
- [ ] Read source files for implementation details
|
||||
- [ ] State the repository and index freshness with the explanation
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
|
@ -50,7 +61,7 @@ description: "Use when the user asks how code works, wants to understand archite
|
|||
**query** — find execution flows related to a concept:
|
||||
|
||||
```
|
||||
query({search_query: "payment processing"})
|
||||
query({search_query: "payment processing", repo: "my-app"})
|
||||
→ Processes: CheckoutFlow, RefundFlow, WebhookHandler
|
||||
→ Symbols grouped by flow with file locations
|
||||
```
|
||||
|
|
@ -58,16 +69,20 @@ query({search_query: "payment processing"})
|
|||
**context** — 360-degree view of a symbol:
|
||||
|
||||
```
|
||||
context({name: "validateUser"})
|
||||
context({name: "validateUser", repo: "my-app"})
|
||||
→ Incoming calls: loginHandler, apiMiddleware
|
||||
→ Outgoing calls: checkToken, getUserById
|
||||
→ Processes: LoginFlow (step 2/5), TokenRefresh (step 1/3)
|
||||
```
|
||||
|
||||
`repo` is required once more than one repository is indexed, and may be omitted
|
||||
with a single one.
|
||||
|
||||
## Example: "How does payment processing work?"
|
||||
|
||||
```
|
||||
1. READ gitnexus://repo/my-app/context → 918 symbols, 45 processes
|
||||
1. list_repos {} → total: 1 (my-app) — bind it
|
||||
READ gitnexus://repo/my-app/context → 918 symbols, 45 processes
|
||||
2. query({search_query: "payment processing"})
|
||||
→ CheckoutFlow: processPayment → validateCard → chargeStripe
|
||||
→ RefundFlow: initiateRefund → calculateRefund → processRefund
|
||||
|
|
@ -75,4 +90,8 @@ context({name: "validateUser"})
|
|||
→ Incoming: checkoutHandler, webhookHandler
|
||||
→ Outgoing: validateCard, chargeStripe, saveTransaction
|
||||
4. Read src/payments/processor.ts for implementation details
|
||||
5. Answer, noting: Repository my-app, index current
|
||||
```
|
||||
|
||||
Had step 1 returned two repositories, every call above would carry
|
||||
`repo: "my-app"`.
|
||||
|
|
|
|||
|
|
@ -14,13 +14,42 @@ description: "Use when the user wants to know what will break if they change som
|
|||
- Before making non-trivial code changes
|
||||
- Before committing — to understand what your changes affect
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
Impact analysis is the gate that authorizes an edit, so it must answer for the
|
||||
repository you are about to edit.
|
||||
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask — every result below an ambiguous
|
||||
identity inherits the ambiguity. `list_repos` is paginated, so page with
|
||||
`offset: pagination.nextOffset` until `hasMore` is false before concluding a
|
||||
repository is absent.
|
||||
|
||||
`detect_changes` takes `worktree` when your changes are in a linked worktree
|
||||
the MCP server was not launched from. The server auto-detects a worktree only
|
||||
when it was launched from inside one; otherwise `git diff` runs in the wrong
|
||||
checkout and reports zero changed symbols — a false clean check that carries
|
||||
none of the degradation flags described below. In the CLI fallbacks, `--repo .`
|
||||
means the current checkout; pass the intended repository path instead when you
|
||||
are not standing in it.
|
||||
|
||||
State the bound identity with your risk report:
|
||||
|
||||
```
|
||||
Repository: <name> (<path>) Worktree: <path> Index: <commit>, <n> behind HEAD
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo (and worktree)
|
||||
1. impact({target: "X", direction: "upstream"}) or `node .gitnexus/run.cjs impact "X" --direction upstream --repo .`
|
||||
2. READ gitnexus://repo/{name}/processes → Check affected execution flows
|
||||
3. detect_changes({scope: "all"}) or `node .gitnexus/run.cjs detect-changes --scope all --repo .`
|
||||
4. Assess risk and report to user
|
||||
4. Assess risk and report to user, echoing repo/worktree/index identity
|
||||
```
|
||||
|
||||
> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in terminal.
|
||||
|
|
@ -29,12 +58,14 @@ description: "Use when the user wants to know what will break if they change som
|
|||
## Checklist
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] impact({target, direction: "upstream"}) or CLI fallback to find dependents
|
||||
- [ ] Review d=1 items first (these WILL BREAK)
|
||||
- [ ] Check high-confidence (>0.8) dependencies
|
||||
- [ ] READ processes to check affected execution flows
|
||||
- [ ] detect_changes({scope: "all"}) or CLI fallback for pre-commit check
|
||||
- [ ] Assess risk level and report to user
|
||||
- [ ] Confirm the checkout you edited is the checkout that was diffed
|
||||
- [ ] Assess risk level and report, stating repo/worktree/index identity
|
||||
```
|
||||
|
||||
## Understanding Output
|
||||
|
|
@ -69,6 +100,7 @@ treating the symbol as safe to change or delete.
|
|||
```
|
||||
impact({
|
||||
target: "validateUser",
|
||||
repo: "my-app", // required once >1 repository is indexed
|
||||
direction: "upstream",
|
||||
minConfidence: 0.8,
|
||||
maxDepth: 3
|
||||
|
|
@ -92,15 +124,26 @@ detect_changes({scope: "all"})
|
|||
→ Risk: MEDIUM
|
||||
```
|
||||
|
||||
Add `repo` once more than one repository is indexed, and `worktree: "<abs
|
||||
path>"` when your changes are in a linked worktree the server was not launched
|
||||
from.
|
||||
|
||||
`partial: true` (a graph query failed) or `truncated: true` (the changed-symbol
|
||||
listing was capped) means the result is short of the truth, and reads like
|
||||
`UNKNOWN` above: a zero there means unseen, not unaffected. Re-run it rather
|
||||
than tick the pre-commit check.
|
||||
|
||||
A wrong-worktree zero carries neither flag and is shape-identical to a genuine
|
||||
clean result, so confirm the checkout you edited is the one that was diffed
|
||||
before treating an empty change set as a passed check.
|
||||
|
||||
## Example: "What breaks if I change validateUser?"
|
||||
|
||||
```
|
||||
1. impact({target: "validateUser", direction: "upstream"}) or `node .gitnexus/run.cjs impact "validateUser" --direction upstream --repo .`
|
||||
0. list_repos {}
|
||||
→ total: 2 (my-app, billing-api) — both define validateUser, so bind explicitly
|
||||
|
||||
1. impact({target: "validateUser", repo: "my-app", direction: "upstream"}) or `node .gitnexus/run.cjs impact "validateUser" --direction upstream --repo .`
|
||||
→ d=1: loginHandler, apiMiddleware (WILL BREAK)
|
||||
→ d=2: authRouter, sessionManager (LIKELY AFFECTED)
|
||||
|
||||
|
|
@ -108,4 +151,8 @@ than tick the pre-commit check.
|
|||
→ LoginFlow and TokenRefresh touch validateUser
|
||||
|
||||
3. Risk: 2 direct callers, 2 processes = MEDIUM
|
||||
Repository: my-app (/abs/path/my-app) Worktree: same Index: current
|
||||
```
|
||||
|
||||
With a single indexed repository, step 0 returns `total: 1` and the `repo`
|
||||
argument drops out of every call above.
|
||||
|
|
|
|||
|
|
@ -13,9 +13,29 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|||
- "Move this to a new file"
|
||||
- Any task involving renaming, extracting, splitting, or restructuring code
|
||||
|
||||
## Bind the repository first
|
||||
|
||||
Refactoring writes to disk. `rename` with `dry_run: false` edits files in
|
||||
whichever repository was resolved, so binding identity here is a safety gate,
|
||||
not bookkeeping.
|
||||
|
||||
Call `list_repos {}` before the first tool call. With one indexed repository,
|
||||
use the examples below as written. With more than one, pass `repo` on every
|
||||
call: an omitted `repo` normally errors, but under an MCP policy with a
|
||||
configured default it resolves to that default silently. If you cannot tell
|
||||
which repository is meant, stop and ask. Never run `rename` with
|
||||
`dry_run: false` until the preview in the same bound repository has been
|
||||
reviewed — its returned `file_path` values show which checkout is about to be
|
||||
written, so read them as a confirmation of identity.
|
||||
|
||||
`detect_changes` takes `worktree` when you are editing a linked worktree the
|
||||
MCP server was not launched from; otherwise `git diff` runs in the wrong
|
||||
checkout and reports nothing changed, which reads as a verified refactor.
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
0. list_repos {} → Bind repo (and worktree)
|
||||
1. impact({target: "X", direction: "upstream"}) → Map all dependents
|
||||
2. query({search_query: "X"}) → Find execution flows involving X
|
||||
3. context({name: "X"}) → See all incoming/outgoing refs
|
||||
|
|
@ -29,7 +49,9 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|||
### Rename Symbol
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] rename({symbol_name: "oldName", new_name: "newName", dry_run: true}) — preview all edits
|
||||
- [ ] Confirm the previewed file paths are in the bound repository/worktree
|
||||
- [ ] Review graph edits (high confidence) and text_search edits (review carefully)
|
||||
- [ ] If satisfied: rename({..., dry_run: false}) — apply edits
|
||||
- [ ] detect_changes() — verify only expected files changed
|
||||
|
|
@ -39,6 +61,7 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|||
### Extract Module
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] context({name: target}) — see all incoming/outgoing refs
|
||||
- [ ] impact({target, direction: "upstream"}) — find all external callers
|
||||
- [ ] Define new module interface
|
||||
|
|
@ -50,6 +73,7 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|||
### Split Function/Service
|
||||
|
||||
```
|
||||
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
|
||||
- [ ] context({name: target}) — understand all callees
|
||||
- [ ] Group callees by responsibility
|
||||
- [ ] impact({target, direction: "upstream"}) — map callers to update
|
||||
|
|
@ -64,7 +88,7 @@ description: "Use when the user wants to rename, extract, split, move, or restru
|
|||
**rename** — automated multi-file rename:
|
||||
|
||||
```
|
||||
rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true})
|
||||
rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: true})
|
||||
→ 12 edits across 8 files
|
||||
→ 10 graph edits (high confidence), 2 text_search edits (review)
|
||||
→ Changes: [{file_path, edits: [{line, old_text, new_text, confidence}]}]
|
||||
|
|
@ -73,7 +97,7 @@ rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true
|
|||
**impact** — map all dependents first:
|
||||
|
||||
```
|
||||
impact({target: "validateUser", direction: "upstream"})
|
||||
impact({target: "validateUser", repo: "my-app", direction: "upstream"})
|
||||
→ d=1: loginHandler, apiMiddleware, testUtils
|
||||
→ Affected Processes: LoginFlow, TokenRefresh
|
||||
```
|
||||
|
|
@ -92,6 +116,9 @@ listing was capped) means the result is short of the truth: a short or empty
|
|||
list is not proof that only the expected files changed. Re-run it rather than
|
||||
treat the refactor as verified.
|
||||
|
||||
A wrong-worktree zero carries neither flag and is indistinguishable from a
|
||||
clean verification, so confirm the diffed checkout is the one you edited.
|
||||
|
||||
**cypher** — custom reference queries:
|
||||
|
||||
```cypher
|
||||
|
|
@ -107,20 +134,28 @@ RETURN caller.name, caller.filePath ORDER BY caller.filePath
|
|||
| Cross-area refs | Use detect_changes after to verify scope |
|
||||
| String/dynamic refs | query to find them |
|
||||
| External/public API | Version and deprecate properly |
|
||||
| Same name in another indexed repo | Bind `repo`; verify previewed paths before applying |
|
||||
|
||||
## Example: Rename `validateUser` to `authenticateUser`
|
||||
|
||||
```
|
||||
1. rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true})
|
||||
0. list_repos {}
|
||||
→ total: 2 (my-app, billing-api) — both define validateUser, so bind explicitly
|
||||
|
||||
1. rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: true})
|
||||
→ 12 edits: 10 graph (safe), 2 text_search (review)
|
||||
→ Files: validator.ts, login.ts, middleware.ts, config.json...
|
||||
|
||||
2. Review text_search edits (config.json: dynamic reference!)
|
||||
|
||||
3. rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: false})
|
||||
3. rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: false})
|
||||
→ Applied 12 edits across 8 files
|
||||
|
||||
4. detect_changes({scope: "all"})
|
||||
4. detect_changes({scope: "all", repo: "my-app"})
|
||||
→ Affected: LoginFlow, TokenRefresh
|
||||
→ Risk: MEDIUM — run tests for these flows
|
||||
Repository: my-app (/abs/path/my-app) Worktree: same Index: current
|
||||
```
|
||||
|
||||
With a single indexed repository, step 0 returns `total: 1` and the `repo`
|
||||
argument drops out of every call above.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue