Skillspector Code Skill
Overview
Security scanner for AI agent skills. Detect vulnerabilities, malicious patterns, and security risks before installing agent skills.
Top-level areas: .github/, contrib/, docs/, extensions/, src/, tests/.
Primary languages: Python, TypeScript, Shell. The codebase contains 282 public symbols across 69 source files.
Key symbols:
is_language_compatible def is_language_compatible(rule_id: str, detected_language: str) -> bool — Return True when rule_id is reliable for detected_language.
annotate_findings def annotate_findings( issues: list[dict[str, object]], detected_language: str, ) -> list[dict[str, object]] — Add a language_compatible field to each issue dict.
ApiKey class ApiKey — A single API key with concurrency and rate-limit metadata.
ApiKey.available def available(self) -> bool — True when this key can accept at least one more caller.
ApiKeyPool class ApiKeyPool — Thread-safe pool of API keys with per-key concurrency slots.
ApiKeyPool.__init__ def __init__(self, keys: list[ApiKey]) -> None
ApiKeyPool.acquire def acquire(self, timeout: float | None = None) -> ApiKey — Acquire a slot on the least-loaded available key.
ApiKeyPool.try_acquire def try_acquire(self) -> ApiKey | None — Non-blocking acquire — returns a key immediately or None.
ApiKeyPool.release def release(self, key: ApiKey, *, success: bool = True) -> None — Release a slot on key back to the pool.
ApiKeyPool.record_retry_success def record_retry_success(self) -> None — Increment the retry-success counter for reporting.
ApiKeyPool.rate_limits_hit def rate_limits_hit(self) -> int — Total number of 429 responses encountered across all keys.
ApiKeyPool.retry_successes def retry_successes(self) -> int — Total number of successful retries after a key switch.
ApiKeyPool.keys_configured def keys_configured(self) -> int — Total number of keys in the pool.
ApiKeyPool.total_capacity def total_capacity(self) -> int — Sum of max_concurrent across all keys.
ApiKeyPool.active_requests def active_requests(self) -> int — Total active requests across all keys.
ApiKeyPool.snapshot def snapshot(self) -> dict[str, object] — Return a snapshot dict suitable for report metadata.
PooledChatModel class PooledChatModel — LangChain-compatible chat model wrapper with transparent key switching.
PooledChatModel.__init__ def __init__( self, pool: ApiKeyPool, *, max_tokens: int = 4096, timeout: float = 30.0, max_retries: int = _MAX_RATE_LIMIT_RETRIES, ) -> None
PooledChatModel.invoke def invoke(self, prompt: str) -> object — Synchronous invoke with automatic key switching on rate-limit.
PooledChatModel.ainvoke def ainvoke(self, prompt: str) -> object — Async invoke with automatic key switching on rate-limit.
…and 262 more — see references/api.md.
When to Use
- Understanding the architecture and module layout of SkillSpector
- Extending or modifying SkillSpector consistent with its existing patterns
- Debugging issues by tracing through SkillSpector's modules and dependencies
- Setting up, running, or configuring SkillSpector
- Calling functions, classes, or methods in SkillSpector's public API
When NOT to use: General Python, TypeScript, Shell questions, tutorials, or tasks unrelated to the SkillSpector codebase.
Related: For general Python, TypeScript, Shell guidance, use language-specific skills instead.
Core Process
Step 1: Understand the Architecture
Read the existing code in SkillSpector before making changes. Check references/architecture.md to understand the module layout, dependency graph, and internal import structure. The goal is to extend existing patterns, not invent new ones.
Step 2: Locate Relevant Modules
Use references/api.md to find the public symbols, functions, and classes relevant to the task. Trace the call chain through SkillSpector's internal imports to understand how the pieces connect.
Step 3: Make Changes Following Existing Patterns
Implement the change consistent with SkillSpector's established conventions: naming patterns, error handling style, module organization, and test structure. Consistency matters more than personal preference.
Step 4: Verify the Change
Run the project's test suite and confirm all tests pass. If no tests exist for the changed behavior, write them first. Check that no regressions were introduced in adjacent modules.
Common Rationalizations
| Rationalization |
Reality |
| "I know SkillSpector well enough to skip reading the existing code" |
Every session starts with stale context. Re-read the architecture reference before assuming you know the current state. |
| "This change is too small to need tests" |
Small changes in unfamiliar codebases cause the most subtle regressions. A test that fails without the fix and passes with it is the minimum bar. |
| "I'll follow the patterns later, let me just get it working first" |
Pattern violations compound. Code that works but violates the repository's conventions creates maintenance debt for every future contributor. |
Red Flags
- Making changes to SkillSpector without reading
references/architecture.md first
- Inventing new patterns instead of extending existing ones
- Skipping the test suite before declaring the task complete
- Modifying code outside the scope of the current task
Verification
Before declaring this workflow complete, confirm each item with evidence:
References
- Full API reference
- Architecture & dependencies
- Usage examples
- Setup & commands
- Configuration
- Full Code Digest
1---2name: nvidia-skillspector3description: Guides agents through working with the NVIDIA/SkillSpector codebase (Python, TypeScript, Shell). Use when extending, debugging, or navigating SkillSpector, or when the user mentions 'SkillSpector', 'NVIDIA/SkillSpector', or asks about its architecture, modules, or public API. Not for general Python, TypeScript, Shell questions unrelated to SkillSpector.4---56# Skillspector Code Skill78## Overview910**Security scanner for AI agent skills.** Detect vulnerabilities, malicious patterns, and security risks before installing agent skills.1112Top-level areas: `.github/`, `contrib/`, `docs/`, `extensions/`, `src/`, `tests/`.1314Primary languages: Python, TypeScript, Shell. The codebase contains 282 public symbols across 69 source files.1516**Key symbols:**1718- `is_language_compatible` `def is_language_compatible(rule_id: str, detected_language: str) -> bool` — Return ``True`` when *rule_id* is reliable for *detected_language*.19- `annotate_findings` `def annotate_findings( issues: list[dict[str, object]], detected_language: str, ) -> list[dict[str, object]]` — Add a ``language_compatible`` field to each issue dict.20- `ApiKey` `class ApiKey` — A single API key with concurrency and rate-limit metadata.21- `ApiKey.available` `def available(self) -> bool` — ``True`` when this key can accept at least one more caller.22- `ApiKeyPool` `class ApiKeyPool` — Thread-safe pool of API keys with per-key concurrency slots.23- `ApiKeyPool.__init__` `def __init__(self, keys: list[ApiKey]) -> None`24- `ApiKeyPool.acquire` `def acquire(self, timeout: float | None = None) -> ApiKey` — Acquire a slot on the least-loaded available key.25- `ApiKeyPool.try_acquire` `def try_acquire(self) -> ApiKey | None` — Non-blocking acquire — returns a key immediately or ``None``.26- `ApiKeyPool.release` `def release(self, key: ApiKey, *, success: bool = True) -> None` — Release a slot on *key* back to the pool.27- `ApiKeyPool.record_retry_success` `def record_retry_success(self) -> None` — Increment the retry-success counter for reporting.28- `ApiKeyPool.rate_limits_hit` `def rate_limits_hit(self) -> int` — Total number of 429 responses encountered across all keys.29- `ApiKeyPool.retry_successes` `def retry_successes(self) -> int` — Total number of successful retries after a key switch.30- `ApiKeyPool.keys_configured` `def keys_configured(self) -> int` — Total number of keys in the pool.31- `ApiKeyPool.total_capacity` `def total_capacity(self) -> int` — Sum of ``max_concurrent`` across all keys.32- `ApiKeyPool.active_requests` `def active_requests(self) -> int` — Total active requests across all keys.33- `ApiKeyPool.snapshot` `def snapshot(self) -> dict[str, object]` — Return a snapshot dict suitable for report metadata.34- `PooledChatModel` `class PooledChatModel` — LangChain-compatible chat model wrapper with transparent key switching.35- `PooledChatModel.__init__` `def __init__( self, pool: ApiKeyPool, *, max_tokens: int = 4096, timeout: float = 30.0, max_retries: int = _MAX_RATE_LIMIT_RETRIES, ) -> None`36- `PooledChatModel.invoke` `def invoke(self, prompt: str) -> object` — Synchronous invoke with automatic key switching on rate-limit.37- `PooledChatModel.ainvoke` `def ainvoke(self, prompt: str) -> object` — Async invoke with automatic key switching on rate-limit.3839*…and 262 more — see `references/api.md`.*4041## When to Use4243- Understanding the architecture and module layout of SkillSpector44- Extending or modifying SkillSpector consistent with its existing patterns45- Debugging issues by tracing through SkillSpector's modules and dependencies46- Setting up, running, or configuring SkillSpector47- Calling functions, classes, or methods in SkillSpector's public API4849**When NOT to use:** General Python, TypeScript, Shell questions, tutorials, or tasks unrelated to the SkillSpector codebase.5051**Related:** For general Python, TypeScript, Shell guidance, use language-specific skills instead.5253## Core Process5455### Step 1: Understand the Architecture5657Read the existing code in SkillSpector before making changes. Check `references/architecture.md` to understand the module layout, dependency graph, and internal import structure. The goal is to extend existing patterns, not invent new ones.5859### Step 2: Locate Relevant Modules6061Use `references/api.md` to find the public symbols, functions, and classes relevant to the task. Trace the call chain through SkillSpector's internal imports to understand how the pieces connect.6263### Step 3: Make Changes Following Existing Patterns6465Implement the change consistent with SkillSpector's established conventions: naming patterns, error handling style, module organization, and test structure. Consistency matters more than personal preference.6667### Step 4: Verify the Change6869Run the project's test suite and confirm all tests pass. If no tests exist for the changed behavior, write them first. Check that no regressions were introduced in adjacent modules.7071## Common Rationalizations7273| Rationalization | Reality |74|---|---|75| "I know SkillSpector well enough to skip reading the existing code" | Every session starts with stale context. Re-read the architecture reference before assuming you know the current state. |76| "This change is too small to need tests" | Small changes in unfamiliar codebases cause the most subtle regressions. A test that fails without the fix and passes with it is the minimum bar. |77| "I'll follow the patterns later, let me just get it working first" | Pattern violations compound. Code that works but violates the repository's conventions creates maintenance debt for every future contributor. |7879## Red Flags8081- Making changes to SkillSpector without reading `references/architecture.md` first82- Inventing new patterns instead of extending existing ones83- Skipping the test suite before declaring the task complete84- Modifying code outside the scope of the current task8586## Verification8788Before declaring this workflow complete, confirm each item with evidence:8990- [ ] Changes follow SkillSpector's existing patterns — evidence: diff review against `references/architecture.md`91- [ ] All tests pass — evidence: test runner output92- [ ] No regressions introduced in adjacent modules — evidence: full test suite output93- [ ] Code is consistent with the repository's naming and style conventions — evidence: code review9495## References9697- [Full API reference](references/api.md)98- [Architecture & dependencies](references/architecture.md)99- [Usage examples](references/examples.md)100- [Setup & commands](references/setup.md)101- [Configuration](references/config.md)102- [Full Code Digest](references/nvidia_skillspector_digest.txt)