fix: route context checks to native meters

This commit is contained in:
haelyra
2026-08-09 17:32:15 -04:00
parent 649def769b
commit 6ab6cfd9b4
3 changed files with 125 additions and 113 deletions
@@ -18,6 +18,6 @@ $ARGUMENTS
## Delegation
Apply the `context-budget` skill.
- Pass through `--verbose` if the user supplied it.
- Assume a 200K context window unless the user specified otherwise.
- Return the skill's inventory, issue detection, and prioritized savings report without re-implementing the scan here.
- Without an explicit `--audit`, return the harness's native live-context command and do not scan files or call tools.
- Pass through `--audit` and `--verbose` only when the user supplied them.
- Keep any explicit audit bounded to the scope and safety rules in the canonical skill.
+52 -110
View File
@@ -1,136 +1,78 @@
---
name: context-budget
description: Audits Claude Code context window consumption across agents, skills, MCP servers, and rules. Identifies bloat, redundant components, and produces prioritized token-savings recommendations.
description: Routes live context checks to the native Codex or Claude Code meter without scanning files, and performs a bounded static component audit only when explicitly requested.
metadata:
origin: ECC
---
# Context Budget
Analyze token overhead across every loaded component in a Claude Code session and surface actionable optimizations to reclaim context space.
Use the provider's native meter for live session usage. Keep the separate,
estimated installation audit behind an explicit opt-in.
## When to Use
## Default: Live Context
- Session performance feels sluggish or output quality is degrading
- You've recently added many skills, agents, or MCP servers
- You want to know how much context headroom you actually have
- Planning to add more components and need to know if there's room
- Running `/context-budget` command (this skill backs it)
Treat an invocation with no audit request as a live-context request. This
includes requests for the current window, remaining capacity, headroom, token
usage, or a context breakdown.
## How It Works
For this default path:
### Phase 1: Inventory
- Do not call or use tools.
- Do not scan or read files.
- Do not run shell commands, provider CLIs, debug logging, or MCP discovery.
- Reply with only the native command and one short explanation.
Scan all component directories and estimate token consumption:
Route by the active harness:
**Agents** (`agents/*.md`)
- Count lines and tokens per file (words × 1.3)
- Extract `description` frontmatter length
- Flag: files >200 lines (heavy), description >30 words (bloated frontmatter)
| Harness | Native command | Guidance |
| --- | --- | --- |
| Codex CLI | `/status` | Shows current token usage and remaining context capacity. Use `/statusline` and enable **Context stats** plus **Token counters** for a persistent footer meter. |
| Claude Code | `/context` | Shows the live context breakdown. Use `/context all` for expanded items. |
| Other or unknown | None verified | State that ECC cannot read live provider state and ask which harness is active. |
**Skills** (`skills/*/SKILL.md`)
- Count tokens per SKILL.md
- Flag: files >400 lines
- Check for duplicate copies in `.agents/skills/` — skip identical copies to avoid double-counting
A skill cannot invoke a TUI slash command on the user's behalf. Never replace
the native command with an estimated scan and never infer an audit request from
phrases such as “context is heavy” or “how much is left.”
**Rules** (`rules/**/*.md`)
- Count tokens per file
- Flag: files >100 lines
- Detect content overlap between rule files in the same language module
## Explicit Static Audit
**MCP Servers** (`.mcp.json` or active MCP config)
- Count configured servers and total tool count
- Estimate schema overhead at ~500 tokens per tool
- Flag: servers with >20 tools, servers that wrap simple CLI commands (`gh`, `git`, `npm`, `supabase`, `vercel`)
Run an installation/configuration audit only when the user explicitly says
`--audit`, “audit installed components,” or equivalent unambiguous wording.
`--verbose` changes report detail; it does not opt into an audit by itself.
**CLAUDE.md** (project + user-level)
- Count tokens per file in the CLAUDE.md chain
- Flag: combined total >300 lines
If the audit scope is ambiguous, ask for the harness and installation root
before reading anything. Keep every audit bounded and read-only:
### Phase 2: Classify
1. Inspect only the named plugin/install root and the named harness's known
configuration files.
2. Never recursively enumerate the workspace root, home directory, provider
cache, transcripts, debug logs, or unrelated worktrees.
3. Never launch a provider CLI, MCP server, or debug session to count tools.
4. Cap inventory output at 50 entries per component class. Summarize the rest.
5. Do not write temporary logs or copy configuration content into the report.
Sort every component into a bucket:
Audit only the component metadata relevant to eager discovery:
| Bucket | Criteria | Action |
|--------|----------|--------|
| **Always needed** | Referenced in CLAUDE.md, backs an active command, or matches current project type | Keep |
| **Sometimes needed** | Domain-specific (e.g. language patterns), not referenced in CLAUDE.md | Consider on-demand activation |
| **Rarely needed** | No command reference, overlapping content, or no obvious project match | Remove or lazy-load |
- agent and skill descriptions;
- command descriptions when the harness discovers them eagerly;
- always-loaded instruction files in the explicitly named scope;
- configured MCP tool schemas when an existing bounded manifest exposes them.
### Phase 3: Detect Issues
Full skill, agent, command, and rule bodies are generally on-demand content.
Report their disk size separately from estimated eager overhead instead of
adding every body to the session baseline.
Identify the following problem patterns:
## Audit Output
- **Bloated agent descriptions** — description >30 words in frontmatter loads into every Task tool invocation
- **Heavy agents** — files >200 lines inflate Task tool context on every spawn
- **Redundant components** — skills that duplicate agent logic, rules that duplicate CLAUDE.md
- **MCP over-subscription** — >10 servers, or servers wrapping CLI tools available for free
- **CLAUDE.md bloat** — verbose explanations, outdated sections, instructions that should be rules
Return a compact report containing:
### Phase 4: Report
- harness and exact paths inspected;
- estimated eager/discovery overhead by component class;
- installed counts and the heaviest metadata entries;
- assumptions, unavailable measurements, and up to three optimizations.
Produce the context budget report:
```
Context Budget Report
═══════════════════════════════════════
Total estimated overhead: ~XX,XXX tokens
Context model: Claude Sonnet (200K window)
Effective available context: ~XXX,XXX tokens (XX%)
Component Breakdown:
┌─────────────────┬────────┬───────────┐
│ Component │ Count │ Tokens │
├─────────────────┼────────┼───────────┤
│ Agents │ N │ ~X,XXX │
│ Skills │ N │ ~X,XXX │
│ Rules │ N │ ~X,XXX │
│ MCP tools │ N │ ~XX,XXX │
│ CLAUDE.md │ N │ ~X,XXX │
└─────────────────┴────────┴───────────┘
WARNING: Issues Found (N):
[ranked by token savings]
Top 3 Optimizations:
1. [action] → save ~X,XXX tokens
2. [action] → save ~X,XXX tokens
3. [action] → save ~X,XXX tokens
Potential savings: ~XX,XXX tokens (XX% of current overhead)
```
In verbose mode, additionally output per-file token counts, line-by-line breakdown of the heaviest files, specific redundant lines between overlapping components, and MCP tool list with per-tool schema size estimates.
## Examples
**Basic audit**
```
User: /context-budget
Skill: Scans setup → 16 agents (12,400 tokens), 28 skills (6,200), 87 MCP tools (43,500), 2 CLAUDE.md (1,200)
Flags: 3 heavy agents, 14 MCP servers (3 CLI-replaceable)
Top saving: remove 3 MCP servers → -27,500 tokens (47% overhead reduction)
```
**Verbose mode**
```
User: /context-budget --verbose
Skill: Full report + per-file breakdown showing planner.md (213 lines, 1,840 tokens),
MCP tool list with per-tool sizes, duplicated rule lines side by side
```
**Pre-expansion check**
```
User: I want to add 5 more MCP servers, do I have room?
Skill: Current overhead 33% → adding 5 servers (~50 tools) would add ~25,000 tokens → pushes to 45% overhead
Recommendation: remove 2 CLI-replaceable servers first to stay under 40%
```
## Best Practices
- **Token estimation**: use `words × 1.3` for prose, `chars / 4` for code-heavy files
- **MCP is the biggest lever**: each tool schema costs ~500 tokens; a 30-tool server costs more than all your skills combined
- **Agent descriptions are loaded always**: even if the agent is never invoked, its description field is present in every Task tool context
- **Verbose mode for debugging**: use when you need to pinpoint the exact files driving overhead, not for regular audits
- **Audit after changes**: run after adding any agent, skill, or MCP server to catch creep early
Every calculated token number is an estimate of static configuration overhead,
not live session context. Do not claim that an estimate is provider-reported,
current, exact, or evidence of realized savings. Direct the user back to the
native live-context command for current usage.
+70
View File
@@ -0,0 +1,70 @@
'use strict';
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const repoRoot = path.resolve(__dirname, '..', '..');
const skillPath = path.join(repoRoot, 'skills', 'context-budget', 'SKILL.md');
const legacyShimPath = path.join(repoRoot, 'legacy-command-shims', 'commands', 'context-budget.md');
const skill = fs.readFileSync(skillPath, 'utf8');
const legacyShim = fs.readFileSync(legacyShimPath, 'utf8');
let passed = 0;
let failed = 0;
function test(name, fn) {
try {
fn();
console.log(` ✓ ${name}`);
passed += 1;
} catch (error) {
console.log(` ✗ ${name}`);
console.log(` Error: ${error.message}`);
failed += 1;
}
}
console.log('\n=== Context budget skill tests ===\n');
test('describes a cross-harness live-context router instead of a Claude-only audit', () => {
const frontmatter = skill.match(/^---\n([\s\S]*?)\n---/);
assert.ok(frontmatter, 'SKILL.md frontmatter is missing');
assert.match(frontmatter[1], /description:.*live context/i);
assert.match(frontmatter[1], /Codex/i);
assert.doesNotMatch(frontmatter[1], /Audits Claude Code/i);
});
test('routes Codex live context requests to native status surfaces without tools', () => {
assert.match(skill, /Codex[\s\S]*`\/status`/i);
assert.match(skill, /Codex[\s\S]*`\/statusline`/i);
assert.match(skill, /do not (?:call|use).*tools/i);
assert.match(skill, /do not (?:scan|read).*files/i);
});
test('routes Claude Code live context requests to its native context command', () => {
assert.match(skill, /Claude Code[\s\S]*`\/context`/i);
});
test('requires explicit audit intent before inventorying installed components', () => {
assert.match(skill, /only.*(?:`--audit`|explicit).*audit/is);
assert.match(skill, /never infer.*audit/is);
assert.match(skill, /bounded/i);
});
test('keeps estimated static overhead distinct from live provider usage', () => {
assert.match(skill, /estimate/i);
assert.match(skill, /not.*live (?:session|context)/i);
assert.match(skill, /do not claim/i);
});
test('keeps the legacy slash shim on the same safe default', () => {
assert.match(legacyShim, /native live-context command/i);
assert.match(legacyShim, /explicit.*`--audit`/i);
assert.doesNotMatch(legacyShim, /Assume a 200K context window/i);
});
console.log(`\nPassed: ${passed}`);
console.log(`Failed: ${failed}`);
process.exit(failed > 0 ? 1 : 0);