snippet-manager
Save, organize, search, and retrieve code snippets with tags, categories, and smart search capabi...
Best use case
snippet-manager is best used when you need a repeatable AI agent workflow instead of a one-off prompt. It is especially useful for teams working in multi. Save, organize, search, and retrieve code snippets with tags, categories, and smart search capabi...
Save, organize, search, and retrieve code snippets with tags, categories, and smart search capabi...
Users should expect a more consistent workflow output, faster repeated execution, and less time spent rewriting prompts from scratch.
Practical example
Example input
Use the "snippet-manager" skill to help with this workflow task. Context: Save, organize, search, and retrieve code snippets with tags, categories, and smart search capabi...
Example output
A structured workflow result with clearer steps, more consistent formatting, and an output that is easier to reuse in the next run.
When to use this skill
- Use this skill when you want a reusable workflow rather than writing the same prompt again and again.
When not to use this skill
- Do not use this when you only need a one-off answer and do not need a reusable workflow.
- Do not use it if you cannot install or maintain the related files, repository context, or supporting tools.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/snippet-manager/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How snippet-manager Compares
| Feature / Agent | snippet-manager | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Save, organize, search, and retrieve code snippets with tags, categories, and smart search capabi...
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Snippet Manager Skill
Save, organize, search, and retrieve code snippets with tags, categories, and smart search capabilities.
## Instructions
You are a code snippet management expert. When invoked:
1. **Save Code Snippets**:
- Extract reusable code patterns
- Add metadata (language, tags, description)
- Organize by category and use case
- Version snippet variations
2. **Search and Retrieve**:
- Search by language, tags, or keywords
- Find similar patterns
- Suggest relevant snippets based on context
- Filter by framework or library
3. **Snippet Organization**:
- Categorize snippets logically
- Tag with relevant keywords
- Group related snippets
- Create snippet collections
4. **Snippet Enhancement**:
- Add usage examples
- Document parameters and options
- Include edge cases
- Provide alternative implementations
## Snippet Categories
- **Language Basics**: Common patterns, idioms, syntax helpers
- **Data Structures**: Arrays, objects, maps, sets manipulation
- **Algorithms**: Sorting, searching, recursion, dynamic programming
- **API Patterns**: REST clients, error handling, authentication
- **Database**: Queries, migrations, ORM patterns
- **Testing**: Test setups, mocks, assertions
- **React/Vue/Angular**: Component patterns, hooks, directives
- **Node.js**: Express middleware, streams, file operations
- **Python**: Decorators, context managers, generators
- **DevOps**: Docker, CI/CD, deployment scripts
- **Utilities**: Date/time, string manipulation, validation
## Usage Examples
```
@snippet-manager Save API error handler
@snippet-manager --search "react hooks"
@snippet-manager --category testing
@snippet-manager --language python
@snippet-manager --tag async
@snippet-manager --collection "authentication patterns"
```
## Snippet Format
### Basic Snippet Structure
```markdown
# Snippet: Async Error Handler Wrapper
**Language**: JavaScript/TypeScript
**Category**: Error Handling
**Tags**: async, error-handling, middleware, express
**Framework**: Express.js
**Use Case**: Wrap async route handlers to catch errors
## Code
```javascript
const asyncHandler = (fn) => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
// Usage
app.get('/users/:id', asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
res.json(user);
}));
```
## Parameters
- `fn`: Async function to wrap (Request, Response, NextFunction) => Promise<void>
## Returns
Express middleware function that handles promise rejections
## Notes
- Eliminates try-catch blocks in route handlers
- Passes errors to Express error handler middleware
- Works with any async function
## Related Snippets
- [Express Error Handler Middleware](#express-error-handler)
- [Custom Error Classes](#custom-error-classes)
```
## JavaScript/TypeScript Snippets
### Debounce Function
```javascript
// Snippet: Debounce
// Category: Performance
// Tags: debounce, performance, optimization
function debounce(func, wait, immediate = false) {
let timeout;
return function executedFunction(...args) {
const later = () => {
timeout = null;
if (!immediate) func.apply(this, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(this, args);
};
}
// Usage
const handleSearch = debounce((query) => {
fetchResults(query);
}, 300);
// In React
const [searchTerm, setSearchTerm] = useState('');
const debouncedSearch = useMemo(
() => debounce((term) => {
// Perform search
console.log('Searching for:', term);
}, 500),
[]
);
useEffect(() => {
debouncedSearch(searchTerm);
}, [searchTerm, debouncedSearch]);
```
### Deep Clone Object
```javascript
// Snippet: Deep Clone
// Category: Data Structures
// Tags: clone, deep-copy, objects
// Method 1: JSON (simple objects only)
const deepClone = (obj) => JSON.parse(JSON.stringify(obj));
// Method 2: Structured Clone (modern browsers/Node.js)
const deepClone2 = (obj) => structuredClone(obj);
// Method 3: Custom recursive (handles complex types)
function deepClone3(obj, hash = new WeakMap()) {
if (Object(obj) !== obj) return obj; // primitives
if (hash.has(obj)) return hash.get(obj); // cyclic reference
const result = Array.isArray(obj)
? []
: obj.constructor
? new obj.constructor()
: Object.create(null);
hash.set(obj, result);
return Object.assign(
result,
...Object.keys(obj).map(key => ({
[key]: deepClone3(obj[key], hash)
}))
);
}
// Usage
const original = { a: 1, b: { c: 2 }, d: [3, 4] };
const cloned = deepClone(original);
cloned.b.c = 999; // original.b.c remains 2
```
### Retry with Exponential Backoff
```typescript
// Snippet: Retry with Exponential Backoff
// Category: Error Handling
// Tags: retry, async, error-handling, resilience
async function retryWithBackoff<T>(
fn: () => Promise<T>,
options: {
maxRetries?: number;
initialDelay?: number;
maxDelay?: number;
factor?: number;
} = {}
): Promise<T> {
const {
maxRetries = 3,
initialDelay = 1000,
maxDelay = 30000,
factor = 2,
} = options;
let lastError: Error;
let delay = initialDelay;
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (error) {
lastError = error as Error;
if (attempt === maxRetries) {
throw new Error(
`Failed after ${maxRetries} retries: ${lastError.message}`
);
}
console.log(`Attempt ${attempt + 1} failed, retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
delay = Math.min(delay * factor, maxDelay);
}
}
throw lastError!;
}
// Usage
const data = await retryWithBackoff(
() => fetch('https://api.example.com/data').then(r => r.json()),
{ maxRetries: 5, initialDelay: 500 }
);
```
### Local Storage with Expiry
```javascript
// Snippet: Local Storage with Expiry
// Category: Browser APIs
// Tags: localstorage, cache, expiry
const storage = {
set(key, value, expiryMs = null) {
const item = {
value,
expiry: expiryMs ? Date.now() + expiryMs : null,
};
localStorage.setItem(key, JSON.stringify(item));
},
get(key) {
const itemStr = localStorage.getItem(key);
if (!itemStr) return null;
const item = JSON.parse(itemStr);
if (item.expiry && Date.now() > item.expiry) {
localStorage.removeItem(key);
return null;
}
return item.value;
},
remove(key) {
localStorage.removeItem(key);
},
clear() {
localStorage.clear();
},
};
// Usage
storage.set('user', { id: 1, name: 'John' }, 3600000); // 1 hour
const user = storage.get('user');
```
## React Snippets
### Custom useDebounce Hook
```typescript
// Snippet: useDebounce Hook
// Category: React Hooks
// Tags: react, hooks, debounce, performance
import { useEffect, useState } from 'react';
function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
}
// Usage
function SearchComponent() {
const [searchTerm, setSearchTerm] = useState('');
const debouncedSearchTerm = useDebounce(searchTerm, 500);
useEffect(() => {
if (debouncedSearchTerm) {
// Perform search
fetchResults(debouncedSearchTerm);
}
}, [debouncedSearchTerm]);
return (
<input
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
);
}
```
### Custom useAsync Hook
```typescript
// Snippet: useAsync Hook
// Category: React Hooks
// Tags: react, hooks, async, data-fetching
import { useEffect, useState, useCallback } from 'react';
type Status = 'idle' | 'loading' | 'success' | 'error';
interface AsyncState<T> {
status: Status;
data: T | null;
error: Error | null;
}
function useAsync<T>(
asyncFunction: () => Promise<T>,
immediate = true
) {
const [state, setState] = useState<AsyncState<T>>({
status: 'idle',
data: null,
error: null,
});
const execute = useCallback(async () => {
setState({ status: 'loading', data: null, error: null });
try {
const data = await asyncFunction();
setState({ status: 'success', data, error: null });
return data;
} catch (error) {
setState({ status: 'error', data: null, error: error as Error });
throw error;
}
}, [asyncFunction]);
useEffect(() => {
if (immediate) {
execute();
}
}, [execute, immediate]);
return { ...state, execute };
}
// Usage
function UserProfile({ userId }) {
const { status, data, error } = useAsync(
() => fetch(`/api/users/${userId}`).then(r => r.json()),
true
);
if (status === 'loading') return <div>Loading...</div>;
if (status === 'error') return <div>Error: {error.message}</div>;
if (status === 'success') return <div>User: {data.name}</div>;
return null;
}
```
### Custom useLocalStorage Hook
```typescript
// Snippet: useLocalStorage Hook
// Category: React Hooks
// Tags: react, hooks, localstorage, persistence
import { useState, useEffect } from 'react';
function useLocalStorage<T>(
key: string,
initialValue: T
): [T, (value: T | ((val: T) => T)) => void] {
// Get from local storage then parse stored json or return initialValue
const readValue = (): T => {
if (typeof window === 'undefined') {
return initialValue;
}
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.warn(`Error reading localStorage key "${key}":`, error);
return initialValue;
}
};
const [storedValue, setStoredValue] = useState<T>(readValue);
const setValue = (value: T | ((val: T) => T)) => {
try {
const valueToStore =
value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
if (typeof window !== 'undefined') {
window.localStorage.setItem(key, JSON.stringify(valueToStore));
}
} catch (error) {
console.warn(`Error setting localStorage key "${key}":`, error);
}
};
useEffect(() => {
setStoredValue(readValue());
}, []);
return [storedValue, setValue];
}
// Usage
function App() {
const [theme, setTheme] = useLocalStorage('theme', 'light');
return (
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Current theme: {theme}
</button>
);
}
```
## Python Snippets
### Retry Decorator
```python
# Snippet: Retry Decorator
# Category: Error Handling
# Tags: python, decorator, retry, error-handling
import time
import functools
from typing import Callable, Type
def retry(
max_attempts: int = 3,
delay: float = 1.0,
backoff: float = 2.0,
exceptions: tuple[Type[Exception], ...] = (Exception,)
):
"""
Retry decorator with exponential backoff
Args:
max_attempts: Maximum number of retry attempts
delay: Initial delay between retries in seconds
backoff: Multiplier for delay after each retry
exceptions: Tuple of exceptions to catch
"""
def decorator(func: Callable):
@functools.wraps(func)
def wrapper(*args, **kwargs):
current_delay = delay
last_exception = None
for attempt in range(max_attempts):
try:
return func(*args, **kwargs)
except exceptions as e:
last_exception = e
if attempt == max_attempts - 1:
raise
print(f"Attempt {attempt + 1} failed: {e}")
print(f"Retrying in {current_delay}s...")
time.sleep(current_delay)
current_delay *= backoff
raise last_exception
return wrapper
return decorator
# Usage
@retry(max_attempts=5, delay=0.5, exceptions=(ConnectionError, TimeoutError))
def fetch_data(url: str):
response = requests.get(url, timeout=10)
response.raise_for_status()
return response.json()
```
### Context Manager for Timing
```python
# Snippet: Timing Context Manager
# Category: Performance
# Tags: python, context-manager, timing, profiling
import time
from contextlib import contextmanager
from typing import Optional
@contextmanager
def timer(name: Optional[str] = None):
"""
Context manager to time code execution
Usage:
with timer("Database query"):
result = db.query(...)
"""
start = time.perf_counter()
try:
yield
finally:
elapsed = time.perf_counter() - start
label = f"{name}: " if name else ""
print(f"{label}Elapsed time: {elapsed:.4f}s")
# Usage
with timer("API call"):
response = requests.get("https://api.example.com/data")
data = response.json()
# Alternative: As a decorator
def timed(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
elapsed = time.perf_counter() - start
print(f"{func.__name__} took {elapsed:.4f}s")
return result
return wrapper
@timed
def process_data(data):
# Process data
pass
```
### Memoization with LRU Cache
```python
# Snippet: Memoization
# Category: Performance
# Tags: python, cache, memoization, optimization
from functools import lru_cache, wraps
import pickle
import hashlib
# Simple memoization with lru_cache
@lru_cache(maxsize=128)
def fibonacci(n: int) -> int:
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
# Custom memoization for unhashable arguments
def memoize(func):
cache = {}
@wraps(func)
def wrapper(*args, **kwargs):
# Create hashable key from arguments
key = hashlib.md5(
pickle.dumps((args, tuple(sorted(kwargs.items()))))
).hexdigest()
if key not in cache:
cache[key] = func(*args, **kwargs)
return cache[key]
wrapper.cache_clear = lambda: cache.clear()
wrapper.cache_info = lambda: f"Cache size: {len(cache)}"
return wrapper
# Usage with unhashable types (lists, dicts)
@memoize
def expensive_computation(data: list[int]) -> int:
return sum(x ** 2 for x in data)
result = expensive_computation([1, 2, 3, 4, 5])
```
## Node.js Snippets
### Rate Limiter Middleware
```javascript
// Snippet: Rate Limiter
// Category: Middleware
// Tags: nodejs, express, rate-limiting, security
class RateLimiter {
constructor(options = {}) {
this.windowMs = options.windowMs || 60000; // 1 minute
this.maxRequests = options.maxRequests || 100;
this.requests = new Map();
}
middleware() {
return (req, res, next) => {
const key = req.ip || req.connection.remoteAddress;
const now = Date.now();
if (!this.requests.has(key)) {
this.requests.set(key, []);
}
const userRequests = this.requests.get(key);
// Remove old requests outside the window
const validRequests = userRequests.filter(
timestamp => now - timestamp < this.windowMs
);
if (validRequests.length >= this.maxRequests) {
const oldestRequest = validRequests[0];
const resetTime = oldestRequest + this.windowMs;
const retryAfter = Math.ceil((resetTime - now) / 1000);
res.set('Retry-After', retryAfter.toString());
return res.status(429).json({
error: 'Too many requests',
retryAfter: retryAfter,
});
}
validRequests.push(now);
this.requests.set(key, validRequests);
res.set('X-RateLimit-Limit', this.maxRequests.toString());
res.set('X-RateLimit-Remaining',
(this.maxRequests - validRequests.length).toString()
);
next();
};
}
// Cleanup old entries periodically
cleanup() {
const now = Date.now();
for (const [key, timestamps] of this.requests.entries()) {
const valid = timestamps.filter(t => now - t < this.windowMs);
if (valid.length === 0) {
this.requests.delete(key);
} else {
this.requests.set(key, valid);
}
}
}
}
// Usage
const limiter = new RateLimiter({
windowMs: 15 * 60 * 1000, // 15 minutes
maxRequests: 100,
});
app.use('/api', limiter.middleware());
// Cleanup every 5 minutes
setInterval(() => limiter.cleanup(), 5 * 60 * 1000);
```
### Stream Pipeline Helper
```javascript
// Snippet: Stream Pipeline
// Category: Streams
// Tags: nodejs, streams, pipeline, files
const { pipeline } = require('stream');
const { promisify } = require('util');
const fs = require('fs');
const zlib = require('zlib');
const { Transform } = require('stream');
const pipelineAsync = promisify(pipeline);
// Custom transform stream
class LineCounter extends Transform {
constructor(options) {
super(options);
this.lineCount = 0;
}
_transform(chunk, encoding, callback) {
const lines = chunk.toString().split('\n').length - 1;
this.lineCount += lines;
this.push(chunk);
callback();
}
}
// Usage: Compress file and count lines
async function compressAndCount(inputFile, outputFile) {
const counter = new LineCounter();
await pipelineAsync(
fs.createReadStream(inputFile),
counter,
zlib.createGzip(),
fs.createWriteStream(outputFile)
);
console.log(`Processed ${counter.lineCount} lines`);
return counter.lineCount;
}
// Usage: Process large CSV
async function processCsv(inputFile) {
const processLine = new Transform({
transform(chunk, encoding, callback) {
const lines = chunk.toString().split('\n');
const processed = lines
.map(line => line.toUpperCase())
.join('\n');
callback(null, processed);
}
});
await pipelineAsync(
fs.createReadStream(inputFile),
processLine,
fs.createWriteStream('output.csv')
);
}
```
## SQL Snippets
### Safe Upsert Pattern
```sql
-- Snippet: Upsert (Insert or Update)
-- Category: Database
-- Tags: sql, upsert, postgresql
-- PostgreSQL
INSERT INTO users (id, email, name, updated_at)
VALUES (1, 'user@example.com', 'John Doe', NOW())
ON CONFLICT (id)
DO UPDATE SET
email = EXCLUDED.email,
name = EXCLUDED.name,
updated_at = NOW()
RETURNING *;
-- Multiple rows upsert
INSERT INTO products (sku, name, price)
VALUES
('SKU001', 'Product 1', 29.99),
('SKU002', 'Product 2', 39.99)
ON CONFLICT (sku)
DO UPDATE SET
name = EXCLUDED.name,
price = EXCLUDED.price,
updated_at = NOW();
```
### Pagination Query
```sql
-- Snippet: Efficient Pagination
-- Category: Database
-- Tags: sql, pagination, performance
-- Offset-based (simple but slower for large offsets)
SELECT *
FROM posts
ORDER BY created_at DESC
LIMIT 20 OFFSET 40; -- Page 3
-- Cursor-based (more efficient)
SELECT *
FROM posts
WHERE created_at < '2024-01-01 12:00:00'
ORDER BY created_at DESC
LIMIT 20;
-- Keyset pagination (best performance)
SELECT *
FROM posts
WHERE (created_at, id) < ('2024-01-01 12:00:00', 12345)
ORDER BY created_at DESC, id DESC
LIMIT 20;
```
## Best Practices
### Snippet Organization
- **Consistent naming**: Use clear, descriptive names
- **Comprehensive tags**: Add multiple relevant tags
- **Version tracking**: Keep track of snippet versions
- **Dependencies**: Document required libraries
### Documentation
- **Usage examples**: Show real-world usage
- **Parameter docs**: Document all parameters
- **Edge cases**: Mention limitations and edge cases
- **Alternatives**: Suggest related patterns
### Maintenance
- **Regular review**: Update snippets periodically
- **Test snippets**: Ensure snippets still work
- **Deprecation**: Mark outdated snippets
- **Contribution**: Share useful snippets with team
## Snippet Management Tools
### File-based Storage
```
snippets/
├── javascript/
│ ├── async/
│ │ ├── retry.js
│ │ └── debounce.js
│ └── react/
│ ├── hooks/
│ └── components/
├── python/
│ ├── decorators/
│ └── context-managers/
└── sql/
├── queries/
└── migrations/
```
### Metadata Format (frontmatter)
```yaml
---
title: "Async Retry with Backoff"
language: javascript
category: error-handling
tags: [async, retry, error-handling, resilience]
framework: nodejs
version: 1.2.0
author: team
created: 2024-01-15
updated: 2024-01-20
---
```
## Notes
- Keep snippets focused and single-purpose
- Include error handling in examples
- Document performance characteristics
- Test snippets before saving
- Use consistent coding style
- Add comments for complex logic
- Version snippets when making changes
- Share snippets within team
- Regular cleanup of outdated snippetsRelated Skills
backlog-manager
需求池管理。用户随时抛出想法/痛点,AI 负责追问、整理、合并、归档到需求池文件。用户准备开新版本时,协助从池中筛选。痛点驱动,不做提前排期。
seo-snippet-hunter
Formats content to be eligible for featured snippets and SERP features. Creates snippet-optimized content blocks based on best practices. Use PROACTIVELY for question-based content.
risk-manager
Monitor portfolio risk, R-multiples, and position limits. Creates hedging strategies, calculates expectancy, and implements stop-losses. Use PROACTIVELY for risk assessment, trade tracking, or portfolio protection.
context-manager
Elite AI context engineering specialist mastering dynamic context management, vector databases, knowledge graphs, and intelligent memory systems. Orchestrates context across multi-agent workflows, enterprise AI systems, and long-running projects with 2024/2025 best practices. Use PROACTIVELY for complex AI orchestration.
azure-resource-manager-sql-dotnet
Azure Resource Manager SDK for Azure SQL in .NET. Use for MANAGEMENT PLANE operations: creating/managing SQL servers, databases, elastic pools, firewall rules, and failover groups via Azure Resource Manager. NOT for data plane operations (executing queries) - use Microsoft.Data.SqlClient for that. Triggers: "SQL server", "create SQL database", "manage SQL resources", "ARM SQL", "SqlServerResource", "provision Azure SQL", "elastic pool", "firewall rule".
azure-resource-manager-redis-dotnet
Azure Resource Manager SDK for Redis in .NET. Use for MANAGEMENT PLANE operations: creating/managing Azure Cache for Redis instances, firewall rules, access keys, patch schedules, linked servers (geo-replication), and private endpoints via Azure Resource Manager. NOT for data plane operations (get/set keys, pub/sub) - use StackExchange.Redis for that. Triggers: "Redis cache", "create Redis", "manage Redis", "ARM Redis", "RedisResource", "provision Redis", "Azure Cache for Redis".
azure-resource-manager-postgresql-dotnet
Azure PostgreSQL Flexible Server SDK for .NET. Database management for PostgreSQL Flexible Server deployments. Use for creating servers, databases, firewall rules, configurations, backups, and high availability. Triggers: "PostgreSQL", "PostgreSqlFlexibleServer", "PostgreSQL Flexible Server", "Azure Database for PostgreSQL", "PostgreSQL database management", "PostgreSQL firewall", "PostgreSQL backup", "Postgres".
azure-resource-manager-playwright-dotnet
Azure Resource Manager SDK for Microsoft Playwright Testing in .NET. Use for MANAGEMENT PLANE operations: creating/managing Playwright Testing workspaces, checking name availability, and managing workspace quotas via Azure Resource Manager. NOT for running Playwright tests - use Azure.Developer.MicrosoftPlaywrightTesting.NUnit for that. Triggers: "Playwright workspace", "create Playwright Testing workspace", "manage Playwright resources", "ARM Playwright", "PlaywrightWorkspaceResource", "provision Playwright Testing".
azure-resource-manager-cosmosdb-dotnet
Azure Resource Manager SDK for Cosmos DB in .NET. Use for MANAGEMENT PLANE operations: creating/managing Cosmos DB accounts, databases, containers, throughput settings, and RBAC via Azure Resource Manager. NOT for data plane operations (CRUD on documents) - use Microsoft.Azure.Cosmos for that. Triggers: "Cosmos DB account", "create Cosmos account", "manage Cosmos resources", "ARM Cosmos", "CosmosDBAccountResource", "provision Cosmos DB".
agent-manager-skill
Manage multiple local CLI agents via tmux sessions (start/stop/monitor/assign) with cron-friendly scheduling.
notebooklm-manager
This skill should be used when the user wants to interact with NotebookLM notebooks via Claude Code's Chrome integration. Trigger phrases: "Query my NotebookLM", "Ask my notebook about X", "query [id] about X", "list my notebooks", "add notebook URL", "show notebook details", "search notebooks for X", "Check my docs", "what does my [topic] notebook say about", "remove notebook", "delete notebook", "disable notebook", "enable notebook". Also triggers when user: (1) mentions NotebookLM explicitly, (2) shares NotebookLM URL (https://notebooklm.google.com/notebook/...). Do NOT use for: general web searches, local file reading, or non-NotebookLM documentation queries. Requires: claude --chrome with claude-in-chrome MCP.
home-assistant-manager
Expert-level Home Assistant configuration management with efficient deployment workflows (git and rapid scp iteration), remote CLI access via SSH and hass-cli, automation verification protocols, log analysis, reload vs restart optimization, and comprehensive Lovelace dashboard management for tablet-optimized UIs. Includes template patterns, card types, debugging strategies, and real-world examples.