fix(claude-skills): inline identity contract and sync shipped copies

This commit is contained in:
sanguine59 2026-08-16 14:55:31 +07:00
parent df73552178
commit 6772350105
20 changed files with 612 additions and 535 deletions

View file

@ -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:

View file

@ -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.

View file

@ -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

View file

@ -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.

View file

@ -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)

View file

@ -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.

View file

@ -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"})

View file

@ -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.

View file

@ -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.

View file

@ -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"`.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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"`.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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"`.

View file

@ -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.

View file

@ -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.