$npx -y skills add jmxt3/gitscape.ai --skill nvidia-skillspectorGuides 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
| 1 | # Skillspector Code Skill |
| 2 | |
| 3 | ## Overview |
| 4 | |
| 5 | **Security scanner for AI agent skills.** Detect vulnerabilities, malicious patterns, and security risks before installing agent skills. |
| 6 | |
| 7 | Top-level areas: `.github/`, `contrib/`, `docs/`, `extensions/`, `src/`, `tests/`. |
| 8 | |
| 9 | Primary languages: Python, TypeScript, Shell. The codebase contains 282 public symbols across 69 source files. |
| 10 | |
| 11 | **Key symbols:** |
| 12 | |
| 13 | - `is_language_compatible` `def is_language_compatible(rule_id: str, detected_language: str) -> bool` — Return ``True`` when *rule_id* is reliable for *detected_language*. |
| 14 | - `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. |
| 15 | - `ApiKey` `class ApiKey` — A single API key with concurrency and rate-limit metadata. |
| 16 | - `ApiKey.available` `def available(self) -> bool` — ``True`` when this key can accept at least one more caller. |
| 17 | - `ApiKeyPool` `class ApiKeyPool` — Thread-safe pool of API keys with per-key concurrency slots. |
| 18 | - `ApiKeyPool.__init__` `def __init__(self, keys: list[ApiKey]) -> None` |
| 19 | - `ApiKeyPool.acquire` `def acquire(self, timeout: float | None = None) -> ApiKey` — Acquire a slot on the least-loaded available key. |
| 20 | - `ApiKeyPool.try_acquire` `def try_acquire(self) -> ApiKey | None` — Non-blocking acquire — returns a key immediately or ``None``. |
| 21 | - `ApiKeyPool.release` `def release(self, key: ApiKey, *, success: bool = True) -> None` — Release a slot on *key* back to the pool. |
| 22 | - `ApiKeyPool.record_retry_success` `def record_retry_success(self) -> None` — Increment the retry-success counter for reporting. |
| 23 | - `ApiKeyPool.rate_limits_hit` `def rate_limits_hit(self) -> int` — Total number of 429 responses encountered across all keys. |
| 24 | - `ApiKeyPool.retry_successes` `def retry_successes(self) -> int` — Total number of successful retries after a key switch. |
| 25 | - `ApiKeyPool.keys_configured` `def keys_configured(self) -> int` — Total number of keys in the pool. |
| 26 | - `ApiKeyPool.total_capacity` `def total_capacity(self) -> int` — Sum of ``max_concurrent`` across all keys. |
| 27 | - `ApiKeyPool.active_requests` `def active_requests(self) -> int` — Total active requests across all keys. |
| 28 | - `ApiKeyPool.snapshot` `def snapshot(self) -> dict[str, object]` — Return a snapshot dict suitable for report metadata. |
| 29 | - `PooledChatModel` `class PooledChatModel` — LangChain-compatible chat model wrapper with transparent key switching. |
| 30 | - `PooledChatModel.__init__` `def __init__( self, pool: ApiKeyPool, *, max_tokens: int = 4096, timeout: float = 30.0, max_retries: int = _MAX_RATE_LIMIT_RETRIES, ) -> None` |
| 31 | - `PooledChatModel.invoke` `def invoke(self, prompt: str) -> object` — Synchronous invoke with automatic key switching on rate-limit. |
| 32 | - `PooledChatModel.ainvoke` `def ainvoke(self, prompt: str) -> object` — Async invoke with automatic key switching on rate-limit. |
| 33 | |
| 34 | *…and 262 more — see `references/api.md`.* |
| 35 | |
| 36 | ## When to Use |
| 37 | |
| 38 | - Understanding the architecture and module layout of SkillSpector |
| 39 | - Extending or modifying SkillSpector consistent with its existing patterns |
| 40 | - Debugging issues by tracing through SkillSpector's modules and dependencies |
| 41 | - Setting up, running, or configuring SkillSpector |
| 42 | - Calling functions, classes, or methods in SkillSpector's public API |
| 43 | |
| 44 | **When NOT to use:** General Python, TypeScript, Shell questions, tutorials, or tasks unrelated to the SkillSpector codebase. |
| 45 | |
| 46 | **Related:** For general Python, TypeScript, Shell guidance, use language-specific skills instead. |
| 47 | |
| 48 | ## Core Process |
| 49 | |
| 50 | ### Step 1: Understand the Architecture |
| 51 | |
| 52 | 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. |
| 53 | |
| 54 | ### Step 2: Locate Relevant Modules |
| 55 | |
| 56 | 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. |
| 57 | |
| 58 | ### Step 3: Make Changes Following Existing Patterns |
| 59 | |
| 60 | 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. |
| 61 | |
| 62 | ### Step 4: Verify the Change |
| 63 | |
| 64 | 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. |
| 65 | |
| 66 | ## Common Rationalizations |
| 67 | |
| 68 | | Rationalization | Reali |