config-audit/commands/manifest.md
Kjell Tore Guttormsen bb647ce35f feat(mft): v5.6 B1 — load-pattern accounting in manifest
Consume the v5.6 Foundation enumeration in buildManifest:

- Component-level sources: drop the coarse `kind:'plugin'` roll-up (it
  double-counted skills/rules/agents already enumerated once). Kinds are now
  claude-md/skill/rule/agent/output-style/mcp-server/hook.
- Every source carries loadPattern/survivesCompaction/derivationConfidence.
  Rules/agents/output-styles propagate the foundation-derived values; CLAUDE.md
  maps scope→kind (all cascade files always-loaded); skills are tagged on-demand
  (skill-body) so the body cost does not inflate the always-loaded subtotal.
- New `summary` (always/onDemand/external/unknown {tokens,count}); the
  always-loaded subtotal — "tokens that enter context every turn" — is the headline.

manifest is an environment-aware CLI → SC-6/SC-7 verify it by mode-equivalence,
not byte-equal, and it is not in SC-5. Adding fields in place keeps all snapshots
green with no regen (verified). `total` changes (de-duped) — intended correctness fix.
TOK's load-pattern column (byte-equal SC-6) is deferred to the next chunk (B2).

Tests 996→1008 (deterministic buildManifest unit test + CLI presence checks).
Self-audit A/A, scanner count unchanged at 13.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 17:48:55 +02:00

96 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: config-audit:manifest
description: Show ranked token-source manifest — every CLAUDE.md, rule, agent, skill, output style, MCP server, and hook ordered DESC by estimated tokens, each tagged with its load pattern (always-loaded vs on-demand vs external), plus an always-loaded subtotal
argument-hint: "[path] [--json]"
allowed-tools: Read, Bash
model: sonnet
---
# Config-Audit: Manifest
Produce a ranked, single-table view of every token source loaded for a given repo path. Where `whats-active` shows separate tables per category, `manifest` collapses everything into one ordered list — making it easy to see what's costing the most regardless of category.
Every source is tagged with its **load pattern**, derived from the published Claude Code loading model:
- **always** — enters context every turn before you type (project/user CLAUDE.md, unscoped rules, agents, output styles, MCP tool schemas). This is the cost that matters most: it is paid on *every* request.
- **on-demand** — loaded only when needed (skill bodies on invoke, path-scoped rules on a matching file read).
- **external** — runs outside the context window entirely (hooks).
The **always-loaded subtotal** is the headline number. Sources are component-level (a plugin contributes via its skills/rules/agents/output styles/hooks/MCP, each listed once — there is no coarse "plugin" roll-up, which would double-count).
## UX Rules (MANDATORY — from `.claude/rules/ux-rules.md`)
1. **Never show raw JSON or stderr output.** Always use `--output-file` + `2>/dev/null`.
2. **Narrate before acting.** Tell the user what you're about to do.
3. **Read, don't dump.** Read the JSON file and render a formatted table.
4. **End with context-sensitive next steps.**
## Implementation
### Step 1: Parse `$ARGUMENTS`
First non-flag argument is the path (default `.`). Recognized flags:
- `--json` — emit raw JSON instead of the rendered table.
- `--raw` — pass-through to the scanner; accepted for CLI surface consistency with the other config-audit commands. The manifest CLI is data-table only (no findings prose), so `--raw` is a no-op here, but the flag is still threaded through so users get uniform behaviour across `--raw`.
### Step 2: Run the CLI silently
Tell the user: **"Building token-source manifest for `<path>`..."**
```bash
TMPFILE="/tmp/ca-manifest-$$.json"
RAW_FLAG=""
if echo "$ARGUMENTS" | grep -q -- "--raw"; then RAW_FLAG="--raw"; fi
node ${CLAUDE_PLUGIN_ROOT}/scanners/manifest.mjs <path> --output-file "$TMPFILE" $RAW_FLAG 2>/dev/null; echo $?
```
**Exit code handling:**
- `0` → continue
- `3` → tell user: "Couldn't read configuration. Check that the path exists and is a directory." Stop.
### Step 3: If `--json` was requested, cat the file and stop
```bash
cat "$TMPFILE"
```
Do NOT render the table in JSON mode.
### Step 4: Read JSON and render
Use the Read tool on `$TMPFILE`. Extract `meta.repoPath`, `total`, `summary`, and `sources[]`. Lead with the **always-loaded subtotal** (the headline), then render the top 20 sources (or fewer if the manifest is shorter):
```markdown
**Token-source manifest for `<repoPath>`** — ~{total} tokens total
- 🔴 **~{summary.always.tokens} tokens enter context every turn** before you type ({summary.always.count} always-loaded sources)
- 🟡 ~{summary.onDemand.tokens} tokens on-demand ({summary.onDemand.count} sources — loaded only when invoked / matched)
- ⚪ ~{summary.external.tokens} tokens external ({summary.external.count} sources — hooks, run outside context)
| Rank | Kind | Name | Source | Tokens | Load |
|------|------|------|--------|--------|------|
| 1 | {kind} | `<name>` | {source} | ~{estimated_tokens} | {load} |
| ... | ... | ... | ... | ... | ... |
_Load column: **always** / **on-demand** / **external**. Append `°` when `derivationConfidence` is `inferred` (no primary-doc row pins it exactly)._
_Estimates assume ~4 chars/token (Claude ballpark). Real token count varies ±15%._
```
If `sources.length > 20`, follow the table with: _"Showing top 20 of {N} sources. Run with `--json` to see the full list."_
When narrating, prioritize the always-loaded subtotal: a large **always** source is worse than an equally large **on-demand** one, because it is paid on every request. Call out any single always-loaded source that dwarfs the rest.
### Step 5: Suggest next steps
```markdown
**Next steps:**
- `/config-audit tokens` — prompt-cache token-hotspot patterns (cache-breaking, redundant perms, deep imports, MCP budget)
- `/config-audit whats-active` — same data grouped by category, with disable suggestions
- `/config-audit feature-gap` — what *could* improve here, grouped by impact
```
Tone (key on the **always-loaded subtotal** — the every-turn cost — not the grand total):
- High always-loaded (>40k): empathetic — "That's a heavy per-turn cost; it taxes every request before you've typed a word. Look at the largest always-loaded sources first."
- Moderate (1040k): neutral — "Reasonable. Skim the top always-loaded sources to see if anything is unexpectedly large."
- Low (<10k): encouraging — "Tight setup. The model has plenty of room for the actual work each turn."