feat: surface always-loaded token cost during sync + configurable context budget warning
Problem
skillshare analyze already does an excellent job estimating per-target token cost (always-loaded vs on-demand), but the information is opt-in — users have to know the command exists and run it manually.
In practice, many users only discover their context bloat by accident. For example, my own personal skills directory is consuming ~50K+ tokens of always-loaded context across targets, and I had no idea until I ran analyze for an unrelated reason. Every Claude / Cursor / OpenCode chat I start pays that 50K toll on the very first message, eating into the model's working context before I've typed anything.
The data is already computed. It just isn't surfaced where users naturally look (after skillshare sync).
Proposal
Three small, additive changes that build on the existing analyze machinery:
1. Print a one-line token summary at the end of skillshare sync
Today sync ends with:
✔ Synced 47 skill(s) to 4 target(s) in 312ms
Add a follow-up line per target (or aggregated when identical), reusing buildAnalyzeEntries output:
✔ Synced 47 skill(s) to 4 target(s) in 312ms
Context cost: ~12.4K always-loaded · ~58K on-demand (claude, cursor, codex, opencode)
Zero new computation — analyze already produces these numbers.
2. Configurable budget warning thresholds
Add to ~/.config/skillshare/config.yaml:
context_budget:
warn_always_loaded_tokens: 10000 # default; 0 disables
warn_on_demand_tokens: 100000 # default; 0 disables
When sync (or analyze) crosses a threshold:
⚠ Always-loaded context is ~50,123 tokens (budget: 10,000).
Top offenders:
• my-big-skill ~8,200 tokens
• another-verbose-skill ~6,400 tokens
• ...
Run `skillshare analyze` to optimize, or tighten descriptions.
This is the "remind me to optimize" hook — high-signal, low-noise, only fires when there's something to act on.
3. (Optional) Per-target context-window aware percentages
Different targets have very different context budgets (Claude 200K, Gemini 1.5 1M, small local models 32K). Could be expressed as either:
- A built-in default map of
target → context_window with override in config, or
- Just a config field per target:
context_window_tokens: 200000
Then the warning becomes meaningfully relative:
⚠ claude: always-loaded uses 25% of 200K context window
⚠ small-model: always-loaded uses 156% of 32K context window ← red flag
This is the most opinionated piece, so it's fine to defer to a follow-up issue.
Why this matters
- Discoverability — users learn about token cost the moment they take an action that affects it (
sync), not after they happen to read the docs.
- Right place, right time — the warning fires when adding/updating a skill, which is exactly when an alternative ("trim this description before syncing") is cheap.
- Composable with existing skills like
gstack-health — these dashboards can reuse the new fields/exit codes without re-implementing token math.
Scope
- Backend: extend
runSync to call buildAnalyzeEntries (or a lightweight subset that only computes totals) and print one summary line.
- Config: new optional
context_budget block, fully back-compat (zero/missing = no warning).
- CLI:
--no-token-summary flag for users who want the old terse output.
- Docs: short blurb in
sync.md and a cross-link from analyze.md.
I'm happy to take a stab at the PR. Wanted to file the issue first to confirm the direction (especially: defaults for the warn thresholds, and whether (3) should ship in this change or as a follow-up).
References
- Existing analyze logic:
cmd/skillshare/analyze.go (buildAnalyzeEntries, estimateTokens)
- Sync exit point:
cmd/skillshare/sync.go (runSync, printIgnoredSkills)
- Docs:
website/docs/reference/commands/analyze.md
feat: surface always-loaded token cost during
sync+ configurable context budget warningProblem
skillshare analyzealready does an excellent job estimating per-target token cost (always-loaded vs on-demand), but the information is opt-in — users have to know the command exists and run it manually.In practice, many users only discover their context bloat by accident. For example, my own personal skills directory is consuming ~50K+ tokens of always-loaded context across targets, and I had no idea until I ran
analyzefor an unrelated reason. Every Claude / Cursor / OpenCode chat I start pays that 50K toll on the very first message, eating into the model's working context before I've typed anything.The data is already computed. It just isn't surfaced where users naturally look (after
skillshare sync).Proposal
Three small, additive changes that build on the existing
analyzemachinery:1. Print a one-line token summary at the end of
skillshare syncToday
syncends with:Add a follow-up line per target (or aggregated when identical), reusing
buildAnalyzeEntriesoutput:Zero new computation —
analyzealready produces these numbers.2. Configurable budget warning thresholds
Add to
~/.config/skillshare/config.yaml:When
sync(oranalyze) crosses a threshold:This is the "remind me to optimize" hook — high-signal, low-noise, only fires when there's something to act on.
3. (Optional) Per-target context-window aware percentages
Different targets have very different context budgets (Claude 200K, Gemini 1.5 1M, small local models 32K). Could be expressed as either:
target → context_windowwith override in config, orcontext_window_tokens: 200000Then the warning becomes meaningfully relative:
This is the most opinionated piece, so it's fine to defer to a follow-up issue.
Why this matters
sync), not after they happen to read the docs.gstack-health— these dashboards can reuse the new fields/exit codes without re-implementing token math.Scope
runSyncto callbuildAnalyzeEntries(or a lightweight subset that only computes totals) and print one summary line.context_budgetblock, fully back-compat (zero/missing = no warning).--no-token-summaryflag for users who want the old terse output.sync.mdand a cross-link fromanalyze.md.I'm happy to take a stab at the PR. Wanted to file the issue first to confirm the direction (especially: defaults for the warn thresholds, and whether (3) should ship in this change or as a follow-up).
References
cmd/skillshare/analyze.go(buildAnalyzeEntries,estimateTokens)cmd/skillshare/sync.go(runSync,printIgnoredSkills)website/docs/reference/commands/analyze.md