/SKILL.md
# SKILL.md — Compétences Développement **Skills spécialisées pour l'agent Claude Dev** --- ## 🐍 Python Development ### API Development (FastAPI) **Niveau** : Expert ```python from fastapi import FastAPI, HTTPException, Depends from pydantic import BaseModel from typing import Optional app = FastAPI(title="My API", version="1.0.0") # Models class User(BaseModel): id: Optional[int] = None name: str email: str age: int # In-memory database users_db = [] # Dependency async
npx skillsauth add labsmates/claude-dev claude-devInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Skills spécialisées pour l'agent Claude Dev
Niveau : Expert
from fastapi import FastAPI, HTTPException, Depends
from pydantic import BaseModel
from typing import Optional
app = FastAPI(title="My API", version="1.0.0")
# Models
class User(BaseModel):
id: Optional[int] = None
name: str
email: str
age: int
# In-memory database
users_db = []
# Dependency
async def get_current_user(token: str = Depends(oauth2_scheme)):
# Validate token logic
return user
# Routes
@app.get("/")
async def root():
return {"message": "Welcome to API"}
@app.get("/users", response_model=list[User])
async def list_users():
return users_db
@app.get("/users/{user_id}", response_model=User)
async def get_user(user_id: int):
user = next((u for u in users_db if u['id'] == user_id), None)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user
@app.post("/users", response_model=User, status_code=201)
async def create_user(user: User):
user.id = len(users_db) + 1
users_db.append(user.dict())
return user
@app.put("/users/{user_id}", response_model=User)
async def update_user(user_id: int, user: User):
existing = next((u for u in users_db if u['id'] == user_id), None)
if not existing:
raise HTTPException(status_code=404, detail="User not found")
existing.update(user.dict(exclude={'id'}))
return existing
@app.delete("/users/{user_id}", status_code=204)
async def delete_user(user_id: int):
global users_db
users_db = [u for u in users_db if u['id'] != user_id]
return
# Run: uvicorn main:app --reload
Niveau : Avancé
import pandas as pd
import numpy as np
# Load data
df = pd.read_csv('data.csv')
# Basic exploration
print(df.head())
print(df.info())
print(df.describe())
# Filtering
filtered = df[df['age'] > 25]
filtered = df.query('age > 25 and city == "Paris"')
# Grouping & Aggregation
grouped = df.groupby('category').agg({
'price': ['mean', 'sum', 'count'],
'quantity': 'sum'
})
# Pivot tables
pivot = df.pivot_table(
values='sales',
index='month',
columns='product',
aggfunc='sum',
fill_value=0
)
# Handling missing values
df['column'].fillna(df['column'].mean(), inplace=True)
df.dropna(subset=['important_column'], inplace=True)
# Date operations
df['date'] = pd.to_datetime(df['date'])
df['year'] = df['date'].dt.year
df['month'] = df['date'].dt.month
# Apply custom functions
df['new_column'] = df['old_column'].apply(lambda x: x * 2)
# Merge dataframes
merged = pd.merge(df1, df2, on='id', how='inner')
# Export
df.to_csv('output.csv', index=False)
df.to_excel('output.xlsx', sheet_name='Data')
Niveau : Avancé
import requests
from bs4 import BeautifulSoup
import time
def scrape_page(url):
"""Scrape a single page."""
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status()
soup = BeautifulSoup(response.content, 'html.parser')
# Extract data
title = soup.find('h1', class_='title').text.strip()
price = soup.find('span', class_='price').text.strip()
description = soup.find('div', class_='description').text.strip()
return {
'title': title,
'price': price,
'description': description,
'url': url
}
except requests.RequestException as e:
print(f"Error scraping {url}: {e}")
return None
def scrape_multiple(urls, delay=1):
"""Scrape multiple pages with delay."""
results = []
for url in urls:
data = scrape_page(url)
if data:
results.append(data)
time.sleep(delay) # Be polite
return results
# Usage
urls = ['https://example.com/page1', 'https://example.com/page2']
data = scrape_multiple(urls)
df = pd.DataFrame(data)
df.to_csv('scraped_data.csv', index=False)
Niveau : Expert
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
require('dotenv').config();
const app = express();
// Middleware
app.use(helmet());
app.use(cors());
app.use(morgan('combined'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Error handling middleware
const errorHandler = (err, req, res, next) => {
console.error(err.stack);
res.status(err.status || 500).json({
error: {
message: err.message,
status: err.status || 500
}
});
};
// Validation middleware
const validateUser = (req, res, next) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({ error: 'Name and email required' });
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
return res.status(400).json({ error: 'Invalid email format' });
}
next();
};
// Routes
const usersRouter = require('./routes/users');
app.use('/api/users', usersRouter);
// Health check
app.get('/health', (req, res) => {
res.json({ status: 'healthy', timestamp: new Date().toISOString() });
});
// 404 handler
app.use((req, res) => {
res.status(404).json({ error: 'Route not found' });
});
// Error handler
app.use(errorHandler);
// Start server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
module.exports = app;
Niveau : Avancé
const fs = require('fs').promises;
const path = require('path');
// Read file
async function readFile(filePath) {
try {
const content = await fs.readFile(filePath, 'utf-8');
return content;
} catch (error) {
console.error(`Error reading file: ${error.message}`);
throw error;
}
}
// Write file
async function writeFile(filePath, data) {
try {
await fs.writeFile(filePath, data, 'utf-8');
console.log(`File written: ${filePath}`);
} catch (error) {
console.error(`Error writing file: ${error.message}`);
throw error;
}
}
// Read directory
async function listFiles(dirPath) {
try {
const files = await fs.readdir(dirPath);
return files;
} catch (error) {
console.error(`Error reading directory: ${error.message}`);
throw error;
}
}
// Create directory
async function createDir(dirPath) {
try {
await fs.mkdir(dirPath, { recursive: true });
console.log(`Directory created: ${dirPath}`);
} catch (error) {
console.error(`Error creating directory: ${error.message}`);
throw error;
}
}
// Copy file
async function copyFile(source, destination) {
try {
await fs.copyFile(source, destination);
console.log(`File copied: ${source} -> ${destination}`);
} catch (error) {
console.error(`Error copying file: ${error.message}`);
throw error;
}
}
// Delete file
async function deleteFile(filePath) {
try {
await fs.unlink(filePath);
console.log(`File deleted: ${filePath}`);
} catch (error) {
console.error(`Error deleting file: ${error.message}`);
throw error;
}
}
// Check if exists
async function exists(filePath) {
try {
await fs.access(filePath);
return true;
} catch {
return false;
}
}
// Get file stats
async function getStats(filePath) {
try {
const stats = await fs.stat(filePath);
return {
size: stats.size,
isFile: stats.isFile(),
isDirectory: stats.isDirectory(),
created: stats.birthtime,
modified: stats.mtime
};
} catch (error) {
console.error(`Error getting stats: ${error.message}`);
throw error;
}
}
Niveau : Expert
#!/bin/bash
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Logging
LOG_FILE="/var/log/system-check.log"
log_info() {
echo -e "${GREEN}[INFO]${NC} $*" | tee -a "$LOG_FILE"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $*" | tee -a "$LOG_FILE"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $*" | tee -a "$LOG_FILE"
}
# Check if running as root
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "This script must be run as root"
exit 1
fi
}
# Check disk space
check_disk_space() {
log_info "Checking disk space..."
df -h | awk 'NR>1 {
usage = int($5)
if (usage > 80) {
print "WARNING: " $6 " is " $5 " full"
}
}'
}
# Check memory
check_memory() {
log_info "Checking memory..."
free -h | awk '/^Mem:/ {
printf "Total: %s | Used: %s | Free: %s\n", $2, $3, $4
}'
}
# Check CPU load
check_cpu() {
log_info "Checking CPU load..."
uptime | awk '{
print "Load average: " $(NF-2) " " $(NF-1) " " $NF
}'
}
# Check running services
check_services() {
log_info "Checking critical services..."
services=("nginx" "mysql" "redis")
for service in "${services[@]}"; do
if systemctl is-active --quiet "$service"; then
log_info "$service is running"
else
log_warn "$service is NOT running"
fi
done
}
# Backup directory
backup_directory() {
local source="$1"
local dest="$2"
local timestamp=$(date +%Y%m%d_%H%M%S)
local backup_name="backup_${timestamp}.tar.gz"
log_info "Creating backup: $backup_name"
tar -czf "${dest}/${backup_name}" -C "$(dirname "$source")" "$(basename "$source")"
if [[ $? -eq 0 ]]; then
log_info "Backup created successfully"
else
log_error "Backup failed"
return 1
fi
}
# Cleanup old files
cleanup_old_files() {
local directory="$1"
local days="$2"
log_info "Cleaning up files older than $days days in $directory"
find "$directory" -type f -mtime +"$days" -delete
log_info "Cleanup completed"
}
# Main
main() {
check_root
log_info "Starting system check..."
check_disk_space
check_memory
check_cpu
check_services
log_info "System check completed"
}
main "$@"
Niveau : Expert
#Requires -Version 5.1
#Requires -RunAsAdministrator
[CmdletBinding()]
param()
$ErrorActionPreference = 'Stop'
$LogFile = "C:\Logs\system-check.log"
# Logging functions
function Write-Log {
param(
[Parameter(Mandatory=$true)]
[string]$Message,
[ValidateSet('INFO', 'WARN', 'ERROR')]
[string]$Level = 'INFO'
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "[$timestamp] [$Level] $Message"
switch ($Level) {
'INFO' { Write-Host $logMessage -ForegroundColor Green }
'WARN' { Write-Host $logMessage -ForegroundColor Yellow }
'ERROR' { Write-Host $logMessage -ForegroundColor Red }
}
Add-Content -Path $LogFile -Value $logMessage
}
# Check disk space
function Test-DiskSpace {
Write-Log "Checking disk space..."
Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Used -gt 0 } | ForEach-Object {
$percentUsed = [math]::Round(($_.Used / ($_.Used + $_.Free)) * 100, 2)
if ($percentUsed -gt 80) {
Write-Log "WARNING: Drive $($_.Name) is $percentUsed% full" -Level WARN
} else {
Write-Log "Drive $($_.Name): $percentUsed% used"
}
}
}
# Check services
function Test-Services {
Write-Log "Checking critical services..."
$services = @('W3SVC', 'MSSQLSERVER', 'WinRM')
foreach ($service in $services) {
$svc = Get-Service -Name $service -ErrorAction SilentlyContinue
if ($svc) {
if ($svc.Status -eq 'Running') {
Write-Log "$service is running"
} else {
Write-Log "$service is NOT running" -Level WARN
}
} else {
Write-Log "$service not found" -Level WARN
}
}
}
# Get system info
function Get-SystemInfo {
Write-Log "Gathering system information..."
$os = Get-CimInstance Win32_OperatingSystem
$cpu = Get-CimInstance Win32_Processor
$memory = Get-CimInstance Win32_PhysicalMemory | Measure-Object Capacity -Sum
$info = @{
ComputerName = $env:COMPUTERNAME
OS = $os.Caption
Version = $os.Version
Architecture = $os.OSArchitecture
LastBoot = $os.LastBootUpTime
CPU = $cpu.Name
TotalMemoryGB = [math]::Round($memory.Sum / 1GB, 2)
}
$info.GetEnumerator() | ForEach-Object {
Write-Log "$($_.Key): $($_.Value)"
}
return $info
}
# Backup directory
function Backup-Directory {
param(
[Parameter(Mandatory=$true)]
[string]$Source,
[Parameter(Mandatory=$true)]
[string]$Destination
)
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$backupName = "backup_$timestamp.zip"
$backupPath = Join-Path $Destination $backupName
Write-Log "Creating backup: $backupName"
try {
Compress-Archive -Path $Source -DestinationPath $backupPath -CompressionLevel Optimal
Write-Log "Backup created successfully: $backupPath"
}
catch {
Write-Log "Backup failed: $_" -Level ERROR
throw
}
}
# Cleanup old files
function Remove-OldFiles {
param(
[Parameter(Mandatory=$true)]
[string]$Path,
[Parameter(Mandatory=$true)]
[int]$DaysOld
)
Write-Log "Cleaning up files older than $DaysOld days in $Path"
$cutoffDate = (Get-Date).AddDays(-$DaysOld)
Get-ChildItem -Path $Path -Recurse -File | Where-Object {
$_.LastWriteTime -lt $cutoffDate
} | ForEach-Object {
Remove-Item $_.FullName -Force
Write-Log "Deleted: $($_.FullName)"
}
Write-Log "Cleanup completed"
}
# Main
try {
Write-Log "Starting system check..."
Test-DiskSpace
Test-Services
Get-SystemInfo
Write-Log "System check completed successfully"
}
catch {
Write-Log "System check failed: $_" -Level ERROR
exit 1
}
Niveau : Avancé
import sqlite3
from typing import List, Dict, Optional
class Database:
def __init__(self, db_path: str):
self.db_path = db_path
self.connection = None
def connect(self):
"""Connect to database."""
self.connection = sqlite3.connect(self.db_path)
self.connection.row_factory = sqlite3.Row # Return rows as dicts
def disconnect(self):
"""Close connection."""
if self.connection:
self.connection.close()
def __enter__(self):
self.connect()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.disconnect()
def execute(self, query: str, params: tuple = ()) -> sqlite3.Cursor:
"""Execute query."""
cursor = self.connection.cursor()
cursor.execute(query, params)
self.connection.commit()
return cursor
def fetchall(self, query: str, params: tuple = ()) -> List[Dict]:
"""Fetch all rows."""
cursor = self.execute(query, params)
return [dict(row) for row in cursor.fetchall()]
def fetchone(self, query: str, params: tuple = ()) -> Optional[Dict]:
"""Fetch single row."""
cursor = self.execute(query, params)
row = cursor.fetchone()
return dict(row) if row else None
def create_table(self):
"""Create users table."""
self.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
age INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
def insert_user(self, name: str, email: str, age: int) -> int:
"""Insert user."""
cursor = self.execute(
'INSERT INTO users (name, email, age) VALUES (?, ?, ?)',
(name, email, age)
)
return cursor.lastrowid
def get_user(self, user_id: int) -> Optional[Dict]:
"""Get user by ID."""
return self.fetchone('SELECT * FROM users WHERE id = ?', (user_id,))
def get_all_users(self) -> List[Dict]:
"""Get all users."""
return self.fetchall('SELECT * FROM users ORDER BY created_at DESC')
def update_user(self, user_id: int, name: str, email: str, age: int):
"""Update user."""
self.execute(
'UPDATE users SET name = ?, email = ?, age = ? WHERE id = ?',
(name, email, age, user_id)
)
def delete_user(self, user_id: int):
"""Delete user."""
self.execute('DELETE FROM users WHERE id = ?', (user_id,))
# Usage
with Database('mydb.sqlite') as db:
db.create_table()
user_id = db.insert_user('Alice', '[email protected]', 30)
user = db.get_user(user_id)
print(user)
Niveau : Expert
import re
from typing import Optional
def validate_email(email: str) -> bool:
"""Validate email format."""
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
return re.match(pattern, email) is not None
def sanitize_input(text: str) -> str:
"""Remove potentially dangerous characters."""
# Remove HTML tags
text = re.sub(r'<[^>]+>', '', text)
# Remove SQL injection attempts
text = re.sub(r"[';\"\\]", '', text)
return text.strip()
def validate_password(password: str) -> tuple[bool, str]:
"""Validate password strength."""
if len(password) < 8:
return False, "Password must be at least 8 characters"
if not re.search(r'[A-Z]', password):
return False, "Password must contain uppercase letter"
if not re.search(r'[a-z]', password):
return False, "Password must contain lowercase letter"
if not re.search(r'\d', password):
return False, "Password must contain a number"
if not re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
return False, "Password must contain special character"
return True, "Password is valid"
import os
from dotenv import load_dotenv
# Load .env file
load_dotenv()
# Access variables
API_KEY = os.getenv('API_KEY')
DATABASE_URL = os.getenv('DATABASE_URL')
DEBUG = os.getenv('DEBUG', 'False') == 'True'
if not API_KEY:
raise ValueError("API_KEY not found in environment")
// Node.js
require('dotenv').config();
const API_KEY = process.env.API_KEY;
const DATABASE_URL = process.env.DATABASE_URL;
const DEBUG = process.env.DEBUG === 'true';
if (!API_KEY) {
throw new Error('API_KEY not found in environment');
}
Ces skills évoluent constamment. Documente tes découvertes et nouveaux patterns.
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.
development
End-to-end Parallels smoke, upgrade, and rerun workflow for OpenClaw across macOS, Windows, and Linux guests. Use when Codex needs to run, rerun, debug, or interpret VM-based install, onboarding, gateway smoke tests, latest-release-to-main upgrade checks, fresh snapshot retests, or optional Discord roundtrip verification under Parallels.