diff --git a/gitnexus/package.json b/gitnexus/package.json index c4403f9d8..5595b2c17 100644 --- a/gitnexus/package.json +++ b/gitnexus/package.json @@ -9,7 +9,8 @@ "gitnexus": "./dist/cli/index.js" }, "files": [ - "dist" + "dist", + "skills" ], "scripts": { "build": "tsc", diff --git a/gitnexus/skills/debugging.md b/gitnexus/skills/debugging.md new file mode 100644 index 000000000..ac75c13d2 --- /dev/null +++ b/gitnexus/skills/debugging.md @@ -0,0 +1,122 @@ +--- +name: gitnexus-debugging +description: Trace bugs through call chains using knowledge graph +--- + +# Debugging with GitNexus + +## Quick Start +1. `gitnexus_search(query)` → Find code related to the error +2. `gitnexus_explore(name, "symbol")` → Get callers and callees +3. `gitnexus_cypher` → Trace specific dependency paths + +## When to Use +- "Why is this function failing?" +- "Trace where this error comes from" +- "Who calls this method?" +- "Debug the payment issue" + +## Workflow +``` +Bug Investigation: +- [ ] Understand the symptom (error message, behavior) +- [ ] gitnexus_search to find related code +- [ ] Identify the suspect function +- [ ] gitnexus_explore to see callers/callees +- [ ] Check which processes the suspect is in +- [ ] Trace dependencies with gitnexus_cypher +- [ ] Form hypothesis and verify +``` + +## Tool Reference + +### gitnexus_search +Find code related to error or symptom. +``` +gitnexus_search({ + query: "payment validation error", + depth: "full", + groupByProcess: true +}) +→ validatePayment, handlePaymentError, PaymentException +→ Grouped by: CheckoutFlow, RefundFlow +``` + +### gitnexus_explore (for symbol) +Get symbol context. +``` +gitnexus_explore({name: "validatePayment", type: "symbol"}) +→ Callers: processCheckout, webhookHandler +→ Callees: verifyCard, fetchRates +→ Cluster: Payment +→ Processes: CheckoutFlow, RefundFlow +``` + +### gitnexus_cypher +Custom graph queries for tracing. + +**Find all callers of a function:** +``` +gitnexus_cypher({query: ` + MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "validatePayment"}) + RETURN caller.name, caller.filePath +`}) +``` + +**Find what a function calls:** +``` +gitnexus_cypher({query: ` + MATCH (f:Function {name: "validatePayment"})-[:CodeRelation {type: 'CALLS'}]->(callee) + RETURN callee.name, callee.filePath +`}) +``` + +**Trace call chain (2 hops):** +``` +gitnexus_cypher({query: ` + 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. **Search for payment error handling** + ``` + gitnexus_search({query: "payment error handling", depth: "full"}) + ``` + → validatePayment, handlePaymentError, PaymentException + +2. **Explore the suspect function** + ``` + gitnexus_explore({name: "validatePayment", type: "symbol"}) + ``` + → Callers: processCheckout, webhookHandler + → Callees: verifyCard, **fetchRates** (external API!) + +3. **Form hypothesis** + `fetchRates` calls external currency API → intermittent failures when API is slow + +4. **Verify** + Read `fetchRates` source to check timeout/error handling + +5. **Root cause** + `fetchRates` doesn't handle timeout properly → fix with retry logic + +## Debugging Patterns + +| Symptom | Approach | +|---------|----------| +| Error message | Search for error text, trace throw sites | +| Wrong return value | Trace data flow through callees | +| Intermittent failure | Look for external calls, timeouts | +| Performance issue | Find hot paths via callers count | +| Recent regression | Check recently modified files | + +## When to Use Something Else + +| Need | Use Instead | +|------|-------------| +| Explore unfamiliar code | `gitnexus-exploring` skill | +| Check change impact | `gitnexus-impact-analysis` skill | +| Plan refactoring | `gitnexus-refactoring` skill | diff --git a/gitnexus/skills/exploring.md b/gitnexus/skills/exploring.md new file mode 100644 index 000000000..8488c13ae --- /dev/null +++ b/gitnexus/skills/exploring.md @@ -0,0 +1,96 @@ +--- +name: gitnexus-exploring +description: Navigate unfamiliar code using GitNexus knowledge graph +--- + +# Exploring Codebases + +## Quick Start +1. `gitnexus_context` → Get codebase stats and hotspots +2. `gitnexus_overview` → See all clusters and processes +3. `gitnexus_explore(name, "cluster")` → Deep dive on a cluster + +## When to Use +- "How does authentication work?" +- "What's the project structure?" +- "Show me the main components" +- "Where is the database logic?" + +## Workflow +``` +Exploring Codebase: +- [ ] Call gitnexus_context to get codebase overview +- [ ] Call gitnexus_overview to list clusters +- [ ] Identify the relevant cluster by name +- [ ] Call gitnexus_explore(clusterName, "cluster") to see members +- [ ] Call gitnexus_explore(symbolName, "symbol") for specific functions +``` + +## Tool Reference + +### gitnexus_context +Get codebase overview. **Call first.** +``` +gitnexus_context() +→ Stats: 2,400 nodes, 12 clusters, 45 processes +→ Hotspots: most connected functions +``` + +### gitnexus_overview +List all clusters and processes. +``` +gitnexus_overview({showClusters: true, showProcesses: true}) +→ Clusters: Auth, Database, API, ... +→ Processes: LoginFlow, CheckoutFlow, ... +``` + +### gitnexus_explore +Deep dive on symbol, cluster, or process. +``` +gitnexus_explore({name: "Auth", type: "cluster"}) +→ Members: validateUser, checkToken, hashPassword +→ Processes using this cluster + +gitnexus_explore({name: "validateUser", type: "symbol"}) +→ Callers: loginHandler, apiMiddleware +→ Callees: checkToken, getUserById +→ Cluster: Auth + +gitnexus_explore({name: "LoginFlow", type: "process"}) +→ Steps: handleLogin → validateUser → createSession → respond +``` + +## Example: "How does payment processing work?" + +1. **Get overview** + ``` + gitnexus_context() + ``` + → 2,400 nodes, 12 clusters, 45 processes + +2. **Find payment cluster** + ``` + gitnexus_overview({showClusters: true}) + ``` + → Clusters: Auth, **Payment**, Database, API, ... + +3. **Explore payment cluster** + ``` + gitnexus_explore({name: "Payment", type: "cluster"}) + ``` + → Members: processPayment, validateCard, PaymentService, ... + → Processes: CheckoutFlow, RefundFlow + +4. **Trace the checkout flow** + ``` + gitnexus_explore({name: "CheckoutFlow", type: "process"}) + ``` + → handleCheckout → validateCart → processPayment → sendConfirmation + +## When to Use Something Else + +| Need | Use Instead | +|------|-------------| +| Debug failing code | `gitnexus-debugging` skill | +| Check change impact | `gitnexus-impact-analysis` skill | +| Plan refactoring | `gitnexus-refactoring` skill | diff --git a/gitnexus/skills/impact-analysis.md b/gitnexus/skills/impact-analysis.md new file mode 100644 index 000000000..cc3a85e8f --- /dev/null +++ b/gitnexus/skills/impact-analysis.md @@ -0,0 +1,129 @@ +--- +name: gitnexus-impact-analysis +description: Analyze blast radius before making code changes +--- + +# Impact Analysis + +## Quick Start +1. `gitnexus_impact(target, "upstream")` → What depends on this (will break) +2. Review affected processes and clusters +3. Assess risk level + +## 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?" + +## 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 | + +| Confidence | Meaning | +|------------|---------| +| 1.0 | Certain (static analysis) | +| 0.8+ | High confidence | +| <0.8 | Fuzzy match (may be false positive) | + +## Workflow +``` +Impact Analysis: +- [ ] gitnexus_impact(target, "upstream") to find dependents +- [ ] Review affected processes +- [ ] Check high-confidence (>0.8) dependencies first +- [ ] Count affected clusters (cross-cutting = higher risk) +- [ ] If >10 processes affected, consider splitting change +``` + +## Tool Reference + +### gitnexus_impact +Analyze blast radius. +``` +gitnexus_impact({ + target: "validateUser", + direction: "upstream", + minConfidence: 0.8, + maxDepth: 3, + includeTests: false +}) +``` + +**Parameters:** +- `target` — Function, class, or file name +- `direction` — "upstream" (what depends on this) or "downstream" (what this depends on) +- `minConfidence` — Filter out fuzzy matches (default: 0.7) +- `maxDepth` — How far to trace (default: 3) +- `includeTests` — Include test files (default: false) + +**Output:** +``` +Impact Analysis for "validateUser": + +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%] +- sessionManager (src/session/manager.ts:88) [CALLS, 90%] + +Affected Processes: LoginFlow, TokenRefresh, APIGateway +Affected Clusters: Auth, API + +Risk: MEDIUM (3 processes, 2 clusters) +``` + +## Example: "What breaks if I change validateUser?" + +1. **Run impact analysis** + ``` + gitnexus_impact({ + target: "validateUser", + direction: "upstream", + minConfidence: 0.8 + }) + ``` + +2. **Review output** + - d=1: loginHandler, apiMiddleware (WILL BREAK) + - d=2: authRouter, sessionManager (LIKELY AFFECTED) + - Processes: LoginFlow, TokenRefresh, APIGateway + - Risk: MEDIUM + +3. **Decision** + - 2 direct callers → manageable + - 3 processes → need to test all three + - Auth + API clusters → may need API team coordination + +## Risk Assessment Guide + +| Affected | Risk | +|----------|------| +| <5 symbols, 1 cluster | LOW | +| 5-15 symbols, 1-2 clusters | MEDIUM | +| >15 symbols or 3+ clusters | HIGH | +| Critical path (auth, payments) | CRITICAL | + +## Pre-Change Checklist +``` +Before Committing: +- [ ] Run impact analysis +- [ ] Review all d=1 (WILL BREAK) items +- [ ] Verify test coverage for affected processes +- [ ] If risk > MEDIUM, get code review +- [ ] If cross-cluster, coordinate with other teams +``` + +## When to Use Something Else + +| Need | Use Instead | +|------|-------------| +| Explore unfamiliar code | `gitnexus-exploring` skill | +| Debug failing code | `gitnexus-debugging` skill | +| Plan large refactors | `gitnexus-refactoring` skill | diff --git a/gitnexus/skills/refactoring.md b/gitnexus/skills/refactoring.md new file mode 100644 index 000000000..0bd0c84ea --- /dev/null +++ b/gitnexus/skills/refactoring.md @@ -0,0 +1,162 @@ +--- +name: gitnexus-refactoring +description: Plan safe refactors using blast radius and dependency mapping +--- + +# Refactoring with GitNexus + +## Quick Start +1. `gitnexus_impact(target, "upstream")` → Map all dependents +2. `gitnexus_cypher` → Find all references +3. Plan changes in dependency order + +## When to Use +- "Rename this function safely" +- "Extract this into a module" +- "Split this service" +- "Refactor without breaking things" + +## Checklists + +### Rename Symbol +``` +Rename Refactoring: +- [ ] gitnexus_impact(oldName, "upstream") — find all callers +- [ ] gitnexus_search(oldName) — find string literals +- [ ] Check for reflection/dynamic references +- [ ] Update in order: interface → implementation → usages +- [ ] Run tests for affected processes +``` + +### Extract Module +``` +Extract Module: +- [ ] gitnexus_explore(target, "symbol") — map dependencies +- [ ] gitnexus_impact(target, "upstream") — find callers +- [ ] Define new module interface +- [ ] Move code to new module +- [ ] Update imports across affected files +- [ ] Verify no circular dependencies +``` + +### Split Function +``` +Split Function: +- [ ] gitnexus_explore(target, "symbol") — understand callees +- [ ] Group related logic +- [ ] gitnexus_impact — verify callers won't break +- [ ] Create new functions +- [ ] Update callers to use correct function +``` + +## Tool Reference + +### Finding all references +``` +gitnexus_cypher({query: ` + MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "validateUser"}) + RETURN caller.name, caller.filePath + ORDER BY caller.filePath +`}) +``` + +### Finding symbols by name pattern +``` +gitnexus_cypher({query: ` + MATCH (s) + WHERE s.name CONTAINS "Payment" + RETURN s.name, labels(s)[0] AS type, s.filePath +`}) +``` + +### Finding all imports of a module +``` +gitnexus_cypher({query: ` + MATCH (importer)-[:CodeRelation {type: 'IMPORTS'}]->(f:File {name: "utils.ts"}) + RETURN importer.name, importer.filePath +`}) +``` + +### Finding community/cluster members +``` +gitnexus_cypher({query: ` + MATCH (s)-[:CodeRelation {type: 'MEMBER_OF'}]->(c:Community {label: "Auth"}) + RETURN s.name, labels(s)[0] AS type +`}) +``` + +## Example: Safely Rename `validateUser` to `authenticateUser` + +1. **Map all callers** + ``` + gitnexus_impact({ + target: "validateUser", + direction: "upstream", + minConfidence: 0.9 + }) + ``` + → loginHandler, apiMiddleware, testUtils + +2. **Check for string references** + ``` + gitnexus_search({query: "validateUser"}) + ``` + → Found in: config.json (dynamic reference!) + +3. **Get affected processes** + ``` + gitnexus_explore({name: "validateUser", type: "symbol"}) + ``` + → Processes: LoginFlow, TokenRefresh, APIGateway + +4. **Plan update order** + 1. Update declaration in auth.ts + 2. Update config.json string reference + 3. Update loginHandler + 4. Update apiMiddleware + 5. Update testUtils + 6. Run: LoginFlow, TokenRefresh, APIGateway tests + +## Example: Extract PaymentValidator Module + +1. **Understand current dependencies** + ``` + gitnexus_explore({name: "validatePayment", type: "symbol"}) + ``` + → Callees: verifyCard, checkAmount, fetchRates + → Callers: processCheckout, refundHandler + +2. **Map blast radius** + ``` + gitnexus_impact({target: "validatePayment", direction: "upstream"}) + ``` + → 2 direct callers, 3 processes + +3. **Create new module** + - Move validatePayment, verifyCard, checkAmount to PaymentValidator + - Keep fetchRates as external dependency (inject it) + +4. **Update callers** + - processCheckout: import { validatePayment } from './PaymentValidator' + - refundHandler: import { validatePayment } from './PaymentValidator' + +5. **Verify** + - Run tests for CheckoutFlow, RefundFlow processes + +## Refactoring Safety Rules + +| Risk Factor | Mitigation | +|-------------|------------| +| Many callers (>5) | Update in small batches | +| Cross-cluster | Coordinate with other teams | +| String references | Search for dynamic usage | +| Reflection | Check for dynamic invocation | +| External exports | May break downstream repos | + +## When to Use Something Else + +| Need | Use Instead | +|------|-------------| +| Explore unfamiliar code | `gitnexus-exploring` skill | +| Debug failing code | `gitnexus-debugging` skill | +| Quick impact check | `gitnexus-impact-analysis` skill | diff --git a/gitnexus/src/cli/ai-context.ts b/gitnexus/src/cli/ai-context.ts index 119877c09..8dcf1bd36 100644 --- a/gitnexus/src/cli/ai-context.ts +++ b/gitnexus/src/cli/ai-context.ts @@ -8,6 +8,11 @@ import fs from 'fs/promises'; import path from 'path'; +import { fileURLToPath } from 'url'; + +// ESM equivalent of __dirname +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); interface RepoStats { files?: number; @@ -156,6 +161,74 @@ async function upsertGitNexusSection( return 'appended'; } +/** + * Install GitNexus skills to .claude/skills/gitnexus/ + * Works natively with Claude Code, Cursor, and GitHub Copilot + */ +async function installSkills(repoPath: string): Promise { + const skillsDir = path.join(repoPath, '.claude', 'skills', 'gitnexus'); + const installedSkills: string[] = []; + + // Skill definitions bundled with the package + const skills = [ + { + name: 'exploring', + description: 'Navigate unfamiliar code using GitNexus knowledge graph', + }, + { + name: 'debugging', + description: 'Trace bugs through call chains using knowledge graph', + }, + { + name: 'impact-analysis', + description: 'Analyze blast radius before making code changes', + }, + { + name: 'refactoring', + description: 'Plan safe refactors using blast radius and dependency mapping', + }, + ]; + + for (const skill of skills) { + const skillDir = path.join(skillsDir, skill.name); + const skillPath = path.join(skillDir, 'SKILL.md'); + + try { + // Create skill directory + await fs.mkdir(skillDir, { recursive: true }); + + // Try to read from package skills directory + const packageSkillPath = path.join(__dirname, '..', '..', 'skills', `${skill.name}.md`); + let skillContent: string; + + try { + skillContent = await fs.readFile(packageSkillPath, 'utf-8'); + } catch { + // Fallback: generate minimal skill content + skillContent = `--- +name: gitnexus-${skill.name} +description: ${skill.description} +--- + +# ${skill.name.charAt(0).toUpperCase() + skill.name.slice(1)} + +${skill.description} + +Use GitNexus tools to accomplish this task. +`; + } + + await fs.writeFile(skillPath, skillContent, 'utf-8'); + installedSkills.push(skill.name); + } catch (err) { + // Skip on error, don't fail the whole process + console.warn(`Warning: Could not install skill ${skill.name}:`, err); + } + } + + return installedSkills; +} + /** * Generate AI context files after indexing */ @@ -178,5 +251,12 @@ export async function generateAIContextFiles( const claudeResult = await upsertGitNexusSection(claudePath, content); createdFiles.push(`CLAUDE.md (${claudeResult})`); + // Install skills to .claude/skills/gitnexus/ + const installedSkills = await installSkills(repoPath); + if (installedSkills.length > 0) { + createdFiles.push(`.claude/skills/gitnexus/ (${installedSkills.length} skills)`); + } + return { files: createdFiles }; } +