refactor(cli): trim duplicated ai-context CLAUDE.md block (#904)

This commit is contained in:
azizur100389 2026-04-18 07:10:44 +01:00 • committed by GitHub
parent bf35b1b040
commit 8555558f0f
2 changed files with 57 additions and 58 deletions

View file

@ -101,19 +101,6 @@ This project is indexed by GitNexus as **${projectName}**${noStats ? '' : ` (${s
- When exploring unfamiliar code, use \`gitnexus_query({query: "concept"})\` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance.
- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use \`gitnexus_context({name: "symbolName"})\`.
## When Debugging
1. \`gitnexus_query({query: "<error or symptom>"})\` — find execution flows related to the issue
2. \`gitnexus_context({name: "<suspect function>"})\` — see all callers, callees, and process participation
3. \`READ gitnexus://repo/${projectName}/process/{processName}\` — trace the full execution flow step by step
4. For regressions: \`gitnexus_detect_changes({scope: "compare", base_ref: "main"})\` — see what your branch changed
## When Refactoring
- **Renaming**: MUST use \`gitnexus_rename({symbol_name: "old", new_name: "new", dry_run: true})\` first. Review the preview — graph edits are safe, text_search edits need manual review. Then run with \`dry_run: false\`.
- **Extracting/Splitting**: MUST run \`gitnexus_context({name: "target"})\` to see all incoming/outgoing refs, then \`gitnexus_impact({target: "target", direction: "upstream"})\` to find all external callers before moving code.
- After any refactor: run \`gitnexus_detect_changes({scope: "all"})\` to verify only expected files changed.
## Never Do
- NEVER edit a function, class, or method without first running \`gitnexus_impact\` on it.
@ -121,25 +108,6 @@ This project is indexed by GitNexus as **${projectName}**${noStats ? '' : ` (${s
- NEVER rename symbols with find-and-replace — use \`gitnexus_rename\` which understands the call graph.
- NEVER commit changes without running \`gitnexus_detect_changes()\` to check affected scope.
## Tools Quick Reference
| Tool | When to use | Command |
|------|-------------|---------|
| \`query\` | Find code by concept | \`gitnexus_query({query: "auth validation"})\` |
| \`context\` | 360-degree view of one symbol | \`gitnexus_context({name: "validateUser"})\` |
| \`impact\` | Blast radius before editing | \`gitnexus_impact({target: "X", direction: "upstream"})\` |
| \`detect_changes\` | Pre-commit scope check | \`gitnexus_detect_changes({scope: "staged"})\` |
| \`rename\` | Safe multi-file rename | \`gitnexus_rename({symbol_name: "old", new_name: "new", dry_run: true})\` |
| \`cypher\` | Custom graph queries | \`gitnexus_cypher({query: "MATCH ..."})\` |
## Impact Risk Levels
| Depth | Meaning | Action |
|-------|---------|--------|
| d=1 | WILL BREAK — direct callers/importers | MUST update these |
| d=2 | LIKELY AFFECTED — indirect deps | Should test |
| d=3 | MAY NEED TESTING — transitive | Test if critical path |
## Resources
| Resource | Use for |
@ -149,32 +117,6 @@ This project is indexed by GitNexus as **${projectName}**${noStats ? '' : ` (${s
| \`gitnexus://repo/${projectName}/processes\` | All execution flows |
| \`gitnexus://repo/${projectName}/process/{name}\` | Step-by-step execution trace |
## Self-Check Before Finishing
Before completing any code modification task, verify:
1. \`gitnexus_impact\` was run for all modified symbols
2. No HIGH/CRITICAL risk warnings were ignored
3. \`gitnexus_detect_changes()\` confirms changes match expected scope
4. All d=1 (WILL BREAK) dependents were updated
## Keeping the Index Fresh
After committing code changes, the GitNexus index becomes stale. Re-run analyze to update it:
\`\`\`bash
npx gitnexus analyze
\`\`\`
If the index previously included embeddings, preserve them by adding \`--embeddings\`:
\`\`\`bash
npx gitnexus analyze --embeddings
\`\`\`
To check whether embeddings exist, inspect \`.gitnexus/meta.json\` — the \`stats.embeddings\` field shows the count (0 means no embeddings). **Running analyze without \`--embeddings\` will delete any previously generated embeddings.**
> Claude Code users: A PostToolUse hook handles this automatically after \`git commit\` and \`git merge\`.
${
groupNames && groupNames.length > 0
? `## Cross-Repo Groups

View file

@ -45,6 +45,63 @@ describe('generateAIContextFiles', () => {
expect(content).toContain('TestProject');
});
it('keeps the load-bearing repo-specific sections in the CLAUDE.md block (#856)', async () => {
// The trimmed block must still contain everything that is genuinely
// unique per repo or load-bearing for the agent: the freshness warning,
// the Always Do / Never Do imperative lists, the Resources URI table
// (projectName-interpolated), and the skills routing table that tells
// the agent which skill file to read for each task.
const stats = { nodes: 50, edges: 100, processes: 5 };
await generateAIContextFiles(tmpDir, storagePath, 'TestProject', stats);
const content = await fs.readFile(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
expect(content).toContain('If any GitNexus tool warns the index is stale');
expect(content).toContain('## Always Do');
expect(content).toContain('## Never Do');
expect(content).toContain('## Resources');
expect(content).toContain('gitnexus://repo/TestProject/context');
expect(content).toContain('gitnexus-impact-analysis/SKILL.md');
expect(content).toContain('gitnexus-refactoring/SKILL.md');
expect(content).toContain('gitnexus-debugging/SKILL.md');
expect(content).toContain('gitnexus-cli/SKILL.md');
});
it('does not duplicate content that already lives in skill files (#856)', async () => {
// The six sections listed in issue #856 are redundant with the skill
// files shipped alongside the CLAUDE.md block (both are loaded into
// every Claude Code session). Their absence is the whole point of the
// trim — assert each header is gone so a future regression that pads
// the block back out fails here.
const stats = { nodes: 50, edges: 100, processes: 5 };
await generateAIContextFiles(tmpDir, storagePath, 'TestProject', stats);
const content = await fs.readFile(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
expect(content).not.toContain('## Tools Quick Reference');
expect(content).not.toContain('## Impact Risk Levels');
expect(content).not.toContain('## Self-Check Before Finishing');
expect(content).not.toContain('## When Debugging');
expect(content).not.toContain('## When Refactoring');
expect(content).not.toContain('## Keeping the Index Fresh');
});
it('keeps the CLAUDE.md GitNexus block under the token-cost budget (#856)', async () => {
// The pre-trim block was ~5465 chars. After #856 it's ~2580 — about a
// 52% reduction. 2700 is a soft ceiling that still leaves headroom for
// legitimate future additions but will fail loudly if the trim is
// reverted or someone pads the block back out toward the original size.
const stats = { nodes: 50, edges: 100, processes: 5 };
await generateAIContextFiles(tmpDir, storagePath, 'TestProject', stats);
const content = await fs.readFile(path.join(tmpDir, 'CLAUDE.md'), 'utf-8');
const block = content.slice(
content.indexOf('<!-- gitnexus:start -->'),
content.indexOf('<!-- gitnexus:end -->'),
);
expect(block.length).toBeLessThan(2700);
});
it('handles empty stats', async () => {
const stats = {};
const result = await generateAIContextFiles(tmpDir, storagePath, 'EmptyProject', stats);