diff --git a/gitnexus-claude-plugin/hooks/gitnexus-hook.js b/gitnexus-claude-plugin/hooks/gitnexus-hook.js index 4cc79c100b..3ec29b2658 100644 --- a/gitnexus-claude-plugin/hooks/gitnexus-hook.js +++ b/gitnexus-claude-plugin/hooks/gitnexus-hook.js @@ -69,7 +69,7 @@ function extractPattern(toolName, toolInput) { for (const token of tokens) { if (skipNext) { skipNext = false; continue; } if (!foundCmd) { - if (/\brg$|\bgrep$/.test(token)) foundCmd = true; + if (/\brg\b|\bgrep\b/.test(token)) foundCmd = true; continue; } if (token.startsWith('-')) { diff --git a/gitnexus-factory-plugin/.factory-plugin/plugin.json b/gitnexus-factory-plugin/.factory-plugin/plugin.json new file mode 100644 index 0000000000..a849ca337f --- /dev/null +++ b/gitnexus-factory-plugin/.factory-plugin/plugin.json @@ -0,0 +1,12 @@ +{ + "name": "gitnexus", + "description": "Code intelligence powered by a knowledge graph. Provides execution flow tracing, blast radius analysis, and augmented search across your codebase.", + "version": "1.0.0", + "author": { + "name": "Wojciech Guziak", + "url": "https://github.com/mrwogu" + }, + "homepage": "https://github.com/abhigyanpatwari/GitNexus", + "repository": "https://github.com/abhigyanpatwari/GitNexus", + "keywords": ["code-intelligence", "knowledge-graph", "mcp", "static-analysis"] +} diff --git a/gitnexus-factory-plugin/hooks/gitnexus-hook.js b/gitnexus-factory-plugin/hooks/gitnexus-hook.js new file mode 100644 index 0000000000..fcea7dbc1d --- /dev/null +++ b/gitnexus-factory-plugin/hooks/gitnexus-hook.js @@ -0,0 +1,146 @@ +#!/usr/bin/env node +/** + * GitNexus Factory AI Plugin Hook + * + * PostToolUse handler — augments Grep/Glob/Execute searches + * and augments with graph context from the GitNexus index. + */ + +const fs = require('fs'); +const path = require('path'); +const { spawnSync } = require('child_process'); + +/** + * Read JSON input from stdin synchronously. + */ +function readInput() { + try { + const data = fs.readFileSync(0, 'utf-8'); + return JSON.parse(data); + } catch { + return {}; + } +} + +/** + * Check if a directory (or ancestor) has a .gitnexus index. + */ +function findGitNexusIndex(startDir) { + let dir = startDir || process.cwd(); + for (let i = 0; i < 5; i++) { + if (fs.existsSync(path.join(dir, '.gitnexus'))) { + return true; + } + const parent = path.dirname(dir); + if (parent === dir) break; + dir = parent; + } + return false; +} + +/** + * Extract search pattern from tool input. + */ +function extractPattern(toolName, toolInput) { + if (toolName === 'Grep') { + return toolInput.pattern || null; + } + + if (toolName === 'Glob') { + const raw = toolInput.pattern || ''; + const match = raw.match(/[*\/]([a-zA-Z][a-zA-Z0-9_-]{2,})/); + return match ? match[1] : null; + } + + if (toolName === 'Execute') { + const cmd = toolInput.command || ''; + if (!/\brg\b|\bgrep\b/.test(cmd)) return null; + + const tokens = cmd.split(/\s+/); + let foundCmd = false; + let skipNext = false; + const flagsWithValues = new Set(['-e', '-f', '-m', '-A', '-B', '-C', '-g', '--glob', '-t', '--type', '--include', '--exclude']); + + for (const token of tokens) { + if (skipNext) { skipNext = false; continue; } + if (!foundCmd) { + if (/\brg\b|\bgrep\b/.test(token)) foundCmd = true; + continue; + } + if (token.startsWith('-')) { + if (flagsWithValues.has(token)) skipNext = true; + continue; + } + const cleaned = token.replace(/['"]/g, ''); + return cleaned.length >= 3 ? cleaned : null; + } + return null; + } + + return null; +} + +function main() { + try { + const input = readInput(); + const hookEvent = input.hook_event_name || ''; + + if (hookEvent !== 'PostToolUse') return; + + const cwd = input.cwd || process.cwd(); + if (!findGitNexusIndex(cwd)) return; + + const toolName = input.tool_name || ''; + const toolInput = input.tool_input || {}; + + if (toolName !== 'Grep' && toolName !== 'Glob' && toolName !== 'Execute') return; + + const pattern = extractPattern(toolName, toolInput); + if (!pattern || pattern.length < 3) return; + + // augment CLI writes result to stderr (KuzuDB's native module captures + // stdout fd at OS level, making it unusable in subprocess contexts). + let result = ''; + + const isWin = process.platform === 'win32'; + + // Try direct gitnexus binary first (faster if globally installed) + try { + const child = spawnSync( + 'gitnexus', + ['augment', pattern], + { encoding: 'utf-8', timeout: 8000, cwd, stdio: ['pipe', 'pipe', 'pipe'], shell: isWin } + ); + if (child.status === 0 && child.stderr && child.stderr.trim()) { + result = child.stderr; + } + } catch { /* not on PATH */ } + + // Fallback to npx if direct binary didn't produce output + if (!result || !result.trim()) { + try { + const child = spawnSync( + 'npx', + ['-y', 'gitnexus', 'augment', pattern], + { encoding: 'utf-8', timeout: 8000, cwd, stdio: ['pipe', 'pipe', 'pipe'], shell: isWin } + ); + if (child.status === 0 && child.stderr && child.stderr.trim()) { + result = child.stderr; + } + } catch { /* graceful failure */ } + } + + if (result && result.trim()) { + console.log(JSON.stringify({ + hookSpecificOutput: { + hookEventName: 'PostToolUse', + additionalContext: result.trim() + } + })); + } + } catch { + // Graceful failure + } +} + +main(); diff --git a/gitnexus-factory-plugin/hooks/hooks.json b/gitnexus-factory-plugin/hooks/hooks.json new file mode 100644 index 0000000000..4659a18e5a --- /dev/null +++ b/gitnexus-factory-plugin/hooks/hooks.json @@ -0,0 +1,14 @@ +{ + "PostToolUse": [ + { + "matcher": "Grep|Glob|Execute", + "hooks": [ + { + "type": "command", + "command": "node ${DROID_PLUGIN_ROOT}/hooks/gitnexus-hook.js", + "timeout": 10 + } + ] + } + ] +} diff --git a/gitnexus-factory-plugin/mcp.json b/gitnexus-factory-plugin/mcp.json new file mode 100644 index 0000000000..cd02d4285a --- /dev/null +++ b/gitnexus-factory-plugin/mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "gitnexus": { + "command": "npx", + "args": ["-y", "gitnexus@latest", "mcp"] + } + } +} diff --git a/gitnexus-factory-plugin/skills/gitnexus-cli/SKILL.md b/gitnexus-factory-plugin/skills/gitnexus-cli/SKILL.md new file mode 100644 index 0000000000..5f4c7c5f77 --- /dev/null +++ b/gitnexus-factory-plugin/skills/gitnexus-cli/SKILL.md @@ -0,0 +1,82 @@ +--- +name: gitnexus-cli +description: "Use when the user needs to run GitNexus CLI commands like analyze/index a repo, check status, clean the index, generate a wiki, or list indexed repos. Examples: \"Index this repo\", \"Reanalyze the codebase\", \"Generate a wiki\"" +--- + +# GitNexus CLI Commands + +All commands work via `npx` — no global install required. + +## Commands + +### analyze — Build or refresh the index + +```bash +npx gitnexus analyze +``` + +Run from the project root. This parses all source files, builds the knowledge graph, writes it to `.gitnexus/`, and generates FACTORY.md / AGENTS.md context files. + +| Flag | Effect | +|------|--------| +| `--force` | Force full re-index even if up to date | +| `--embeddings` | Enable embedding generation for semantic search (off by default) | + +**When to run:** First time in a project, after major code changes, or when `gitnexus://repo/{name}/context` reports the index is stale. + +### status — Check index freshness + +```bash +npx gitnexus status +``` + +Shows whether the current repo has a GitNexus index, when it was last updated, and symbol/relationship counts. Use this to check if re-indexing is needed. + +### clean — Delete the index + +```bash +npx gitnexus clean +``` + +Deletes the `.gitnexus/` directory and unregisters the repo from the global registry. Use before re-indexing if the index is corrupt or after removing GitNexus from a project. + +| Flag | Effect | +|------|--------| +| `--force` | Skip confirmation prompt | +| `--all` | Clean all indexed repos, not just the current one | + +### wiki — Generate documentation from the graph + +```bash +npx gitnexus wiki +``` + +Generates repository documentation from the knowledge graph using an LLM. Requires an API key (saved to `~/.gitnexus/config.json` on first use). + +| Flag | Effect | +|------|--------| +| `--force` | Force full regeneration | +| `--model ` | LLM model (default: minimax/minimax-m2.5) | +| `--base-url ` | LLM API base URL | +| `--api-key ` | LLM API key | +| `--concurrency ` | Parallel LLM calls (default: 3) | +| `--gist` | Publish wiki as a public GitHub Gist | + +### list — Show all indexed repos + +```bash +npx gitnexus list +``` + +Lists all repositories registered in `~/.gitnexus/registry.json`. The MCP `list_repos` tool provides the same information. + +## After Indexing + +1. **Read `gitnexus://repo/{name}/context`** to verify the index loaded +2. Use the other GitNexus skills (`exploring`, `debugging`, `impact-analysis`, `refactoring`) for your task + +## Troubleshooting + +- **"Not inside a git repository"**: Run from a directory inside a git repo +- **Index is stale after re-analyzing**: Restart Factory AI (droid) to reload the MCP server +- **Embeddings slow**: Omit `--embeddings` (it's off by default) or set `OPENAI_API_KEY` for faster API-based embedding diff --git a/gitnexus-factory-plugin/skills/gitnexus-debugging/SKILL.md b/gitnexus-factory-plugin/skills/gitnexus-debugging/SKILL.md new file mode 100644 index 0000000000..9510b97ac3 --- /dev/null +++ b/gitnexus-factory-plugin/skills/gitnexus-debugging/SKILL.md @@ -0,0 +1,89 @@ +--- +name: gitnexus-debugging +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 + +## Workflow + +``` +1. gitnexus_query({query: ""}) → Find related execution flows +2. gitnexus_context({name: ""}) → See callers/callees/processes +3. READ gitnexus://repo/{name}/process/{name} → Trace execution flow +4. gitnexus_cypher({query: "MATCH path..."}) → Custom traces if needed +``` + +> If "Index is stale" → run `npx gitnexus analyze` in terminal. + +## Checklist + +``` +- [ ] Understand the symptom (error message, unexpected behavior) +- [ ] gitnexus_query for error text or related code +- [ ] Identify the suspect function from returned processes +- [ ] gitnexus_context to see callers and callees +- [ ] Trace execution flow via process resource if applicable +- [ ] gitnexus_cypher for custom call chain traces if needed +- [ ] Read source files to confirm root cause +``` + +## Debugging Patterns + +| Symptom | GitNexus Approach | +| -------------------- | ---------------------------------------------------------- | +| Error message | `gitnexus_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 | + +## Tools + +**gitnexus_query** — find code related to error: + +``` +gitnexus_query({query: "payment validation error"}) +→ Processes: CheckoutFlow, ErrorHandling +→ Symbols: validatePayment, handlePaymentError, PaymentException +``` + +**gitnexus_context** — full context for a suspect: + +``` +gitnexus_context({name: "validatePayment"}) +→ Incoming calls: processCheckout, webhookHandler +→ Outgoing calls: verifyCard, fetchRates (external API!) +→ Processes: CheckoutFlow (step 3/7) +``` + +**gitnexus_cypher** — custom call chain traces: + +```cypher +MATCH path = (a)-[:CodeRelation {type: 'CALLS'}*1..2]->(b:Function {name: "validatePayment"}) +RETURN [n IN nodes(path) | n.name] AS chain +``` + +## Example: "Payment endpoint returns 500 intermittently" + +``` +1. gitnexus_query({query: "payment error handling"}) + → Processes: CheckoutFlow, ErrorHandling + → Symbols: validatePayment, handlePaymentError + +2. gitnexus_context({name: "validatePayment"}) + → 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 +``` diff --git a/gitnexus-factory-plugin/skills/gitnexus-exploring/SKILL.md b/gitnexus-factory-plugin/skills/gitnexus-exploring/SKILL.md new file mode 100644 index 0000000000..927a4e4b64 --- /dev/null +++ b/gitnexus-factory-plugin/skills/gitnexus-exploring/SKILL.md @@ -0,0 +1,78 @@ +--- +name: gitnexus-exploring +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 + +## Workflow + +``` +1. READ gitnexus://repos → Discover indexed repos +2. READ gitnexus://repo/{name}/context → Codebase overview, check staleness +3. gitnexus_query({query: ""}) → Find related execution flows +4. gitnexus_context({name: ""}) → Deep dive on specific symbol +5. READ gitnexus://repo/{name}/process/{name} → Trace full execution flow +``` + +> If step 2 says "Index is stale" → run `npx gitnexus analyze` in terminal. + +## Checklist + +``` +- [ ] READ gitnexus://repo/{name}/context +- [ ] gitnexus_query for the concept you want to understand +- [ ] Review returned processes (execution flows) +- [ ] gitnexus_context on key symbols for callers/callees +- [ ] READ process resource for full execution traces +- [ ] Read source files for implementation details +``` + +## 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) | + +## Tools + +**gitnexus_query** — find execution flows related to a concept: + +``` +gitnexus_query({query: "payment processing"}) +→ Processes: CheckoutFlow, RefundFlow, WebhookHandler +→ Symbols grouped by flow with file locations +``` + +**gitnexus_context** — 360-degree view of a symbol: + +``` +gitnexus_context({name: "validateUser"}) +→ Incoming calls: loginHandler, apiMiddleware +→ Outgoing calls: checkToken, getUserById +→ Processes: LoginFlow (step 2/5), TokenRefresh (step 1/3) +``` + +## Example: "How does payment processing work?" + +``` +1. READ gitnexus://repo/my-app/context → 918 symbols, 45 processes +2. gitnexus_query({query: "payment processing"}) + → CheckoutFlow: processPayment → validateCard → chargeStripe + → RefundFlow: initiateRefund → calculateRefund → processRefund +3. gitnexus_context({name: "processPayment"}) + → Incoming: checkoutHandler, webhookHandler + → Outgoing: validateCard, chargeStripe, saveTransaction +4. Read src/payments/processor.ts for implementation details +``` diff --git a/gitnexus-factory-plugin/skills/gitnexus-guide/SKILL.md b/gitnexus-factory-plugin/skills/gitnexus-guide/SKILL.md new file mode 100644 index 0000000000..937ac73d16 --- /dev/null +++ b/gitnexus-factory-plugin/skills/gitnexus-guide/SKILL.md @@ -0,0 +1,64 @@ +--- +name: gitnexus-guide +description: "Use when the user asks about GitNexus itself — available tools, how to query the knowledge graph, MCP resources, graph schema, or workflow reference. Examples: \"What GitNexus tools are available?\", \"How do I use GitNexus?\"" +--- + +# GitNexus Guide + +Quick reference for all GitNexus MCP tools, resources, and the knowledge graph schema. + +## Always Start Here + +For any task involving code understanding, debugging, impact analysis, or refactoring: + +1. **Read `gitnexus://repo/{name}/context`** — codebase overview + check index freshness +2. **Match your task to a skill below** and **read that skill file** +3. **Follow the skill's workflow and checklist** + +> If step 1 warns the index is stale, run `npx gitnexus analyze` in the terminal first. + +## Skills + +| Task | Skill to read | +| -------------------------------------------- | ------------------- | +| Understand architecture / "How does X work?" | `gitnexus-exploring` | +| Blast radius / "What breaks if I change X?" | `gitnexus-impact-analysis` | +| Trace bugs / "Why is X failing?" | `gitnexus-debugging` | +| Rename / extract / split / refactor | `gitnexus-refactoring` | +| Tools, resources, schema reference | `gitnexus-guide` (this file) | +| Index, status, clean, wiki CLI commands | `gitnexus-cli` | + +## Tools Reference + +| Tool | What it gives you | +| ---------------- | ------------------------------------------------------------------------ | +| `query` | Process-grouped code intelligence — execution flows related to a concept | +| `context` | 360-degree symbol view — categorized refs, processes it participates in | +| `impact` | Symbol blast radius — what breaks at depth 1/2/3 with confidence | +| `detect_changes` | Git-diff impact — what do your current changes affect | +| `rename` | Multi-file coordinated rename with confidence-tagged edits | +| `cypher` | Raw graph queries (read `gitnexus://repo/{name}/schema` first) | +| `list_repos` | Discover indexed repos | + +## Resources Reference + +Lightweight reads (~100-500 tokens) for navigation: + +| Resource | Content | +| ---------------------------------------------- | ----------------------------------------- | +| `gitnexus://repo/{name}/context` | Stats, staleness check | +| `gitnexus://repo/{name}/clusters` | All functional areas with cohesion scores | +| `gitnexus://repo/{name}/cluster/{clusterName}` | Area members | +| `gitnexus://repo/{name}/processes` | All execution flows | +| `gitnexus://repo/{name}/process/{processName}` | Step-by-step trace | +| `gitnexus://repo/{name}/schema` | Graph schema for Cypher | + +## Graph Schema + +**Nodes:** File, Function, Class, Interface, Method, Community, Process +**Edges (via CodeRelation.type):** CALLS, IMPORTS, EXTENDS, IMPLEMENTS, DEFINES, MEMBER_OF, STEP_IN_PROCESS + +```cypher +MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "myFunc"}) +RETURN caller.name, caller.filePath +``` diff --git a/gitnexus-factory-plugin/skills/gitnexus-impact-analysis/SKILL.md b/gitnexus-factory-plugin/skills/gitnexus-impact-analysis/SKILL.md new file mode 100644 index 0000000000..e19af280c1 --- /dev/null +++ b/gitnexus-factory-plugin/skills/gitnexus-impact-analysis/SKILL.md @@ -0,0 +1,97 @@ +--- +name: gitnexus-impact-analysis +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" +- "Who uses this code?" +- Before making non-trivial code changes +- Before committing — to understand what your changes affect + +## Workflow + +``` +1. gitnexus_impact({target: "X", direction: "upstream"}) → What depends on this +2. READ gitnexus://repo/{name}/processes → Check affected execution flows +3. gitnexus_detect_changes() → Map current git changes to affected flows +4. Assess risk and report to user +``` + +> If "Index is stale" → run `npx gitnexus analyze` in terminal. + +## Checklist + +``` +- [ ] gitnexus_impact({target, direction: "upstream"}) to find dependents +- [ ] Review d=1 items first (these WILL BREAK) +- [ ] Check high-confidence (>0.8) dependencies +- [ ] READ processes to check affected execution flows +- [ ] gitnexus_detect_changes() for pre-commit check +- [ ] Assess risk level and report to user +``` + +## 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 | + +## Risk Assessment + +| 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 | + +## Tools + +**gitnexus_impact** — the primary tool for symbol blast radius: + +``` +gitnexus_impact({ + target: "validateUser", + direction: "upstream", + minConfidence: 0.8, + maxDepth: 3 +}) + +→ d=1 (WILL BREAK): + - loginHandler (src/auth/login.ts:42) [CALLS, 100%] + - apiMiddleware (src/api/middleware.ts:15) [CALLS, 100%] + +→ d=2 (LIKELY AFFECTED): + - authRouter (src/routes/auth.ts:22) [CALLS, 95%] +``` + +**gitnexus_detect_changes** — git-diff based impact analysis: + +``` +gitnexus_detect_changes({scope: "staged"}) + +→ Changed: 5 symbols in 3 files +→ Affected: LoginFlow, TokenRefresh, APIMiddlewarePipeline +→ Risk: MEDIUM +``` + +## Example: "What breaks if I change validateUser?" + +``` +1. gitnexus_impact({target: "validateUser", direction: "upstream"}) + → d=1: loginHandler, apiMiddleware (WILL BREAK) + → d=2: authRouter, sessionManager (LIKELY AFFECTED) + +2. READ gitnexus://repo/my-app/processes + → LoginFlow and TokenRefresh touch validateUser + +3. Risk: 2 direct callers, 2 processes = MEDIUM +``` diff --git a/gitnexus-factory-plugin/skills/gitnexus-pr-review/SKILL.md b/gitnexus-factory-plugin/skills/gitnexus-pr-review/SKILL.md new file mode 100644 index 0000000000..e112f47baa --- /dev/null +++ b/gitnexus-factory-plugin/skills/gitnexus-pr-review/SKILL.md @@ -0,0 +1,163 @@ +--- +name: gitnexus-pr-review +description: "Use when the user wants to review a pull request, understand what a PR changes, assess risk of merging, or check for missing test coverage. Examples: \"Review this PR\", \"What does PR #42 change?\", \"Is this PR safe to merge?\"" +--- + +# PR Review with GitNexus + +## When to Use + +- "Review this PR" +- "What does PR #42 change?" +- "Is this safe to merge?" +- "What's the blast radius of this PR?" +- "Are there missing tests for this PR?" +- Reviewing someone else's code changes before merge + +## Workflow + +``` +1. gh pr diff → Get the raw diff +2. gitnexus_detect_changes({scope: "compare", base_ref: "main"}) → Map diff to affected flows +3. For each changed symbol: + gitnexus_impact({target: "", direction: "upstream"}) → Blast radius per change +4. gitnexus_context({name: ""}) → Understand callers/callees +5. READ gitnexus://repo/{name}/processes → Check affected execution flows +6. Summarize findings with risk assessment +``` + +> If "Index is stale" → run `npx gitnexus analyze` in terminal before reviewing. + +## Checklist + +``` +- [ ] Fetch PR diff (gh pr diff or git diff base...head) +- [ ] gitnexus_detect_changes to map changes to affected execution flows +- [ ] gitnexus_impact on each non-trivial changed symbol +- [ ] Review d=1 items (WILL BREAK) — are callers updated? +- [ ] gitnexus_context on key changed symbols to understand full picture +- [ ] Check if affected processes have test coverage +- [ ] Assess overall risk level +- [ ] Write review summary with findings +``` + +## Review Dimensions + +| Dimension | How GitNexus Helps | +| --- | --- | +| **Correctness** | `context` shows callers — are they all compatible with the change? | +| **Blast radius** | `impact` shows d=1/d=2/d=3 dependents — anything missed? | +| **Completeness** | `detect_changes` shows all affected flows — are they all handled? | +| **Test coverage** | `impact({includeTests: true})` shows which tests touch changed code | +| **Breaking changes** | d=1 upstream items that aren't updated in the PR = potential breakage | + +## Risk Assessment + +| Signal | Risk | +| --- | --- | +| Changes touch <3 symbols, 0-1 processes | LOW | +| Changes touch 3-10 symbols, 2-5 processes | MEDIUM | +| Changes touch >10 symbols or many processes | HIGH | +| Changes touch auth, payments, or data integrity code | CRITICAL | +| d=1 callers exist outside the PR diff | Potential breakage — flag it | + +## Tools + +**gitnexus_detect_changes** — map PR diff to affected execution flows: + +``` +gitnexus_detect_changes({scope: "compare", base_ref: "main"}) + +→ Changed: 8 symbols in 4 files +→ Affected processes: CheckoutFlow, RefundFlow, WebhookHandler +→ Risk: MEDIUM +``` + +**gitnexus_impact** — blast radius per changed symbol: + +``` +gitnexus_impact({target: "validatePayment", direction: "upstream"}) + +→ d=1 (WILL BREAK): + - processCheckout (src/checkout.ts:42) [CALLS, 100%] + - webhookHandler (src/webhooks.ts:15) [CALLS, 100%] + +→ d=2 (LIKELY AFFECTED): + - checkoutRouter (src/routes/checkout.ts:22) [CALLS, 95%] +``` + +**gitnexus_impact with tests** — check test coverage: + +``` +gitnexus_impact({target: "validatePayment", direction: "upstream", includeTests: true}) + +→ Tests that cover this symbol: + - validatePayment.test.ts [direct] + - checkout.integration.test.ts [via processCheckout] +``` + +**gitnexus_context** — understand a changed symbol's role: + +``` +gitnexus_context({name: "validatePayment"}) + +→ Incoming calls: processCheckout, webhookHandler +→ Outgoing calls: verifyCard, fetchRates +→ Processes: CheckoutFlow (step 3/7), RefundFlow (step 1/5) +``` + +## Example: "Review PR #42" + +``` +1. gh pr diff 42 > /tmp/pr42.diff + → 4 files changed: payments.ts, checkout.ts, types.ts, utils.ts + +2. gitnexus_detect_changes({scope: "compare", base_ref: "main"}) + → Changed symbols: validatePayment, PaymentInput, formatAmount + → Affected processes: CheckoutFlow, RefundFlow + → Risk: MEDIUM + +3. gitnexus_impact({target: "validatePayment", direction: "upstream"}) + → d=1: processCheckout, webhookHandler (WILL BREAK) + → webhookHandler is NOT in the PR diff — potential breakage! + +4. gitnexus_impact({target: "PaymentInput", direction: "upstream"}) + → d=1: validatePayment (in PR), createPayment (NOT in PR) + → createPayment uses the old PaymentInput shape — breaking change! + +5. gitnexus_context({name: "formatAmount"}) + → Called by 12 functions — but change is backwards-compatible (added optional param) + +6. Review summary: + - MEDIUM risk — 3 changed symbols affect 2 execution flows + - BUG: webhookHandler calls validatePayment but isn't updated for new signature + - BUG: createPayment depends on PaymentInput type which changed + - OK: formatAmount change is backwards-compatible + - Tests: checkout.test.ts covers processCheckout path, but no webhook test +``` + +## Review Output Format + +Structure your review as: + +```markdown +## PR Review: + +**Risk: LOW / MEDIUM / HIGH / CRITICAL** + +### Changes Summary +- <N> symbols changed across <M> files +- <P> execution flows affected + +### Findings +1. **[severity]** Description of finding + - Evidence from GitNexus tools + - Affected callers/flows + +### Missing Coverage +- Callers not updated in PR: ... +- Untested flows: ... + +### Recommendation +APPROVE / REQUEST CHANGES / NEEDS DISCUSSION +``` diff --git a/gitnexus-factory-plugin/skills/gitnexus-refactoring/SKILL.md b/gitnexus-factory-plugin/skills/gitnexus-refactoring/SKILL.md new file mode 100644 index 0000000000..f48cc01bd5 --- /dev/null +++ b/gitnexus-factory-plugin/skills/gitnexus-refactoring/SKILL.md @@ -0,0 +1,121 @@ +--- +name: gitnexus-refactoring +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 + +## Workflow + +``` +1. gitnexus_impact({target: "X", direction: "upstream"}) → Map all dependents +2. gitnexus_query({query: "X"}) → Find execution flows involving X +3. gitnexus_context({name: "X"}) → See all incoming/outgoing refs +4. Plan update order: interfaces → implementations → callers → tests +``` + +> If "Index is stale" → run `npx gitnexus analyze` in terminal. + +## Checklists + +### Rename Symbol + +``` +- [ ] gitnexus_rename({symbol_name: "oldName", new_name: "newName", dry_run: true}) — preview all edits +- [ ] Review graph edits (high confidence) and ast_search edits (review carefully) +- [ ] If satisfied: gitnexus_rename({..., dry_run: false}) — apply edits +- [ ] gitnexus_detect_changes() — verify only expected files changed +- [ ] Run tests for affected processes +``` + +### Extract Module + +``` +- [ ] gitnexus_context({name: target}) — see all incoming/outgoing refs +- [ ] gitnexus_impact({target, direction: "upstream"}) — find all external callers +- [ ] Define new module interface +- [ ] Extract code, update imports +- [ ] gitnexus_detect_changes() — verify affected scope +- [ ] Run tests for affected processes +``` + +### Split Function/Service + +``` +- [ ] gitnexus_context({name: target}) — understand all callees +- [ ] Group callees by responsibility +- [ ] gitnexus_impact({target, direction: "upstream"}) — map callers to update +- [ ] Create new functions/services +- [ ] Update callers +- [ ] gitnexus_detect_changes() — verify affected scope +- [ ] Run tests for affected processes +``` + +## Tools + +**gitnexus_rename** — automated multi-file rename: + +``` +gitnexus_rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true}) +→ 12 edits across 8 files +→ 10 graph edits (high confidence), 2 ast_search edits (review) +→ Changes: [{file_path, edits: [{line, old_text, new_text, confidence}]}] +``` + +**gitnexus_impact** — map all dependents first: + +``` +gitnexus_impact({target: "validateUser", direction: "upstream"}) +→ d=1: loginHandler, apiMiddleware, testUtils +→ Affected Processes: LoginFlow, TokenRefresh +``` + +**gitnexus_detect_changes** — verify your changes after refactoring: + +``` +gitnexus_detect_changes({scope: "all"}) +→ Changed: 8 files, 12 symbols +→ Affected processes: LoginFlow, TokenRefresh +→ Risk: MEDIUM +``` + +**gitnexus_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 + +| Risk Factor | Mitigation | +| ------------------- | ----------------------------------------- | +| Many callers (>5) | Use gitnexus_rename for automated updates | +| Cross-area refs | Use detect_changes after to verify scope | +| String/dynamic refs | gitnexus_query to find them | +| External/public API | Version and deprecate properly | + +## Example: Rename `validateUser` to `authenticateUser` + +``` +1. gitnexus_rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true}) + → 12 edits: 10 graph (safe), 2 ast_search (review) + → Files: validator.ts, login.ts, middleware.ts, config.json... + +2. Review ast_search edits (config.json: dynamic reference!) + +3. gitnexus_rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: false}) + → Applied 12 edits across 8 files + +4. gitnexus_detect_changes({scope: "all"}) + → Affected: LoginFlow, TokenRefresh + → Risk: MEDIUM — run tests for these flows +``` diff --git a/gitnexus/hooks/claude/gitnexus-hook.cjs b/gitnexus/hooks/claude/gitnexus-hook.cjs index 55e694fa2b..a9181f85e4 100755 --- a/gitnexus/hooks/claude/gitnexus-hook.cjs +++ b/gitnexus/hooks/claude/gitnexus-hook.cjs @@ -69,7 +69,7 @@ function extractPattern(toolName, toolInput) { for (const token of tokens) { if (skipNext) { skipNext = false; continue; } if (!foundCmd) { - if (/\brg$|\bgrep$/.test(token)) foundCmd = true; + if (/\brg\b|\bgrep\b/.test(token)) foundCmd = true; continue; } if (token.startsWith('-')) {