mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-08-10 17:14:48 +00:00
Merge pull request #911 from ozymandiashh/fix/swarm-context-budget
fix(context-budget): stop double-counting home skills and CLAUDE.md
This commit is contained in:
commit
9372fb56b7
2 changed files with 58 additions and 2 deletions
|
|
@ -60,8 +60,13 @@ async function countMcpTools(projectPath?: string): Promise<number> {
|
|||
}
|
||||
|
||||
async function countSkills(projectPath?: string): Promise<number> {
|
||||
const dirs = [join(homedir(), '.claude', 'skills')]
|
||||
if (projectPath) dirs.push(join(projectPath, '.claude', 'skills'))
|
||||
// Dedupe by resolved path: when the project IS the home dir, the home and
|
||||
// project skills dirs are the same directory, and counting both double-counts
|
||||
// every skill (and inflates the context budget).
|
||||
const dirs = [...new Set([
|
||||
join(homedir(), '.claude', 'skills'),
|
||||
...(projectPath ? [join(projectPath, '.claude', 'skills')] : []),
|
||||
])]
|
||||
|
||||
let count = 0
|
||||
for (const dir of dirs) {
|
||||
|
|
@ -91,7 +96,12 @@ async function scanMemoryFiles(projectPath?: string): Promise<Array<{ name: stri
|
|||
paths.push({ path: join(projectPath, 'CLAUDE.local.md'), name: 'CLAUDE.local.md' })
|
||||
}
|
||||
|
||||
// Dedupe by path so a project that IS the home dir does not read (and count)
|
||||
// ~/.claude/CLAUDE.md twice.
|
||||
const seenPaths = new Set<string>()
|
||||
for (const { path, name } of paths) {
|
||||
if (seenPaths.has(path)) continue
|
||||
seenPaths.add(path)
|
||||
if (!existsSync(path)) continue
|
||||
const content = await readSessionFile(path)
|
||||
if (content === null) continue
|
||||
|
|
|
|||
46
tests/context-budget-home.test.ts
Normal file
46
tests/context-budget-home.test.ts
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import { describe, it, expect, beforeEach } from 'vitest'
|
||||
import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'fs'
|
||||
import { join } from 'path'
|
||||
|
||||
// Mock homedir to a temp dir so "project == home" is reproducible.
|
||||
import { vi } from 'vitest'
|
||||
vi.mock('os', async () => {
|
||||
const actual = await vi.importActual<typeof import('os')>('os')
|
||||
const fs = await vi.importActual<typeof import('fs')>('fs')
|
||||
const fakeHome = fs.mkdtempSync(actual.tmpdir() + '/cb-ctxbudget-home-')
|
||||
process.env['CB_CTXBUDGET_FAKE_HOME'] = fakeHome
|
||||
return { ...actual, homedir: () => fakeHome }
|
||||
})
|
||||
|
||||
const HOME = process.env['CB_CTXBUDGET_FAKE_HOME']!
|
||||
|
||||
import { estimateContextBudget } from '../src/context-budget.js'
|
||||
|
||||
describe('context budget: no double-count when the project IS the home dir', () => {
|
||||
beforeEach(() => {
|
||||
rmSync(join(HOME, '.claude'), { recursive: true, force: true })
|
||||
mkdirSync(join(HOME, '.claude', 'skills', 'my-skill'), { recursive: true })
|
||||
writeFileSync(join(HOME, '.claude', 'skills', 'my-skill', 'SKILL.md'), '# Skill')
|
||||
writeFileSync(join(HOME, '.claude', 'CLAUDE.md'), 'home memory')
|
||||
})
|
||||
|
||||
it('counts the one home skill once, not twice, when projectPath is home', async () => {
|
||||
// With projectPath === home, the home and project skills dirs resolve to
|
||||
// the same directory; the unfixed code pushed both and counted every skill
|
||||
// twice (and read ~/.claude/CLAUDE.md twice).
|
||||
const budget = await estimateContextBudget(HOME)
|
||||
expect(budget.skills.count).toBe(1)
|
||||
// ~/.claude/CLAUDE.md must appear once in the memory file list.
|
||||
const homeMemory = budget.memory.files.filter(f => f.name.includes('.claude/CLAUDE.md'))
|
||||
expect(homeMemory).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('still counts a distinct project skill separately from a home skill', async () => {
|
||||
const proj = mkdtempSync(join(HOME, '..', 'cb-ctxbudget-proj-'))
|
||||
mkdirSync(join(proj, '.claude', 'skills', 'proj-skill'), { recursive: true })
|
||||
writeFileSync(join(proj, '.claude', 'skills', 'proj-skill', 'SKILL.md'), '# Proj')
|
||||
const budget = await estimateContextBudget(proj)
|
||||
expect(budget.skills.count).toBe(2) // home skill + project skill
|
||||
rmSync(proj, { recursive: true, force: true })
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue