/skill-inbox
Unified entry point for managing skill suggestions and browsing all installed skills. Provides two views: suggestions (default) and all skills.
$ npx -y skills add Evol-ai/SkillCompass --agent claude-codeHow it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/skill-inbox
Context preview
What this command does when you run it.
Unified entry point for managing skill suggestions and browsing all installed skills. Provides two views: suggestions (default) and all skills.
Command definition
skill-inbox.md/skill-inbox — Skill Suggestion Inbox
Unified entry point for managing skill suggestions and browsing all installed skills. Provides two views: suggestions (default) and all skills.
Arguments
- (no args): Show suggestions view (default)
- `all`: Show all installed skills view
Step 1: Load Data
1. Use the **Read** tool to load `.skill-compass/setup-state.json`. If the file does not exist, this is a first-time use. Auto-initialize:
1. Run skill discovery silently (same as setup Step 3: scan immediate children of skill directories for `*/SKILL.md` — do NOT recurse). 2. Run quick scan D1+D2+D3 on all discovered skills. 3. Save `setup-state.json`. 4. Show a brief summary:
Found {N} skill(s){, M with security risks if any high risk}.
Usage data accumulates automatically; you'll be notified when suggestions appear.Then check for statusLine configuration (see `setup.md` StatusLine integration section). If no statusLine is configured, offer the choice.
After initialization, continue to Step 2 (show header) and proceed normally. The inbox will be empty (no suggestions yet since no usage data), but the all-skills view will be populated.
2. Extract the `inventory` array from setup-state.json. This is the full skill list.
3. Load inbox data using `lib/inbox-store.js`. Execute with the **Bash** tool:
node -e "
const { InboxStore } = require('./lib/inbox-store');
const baseDir = process.env.CLAUDE_PLUGIN_ROOT || process.cwd();
const store = new InboxStore('cc', baseDir);
store.reactivateSnoozed();
const allCache = store.getAllSkillCache();
const cacheMap = {};
allCache.forEach(c => { cacheMap[c.skill_name] = c; });
console.log(JSON.stringify({
pending: store.getPending(),
skillCache: cacheMap
}, null, 2));
"Parse the output as `inboxData`. `skillCache` is a map keyed by skill name. If the script fails, treat `pending` as `[]` and `skillCache` as `{}`.
4. Check if a weekly digest is due and run it if so. Execute with the **Bash** tool:
node -e "
const { InboxEngine } = require('./lib/inbox-engine');
const fs = require('fs');
const path = require('path');
const baseDir = process.env.CLAUDE_PLUGIN_ROOT || process.cwd();
const setupPaths = [
path.join(baseDir, '.skill-compass', 'cc', 'setup-state.json'),
path.join(baseDir, '.skill-compass', 'setup-state.json')
];
let state = { inventory: [] };
for (const sp of setupPaths) {
if (fs.existsSync(sp)) { state = JSON.parse(fs.readFileSync(sp, 'utf8')); break; }
}
const skillEntries = state.inventory || [];
const engine = new InboxEngine('cc', baseDir);
if (engine.isDigestDue(7)) {
const result = engine.runDigest(skillEntries);
console.log(JSON.stringify({ ran: true, added: result.added }));
} else {
console.log(JSON.stringify({ ran: false, added: 0 }));
}
"If `ran` is true and `added > 0`, note that `added` new suggestions were generated. Re-load `inboxData.pending` by re-running Step 1.3.
Step 2: Show Header
Compute:
- `pendingCount`: `inboxData.pending.length`
- `totalSkills`: `inventory.length`
Always display:
Skill Inbox — Suggestions ({pendingCount}) | All skills ({totalSkills})Step 3: Route to View
- If argument is `all` → go to Step 5 (All Skills View).
- Otherwise → go to Step 4 (Suggestions View).
Step 4: Suggestions View (Default)
Get pending suggestions from `inboxData.pending` (already sorted by priority).
If suggestions exist
Show up to 3 suggestions at a time. Present each conversationally — explain what was detected and why it matters. Do NOT show rule_id, priority, category, or evidence directly. These are internal metadata; the reason text already summarizes the situation.
Example output:
Skill Inbox — Suggestions (3) | All skills (12)
1. old-formatter — installed 30 days ago, never invoked
Uses 7.1KB of context without producing value; cleaning it up frees space.
2. k8s-deploy — used 8 times in the prior two weeks, suddenly stopped in the last 7 days
May indicate the user found an alternative or hit a problem.
3. translate — used only once (March 15), never again
May have been a one-off need.
For state-changing actions, present keyboard-selectable choices per suggestion. The user can also respond with natural language for non-state-changing queries (e.g. "show all skills", "which haven't been used"), but state changes (pin/delete/mute/snooze) should go through explicit choice confirmation.
After the list, prompt:
Choose a suggestion to see action options, or tell me how you'd like to handle it.
When user selects a suggestion (by number or by name), show the action choices as keyboard-selectable options:
old-formatter — installed 30 days ago, never invoked
[Pin (stop suggesting cleanup)]
[Evaluate quality]
[Delete]
[Remind later (in 14 days)]
[View details]
"View details" expands to show rule_id, evidence, cooldown info — only when user explicitly asks.
If no suggestions
Output:
All suggestions processed ✓ Skill usage data is accumulating.
[View all skills / View skill report / Done]
Stop.
Handle Actions
Wait for the user's input in the form `{n} {action}`. Parse the suggestion number and action keyword per the table below.
For each action, execute the corresponding store methods via the **Bash** tool, then print the confirmation message.
| Action keyword | What to execute | Confirmation output | |----------------|-----------------|---------------------| | pin | `store.pinSkill(skillName)`, `store.accept(sugId)`, `store.resolve(sugId)` | `✓ Pinned {name}; Hygiene rules will no longer suggest cleanup.` | | eval | `store.accept(sugId)` | `✓ Added to eval queue. Run /eval-skill {name}.` | | improve | `store.accept(sugId)` | `✓ Added to improve queue. Run /eval-improve {name}.` | | delete |
Read more
/skill-inbox — Skill Suggestion Inbox
Unified entry point for managing skill suggestions and browsing all installed skills. Provides two views: suggestions (default) and all skills.
Arguments
- (no args): Show suggestions view (default)
- `all`: Show all installed skills view
Step 1: Load Data
1. Use the **Read** tool to load `.skill-compass/setup-state.json`. If the file does not exist, this is a first-time use. Auto-initialize:
1. Run skill discovery silently (same as setup Step 3: scan immediate children of skill directories for `*/SKILL.md` — do NOT recurse). 2. Run quick scan D1+D2+D3 on all discovered skills. 3. Save `setup-state.json`. 4. Show a brief summary:
Found {N} skill(s){, M with security risks if any high risk}.
Usage data accumulates automatically; you'll be notified when suggestions appear.Then check for statusLine configuration (see `setup.md` StatusLine integration section). If no statusLine is configured, offer the choice.
After initialization, continue to Step 2 (show header) and proceed normally. The inbox will be empty (no suggestions yet since no usage data), but the all-skills view will be populated.
2. Extract the `inventory` array from setup-state.json. This is the full skill list.
3. Load inbox data using `lib/inbox-store.js`. Execute with the **Bash** tool:
node -e "
const { InboxStore } = require('./lib/inbox-store');
const baseDir = process.env.CLAUDE_PLUGIN_ROOT || process.cwd();
const store = new InboxStore('cc', baseDir);
store.reactivateSnoozed();
const allCache = store.getAllSkillCache();
const cacheMap = {};
allCache.forEach(c => { cacheMap[c.skill_name] = c; });
console.log(JSON.stringify({
pending: store.getPending(),
skillCache: cacheMap
}, null, 2));
"Parse the output as `inboxData`. `skillCache` is a map keyed by skill name. If the script fails, treat `pending` as `[]` and `skillCache` as `{}`.
4. Check if a weekly digest is due and run it if so. Execute with the **Bash** tool:
node -e "
const { InboxEngine } = require('./lib/inbox-engine');
const fs = require('fs');
const path = require('path');
const baseDir = process.env.CLAUDE_PLUGIN_ROOT || process.cwd();
const setupPaths = [
path.join(baseDir, '.skill-compass', 'cc', 'setup-state.json'),
path.join(baseDir, '.skill-compass', 'setup-state.json')
];
let state = { inventory: [] };
for (const sp of setupPaths) {
if (fs.existsSync(sp)) { state = JSON.parse(fs.readFileSync(sp, 'utf8')); break; }
}
const skillEntries = state.inventory || [];
const engine = new InboxEngine('cc', baseDir);
if (engine.isDigestDue(7)) {
const result = engine.runDigest(skillEntries);
console.log(JSON.stringify({ ran: true, added: result.added }));
} else {
console.log(JSON.stringify({ ran: false, added: 0 }));
}
"If `ran` is true and `added > 0`, note that `added` new suggestions were generated. Re-load `inboxData.pending` by re-running Step 1.3.
Step 2: Show Header
Compute:
- `pendingCount`: `inboxData.pending.length`
- `totalSkills`: `inventory.length`
Always display:
Skill Inbox — Suggestions ({pendingCount}) | All skills ({totalSkills})Step 3: Route to View
- If argument is `all` → go to Step 5 (All Skills View).
- Otherwise → go to Step 4 (Suggestions View).
Step 4: Suggestions View (Default)
Get pending suggestions from `inboxData.pending` (already sorted by priority).
If suggestions exist
Show up to 3 suggestions at a time. Present each conversationally — explain what was detected and why it matters. Do NOT show rule_id, priority, category, or evidence directly. These are internal metadata; the reason text already summarizes the situation.
Example output:
Skill Inbox — Suggestions (3) | All skills (12) 1. old-formatter — installed 30 days ago, never invoked Uses 7.1KB of context without producing value; cleaning it up frees space. 2. k8s-deploy — used 8 times in the prior two weeks, suddenly stopped in the last 7 days May indicate the user found an alternative or hit a problem. 3. translate — used only once (March 15), never again May have been a one-off need.
For state-changing actions, present keyboard-selectable choices per suggestion. The user can also respond with natural language for non-state-changing queries (e.g. "show all skills", "which haven't been used"), but state changes (pin/delete/mute/snooze) should go through explicit choice confirmation.
After the list, prompt:
Choose a suggestion to see action options, or tell me how you'd like to handle it.
When user selects a suggestion (by number or by name), show the action choices as keyboard-selectable options:
old-formatter — installed 30 days ago, never invoked [Pin (stop suggesting cleanup)] [Evaluate quality] [Delete] [Remind later (in 14 days)] [View details]
"View details" expands to show rule_id, evidence, cooldown info — only when user explicitly asks.
If no suggestions
Output:
All suggestions processed ✓ Skill usage data is accumulating. [View all skills / View skill report / Done]
Stop.
Handle Actions
Wait for the user's input in the form `{n} {action}`. Parse the suggestion number and action keyword per the table below.
For each action, execute the corresponding store methods via the **Bash** tool, then print the confirmation message.
| Action keyword | What to execute | Confirmation output | |----------------|-----------------|---------------------| | pin | `store.pinSkill(skillName)`, `store.accept(sugId)`, `store.resolve(sugId)` | `✓ Pinned {name}; Hygiene rules will no longer suggest cleanup.` | | eval | `store.accept(sugId)` | `✓ Added to eval queue. Run /eval-skill {name}.` | | improve | `store.accept(sugId)` | `✓ Added to improve queue. Run /eval-improve {name}.` | | delete |
Evaluate agent skill quality. Find the weakest link. Fix it. Prove it worked.
Repo: Evol-ai/SkillCompass
Other commands on skill-compass.
- /eval-audit
**Locale**: All templates in this spec are written in English. Detect the user's language from the session and translate user-facing text at display time per SKILL.md's Global UX Rules. Dimension labels: see the canonical table in SKILL.md.
Open command - /eval-compare
**Locale**: All templates in this spec are written in English. Detect the user's language from the session and translate user-facing text at display time per SKILL.md's Global UX Rules. Dimension labels: see the canonical table in SKILL.md.
Open command - /eval-evolve
**Locale**: All templates in this spec are written in English. Detect the user's language from the session and translate user-facing text at display time per SKILL.md's Global UX Rules. Dimension labels: see the canonical table in SKILL.md.
Open command - /eval-improve
- **Recommended model: Claude Opus 4.6** (`claude-opus-4-6`). Directed improvement requires understanding complex rubric feedback and generating precise, targeted edits. Weaker models may produce unfocused rewrites that fail to address the weakest dimension or introduce
Open command - /eval-merge
**Locale**: All templates in this spec are written in English. Detect the user's language from the session and translate user-facing text at display time per SKILL.md's Global UX Rules. Dimension labels: see the canonical table in SKILL.md.
Open command - /eval-rollback
**Locale**: All templates in this spec are written in English. Detect the user's language from the session and translate user-facing text at display time per SKILL.md's Global UX Rules. Dimension labels: see the canonical table in SKILL.md.
Open command

