Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:23:58 +08:00
commit 18c5d51e47
22 changed files with 5082 additions and 0 deletions

55
templates/basic-query.ts Normal file
View File

@@ -0,0 +1,55 @@
import { query } from "@anthropic-ai/claude-agent-sdk";
/**
* Basic Query Template
*
* Demonstrates:
* - Simple query execution
* - Model selection
* - Working directory
* - Basic message handling
*/
async function basicQuery() {
const response = query({
prompt: "Analyze the codebase and suggest improvements",
options: {
model: "claude-sonnet-4-5", // or "haiku", "opus"
workingDirectory: process.cwd(),
allowedTools: ["Read", "Grep", "Glob"]
}
});
// Process streaming messages
for await (const message of response) {
switch (message.type) {
case 'system':
if (message.subtype === 'init') {
console.log(`Session ID: ${message.session_id}`);
console.log(`Model: ${message.model}`);
}
break;
case 'assistant':
if (typeof message.content === 'string') {
console.log('Assistant:', message.content);
}
break;
case 'tool_call':
console.log(`Executing tool: ${message.tool_name}`);
break;
case 'tool_result':
console.log(`Tool ${message.tool_name} completed`);
break;
case 'error':
console.error('Error:', message.error.message);
break;
}
}
}
// Run
basicQuery().catch(console.error);

View File

@@ -0,0 +1,161 @@
import { query, createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";
/**
* Custom MCP Server Template
*
* Demonstrates:
* - Creating in-process MCP server
* - Defining tools with Zod schemas
* - Multiple tools in one server
* - Error handling in tools
*/
// Define a custom MCP server with multiple tools
const weatherServer = createSdkMcpServer({
name: "weather-service",
version: "1.0.0",
tools: [
tool(
"get_weather",
"Get current weather for a location",
{
location: z.string().describe("City name or coordinates"),
units: z.enum(["celsius", "fahrenheit"]).default("celsius")
},
async (args) => {
try {
// Simulate API call
const response = await fetch(
`https://api.weather.com/v1/current?location=${args.location}&units=${args.units}`
);
const data = await response.json();
return {
content: [{
type: "text",
text: `Temperature: ${data.temp}° ${args.units}\nConditions: ${data.conditions}\nHumidity: ${data.humidity}%`
}]
};
} catch (error) {
return {
content: [{
type: "text",
text: `Error fetching weather: ${error.message}`
}],
isError: true
};
}
}
),
tool(
"get_forecast",
"Get weather forecast for next 7 days",
{
location: z.string(),
days: z.number().min(1).max(7).default(7)
},
async (args) => {
// Simulated forecast data
return {
content: [{
type: "text",
text: `7-day forecast for ${args.location}: Mostly sunny with temperatures ranging from 15-25°C`
}]
};
}
)
]
});
// Database tools server
const databaseServer = createSdkMcpServer({
name: "database",
version: "1.0.0",
tools: [
tool(
"query_users",
"Query user records from the database",
{
email: z.string().email().optional(),
limit: z.number().min(1).max(100).default(10),
offset: z.number().min(0).default(0)
},
async (args) => {
// Simulated database query
const results = [
{ id: 1, email: "user1@example.com", name: "User 1" },
{ id: 2, email: "user2@example.com", name: "User 2" }
];
return {
content: [{
type: "text",
text: JSON.stringify(results, null, 2)
}]
};
}
),
tool(
"calculate",
"Perform mathematical calculations",
{
expression: z.string().describe("Mathematical expression to evaluate"),
precision: z.number().min(0).max(10).default(2)
},
async (args) => {
try {
// In production, use a proper math parser (e.g., mathjs)
const result = eval(args.expression);
const rounded = Number(result.toFixed(args.precision));
return {
content: [{
type: "text",
text: `Result: ${rounded}`
}]
};
} catch (error) {
return {
content: [{
type: "text",
text: `Invalid expression: ${error.message}`
}],
isError: true
};
}
}
)
]
});
// Use custom tools in query
async function useCustomTools() {
const response = query({
prompt: "What's the weather in San Francisco? Also query users with gmail addresses and calculate 15% tip on $85.50",
options: {
model: "claude-sonnet-4-5",
mcpServers: {
"weather-service": weatherServer,
"database": databaseServer
},
allowedTools: [
"mcp__weather-service__get_weather",
"mcp__weather-service__get_forecast",
"mcp__database__query_users",
"mcp__database__calculate"
]
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log('Assistant:', message.content);
} else if (message.type === 'tool_call') {
console.log(`\n🔧 ${message.tool_name}:`, message.input);
}
}
}
// Run
useCustomTools().catch(console.error);

283
templates/error-handling.ts Normal file
View File

@@ -0,0 +1,283 @@
import { query } from "@anthropic-ai/claude-agent-sdk";
/**
* Error Handling Template
*
* Demonstrates:
* - SDK error handling
* - Message-level error handling
* - Retry strategies
* - Graceful degradation
*/
// Example 1: Basic Error Handling
async function basicErrorHandling() {
try {
const response = query({
prompt: "Analyze and refactor code",
options: {
model: "claude-sonnet-4-5",
workingDirectory: "/path/to/project"
}
});
for await (const message of response) {
switch (message.type) {
case 'assistant':
console.log('Assistant:', message.content);
break;
case 'error':
console.error('Agent error:', message.error.message);
if (message.error.type === 'permission_denied') {
console.log('Permission denied for:', message.error.tool);
// Handle permission errors gracefully
}
break;
}
}
} catch (error) {
console.error('Fatal error:', error);
// Handle specific error codes
if (error.code === 'CLI_NOT_FOUND') {
console.error('Claude Code CLI not installed');
console.error('Install: npm install -g @anthropic-ai/claude-code');
} else if (error.code === 'AUTHENTICATION_FAILED') {
console.error('Invalid API key. Check ANTHROPIC_API_KEY');
} else if (error.code === 'RATE_LIMIT_EXCEEDED') {
console.error('Rate limit exceeded. Retry after delay.');
} else if (error.code === 'CONTEXT_LENGTH_EXCEEDED') {
console.error('Context too large. Use session compaction.');
}
}
}
// Example 2: Retry with Exponential Backoff
async function retryWithBackoff(
prompt: string,
maxRetries = 3,
baseDelay = 1000
): Promise<void> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = query({
prompt,
options: {
model: "claude-sonnet-4-5"
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
return; // Success, exit
} catch (error) {
if (error.code === 'RATE_LIMIT_EXCEEDED' && attempt < maxRetries - 1) {
const delay = baseDelay * Math.pow(2, attempt);
console.log(`Rate limited. Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else {
throw error; // Re-throw if not rate limit or final attempt
}
}
}
}
// Example 3: Graceful Degradation
async function gracefulDegradation(prompt: string) {
// Try with full capabilities first
try {
console.log('Attempting with Sonnet model...');
const response = query({
prompt,
options: {
model: "claude-sonnet-4-5",
allowedTools: ["Read", "Write", "Edit", "Bash", "Grep", "Glob"]
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
} catch (error) {
console.warn('Sonnet failed, falling back to Haiku...');
// Fallback to faster/cheaper model with limited tools
try {
const response = query({
prompt,
options: {
model: "haiku",
allowedTools: ["Read", "Grep", "Glob"] // Read-only
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
} catch (fallbackError) {
console.error('All attempts failed:', fallbackError);
throw fallbackError;
}
}
}
// Example 4: Comprehensive Error Handler
async function comprehensiveErrorHandling() {
const errors: Array<{ type: string; message: string; timestamp: Date }> = [];
try {
const response = query({
prompt: "Complex multi-step task",
options: {
model: "claude-sonnet-4-5",
permissionMode: "default"
}
});
for await (const message of response) {
switch (message.type) {
case 'assistant':
console.log('✅ Assistant:', message.content);
break;
case 'tool_call':
console.log(`🔧 Executing: ${message.tool_name}`);
break;
case 'tool_result':
console.log(`${message.tool_name} completed`);
break;
case 'error':
console.error('❌ Error:', message.error.message);
errors.push({
type: message.error.type,
message: message.error.message,
timestamp: new Date()
});
// Handle different error types
if (message.error.type === 'permission_denied') {
console.log('→ Permission was denied, continuing with limited access');
} else if (message.error.type === 'tool_execution_failed') {
console.log('→ Tool failed, attempting alternative approach');
}
break;
}
}
} catch (error) {
console.error('💥 Fatal error:', error);
// Log error details
errors.push({
type: error.code || 'UNKNOWN',
message: error.message,
timestamp: new Date()
});
// Specific handlers
if (error.code === 'AUTHENTICATION_FAILED') {
console.error('→ Check your ANTHROPIC_API_KEY environment variable');
console.error('→ Visit https://console.anthropic.com/ for API keys');
} else if (error.code === 'RATE_LIMIT_EXCEEDED') {
console.error('→ Rate limit exceeded');
console.error('→ Implement exponential backoff or reduce request frequency');
} else if (error.code === 'CONTEXT_LENGTH_EXCEEDED') {
console.error('→ Context too large');
console.error('→ Consider using session management or reducing prompt size');
} else if (error.code === 'CLI_NOT_FOUND') {
console.error('→ Claude Code CLI not found');
console.error('→ Install: npm install -g @anthropic-ai/claude-code');
}
throw error;
} finally {
// Always log error summary
if (errors.length > 0) {
console.log('\n\n=== Error Summary ===');
errors.forEach(err => {
console.log(`${err.timestamp.toISOString()} - ${err.type}: ${err.message}`);
});
}
}
}
// Example 5: Circuit Breaker Pattern
class CircuitBreaker {
private failures = 0;
private lastFailureTime?: Date;
private readonly threshold = 3;
private readonly resetTimeout = 60000; // 1 minute
async execute(fn: () => Promise<void>): Promise<void> {
// Check if circuit is open
if (this.isOpen()) {
throw new Error('Circuit breaker is OPEN. Too many failures.');
}
try {
await fn();
this.onSuccess();
} catch (error) {
this.onFailure();
throw error;
}
}
private isOpen(): boolean {
if (this.failures >= this.threshold) {
const now = new Date();
if (this.lastFailureTime &&
now.getTime() - this.lastFailureTime.getTime() < this.resetTimeout) {
return true;
}
// Reset after timeout
this.failures = 0;
}
return false;
}
private onSuccess() {
this.failures = 0;
this.lastFailureTime = undefined;
}
private onFailure() {
this.failures++;
this.lastFailureTime = new Date();
console.warn(`Circuit breaker: ${this.failures}/${this.threshold} failures`);
}
}
async function useCircuitBreaker() {
const breaker = new CircuitBreaker();
try {
await breaker.execute(async () => {
const response = query({
prompt: "Perform task",
options: { model: "sonnet" }
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
});
} catch (error) {
console.error('Circuit breaker prevented execution or task failed:', error);
}
}
// Run
comprehensiveErrorHandling().catch(console.error);

View File

@@ -0,0 +1,211 @@
import { query } from "@anthropic-ai/claude-agent-sdk";
/**
* Filesystem Settings Template
*
* Demonstrates:
* - Loading settings from user, project, local
* - Settings priority and merging
* - Isolated vs configured execution
* - Loading CLAUDE.md project instructions
*/
// Example 1: Load All Settings (Legacy Behavior)
async function loadAllSettings() {
const response = query({
prompt: "Build a new feature following project conventions",
options: {
model: "claude-sonnet-4-5",
settingSources: ["user", "project", "local"]
// Loads:
// 1. ~/.claude/settings.json (user)
// 2. .claude/settings.json (project)
// 3. .claude/settings.local.json (local overrides)
//
// Priority (highest first):
// 1. Programmatic options (this config)
// 2. Local settings
// 3. Project settings
// 4. User settings
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Example 2: Project Settings Only (CI/CD Pattern)
async function projectSettingsOnly() {
const response = query({
prompt: "Run automated code review",
options: {
model: "claude-sonnet-4-5",
settingSources: ["project"]
// Only .claude/settings.json
// Ignores user and local settings
// Ensures consistent behavior in CI/CD
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Example 3: No Filesystem Settings (Fully Isolated)
async function isolatedExecution() {
const response = query({
prompt: "Analyze this code snippet",
options: {
model: "claude-sonnet-4-5",
settingSources: [], // Empty = no filesystem settings
workingDirectory: "/tmp/sandbox",
allowedTools: ["Read", "Grep", "Glob"],
systemPrompt: "You are a code analyzer."
// Fully isolated, no filesystem dependencies
// Perfect for sandboxed/containerized environments
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Example 4: Hybrid Approach (Project + Programmatic)
async function hybridConfiguration() {
const response = query({
prompt: "Implement user authentication system",
options: {
model: "claude-sonnet-4-5",
settingSources: ["project"], // Load CLAUDE.md and project settings
systemPrompt: "Follow security best practices and company coding standards.",
agents: {
"security-checker": {
description: "Security validation specialist",
prompt: "Validate all security implementations against OWASP guidelines.",
tools: ["Read", "Grep"],
model: "sonnet"
}
},
allowedTools: ["Read", "Write", "Edit", "Grep", "Glob"]
// Project settings + programmatic overrides
// Programmatic settings always win
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Example 5: Loading CLAUDE.md Project Instructions
async function loadProjectInstructions() {
const response = query({
prompt: "Implement new feature according to project guidelines",
options: {
model: "claude-sonnet-4-5",
systemPrompt: {
type: 'preset',
preset: 'claude_code' // Required to use CLAUDE.md
},
settingSources: ["project"], // Reads CLAUDE.md from project directory
workingDirectory: process.cwd()
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Example 6: Environment-Specific Settings
async function environmentSpecificSettings(
environment: 'development' | 'staging' | 'production'
) {
let settingSources: Array<'user' | 'project' | 'local'>;
let permissionMode: 'default' | 'acceptEdits' | 'bypassPermissions';
switch (environment) {
case 'development':
settingSources = ["user", "project", "local"];
permissionMode = "acceptEdits";
break;
case 'staging':
settingSources = ["project"];
permissionMode = "default";
break;
case 'production':
settingSources = ["project"];
permissionMode = "default";
break;
}
const response = query({
prompt: "Deploy application",
options: {
model: "claude-sonnet-4-5",
settingSources,
permissionMode,
workingDirectory: process.cwd()
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Settings File Examples:
/**
* ~/.claude/settings.json (User Settings)
* {
* "model": "claude-sonnet-4-5",
* "allowedTools": ["Read", "Write", "Edit", "Bash", "Grep", "Glob"],
* "permissionMode": "default"
* }
*/
/**
* .claude/settings.json (Project Settings - version controlled)
* {
* "model": "claude-sonnet-4-5",
* "allowedTools": ["Read", "Write", "Edit", "Grep", "Glob"],
* "disallowedTools": ["Bash"],
* "agents": {
* "code-reviewer": {
* "description": "Review code for quality",
* "prompt": "You review code for best practices.",
* "tools": ["Read", "Grep"],
* "model": "haiku"
* }
* }
* }
*/
/**
* .claude/settings.local.json (Local Overrides - gitignored)
* {
* "permissionMode": "acceptEdits",
* "allowedTools": ["Read", "Write", "Edit", "Bash", "Grep", "Glob"]
* }
*/
// Run
hybridConfiguration().catch(console.error);

View File

@@ -0,0 +1,318 @@
import { query, createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";
/**
* Complete Multi-Agent Workflow Template
*
* Demonstrates:
* - Complex multi-agent orchestration
* - Custom tools for agents
* - Environment-based configuration
* - Production-ready error handling
* - Comprehensive monitoring
*/
// Custom tools for notification and logging
const appTools = createSdkMcpServer({
name: "app-services",
version: "1.0.0",
tools: [
tool(
"send_notification",
"Send notification to users or teams",
{
userId: z.string().optional(),
teamId: z.string().optional(),
message: z.string(),
priority: z.enum(["low", "medium", "high", "critical"]).default("medium")
},
async (args) => {
// Simulate notification service
console.log(`📧 Notification (${args.priority}): ${args.message}`);
return {
content: [{ type: "text", text: "Notification sent successfully" }]
};
}
),
tool(
"log_event",
"Log application events for monitoring",
{
event: z.string(),
data: z.record(z.any()).optional(),
severity: z.enum(["debug", "info", "warning", "error", "critical"]).default("info")
},
async (args) => {
console.log(`📝 [${args.severity.toUpperCase()}] ${args.event}:`, args.data || '');
return {
content: [{ type: "text", text: "Event logged" }]
};
}
),
tool(
"check_health",
"Check system health metrics",
{
service: z.string(),
metrics: z.array(z.enum(["cpu", "memory", "disk", "network"])).optional()
},
async (args) => {
// Simulate health check
const health = {
service: args.service,
status: "healthy",
uptime: "99.9%",
responseTime: "50ms"
};
return {
content: [{ type: "text", text: JSON.stringify(health, null, 2) }]
};
}
)
]
});
// Main DevOps agent orchestrator
async function runDevOpsAgent(task: string) {
console.log(`🚀 Starting DevOps Agent for: ${task}\n`);
const response = query({
prompt: task,
options: {
model: "claude-sonnet-4-5",
workingDirectory: process.cwd(),
systemPrompt: `You are a DevOps automation expert and orchestrator.
Your responsibilities:
- Monitor system health
- Deploy applications safely
- Handle incidents and alerts
- Maintain infrastructure
- Coordinate specialized agents
Always log your actions and notify relevant stakeholders.
Follow the principle of least privilege for tool access.`,
// Custom tools
mcpServers: {
"app-services": appTools
},
// Specialized agents for different tasks
agents: {
"deployment-agent": {
description: "Handles application deployments, rollbacks, and release management",
prompt: `You manage deployments.
Deployment checklist:
1. Verify all tests pass
2. Deploy to staging first
3. Run smoke tests
4. Deploy to production
5. Create rollback plan
6. Monitor for issues
Always notify stakeholders of deployment status.`,
tools: [
"Bash",
"Read",
"mcp__app-services__log_event",
"mcp__app-services__send_notification",
"mcp__app-services__check_health"
],
model: "sonnet"
},
"incident-responder": {
description: "Responds to production incidents, outages, and performance issues",
prompt: `You handle incidents.
Incident response process:
1. Assess impact (users affected, services down)
2. Identify root cause
3. Implement immediate fixes
4. Communicate status updates
5. Document incident for post-mortem
Work quickly but carefully. User experience is critical.`,
tools: [
"Bash",
"Read",
"Grep",
"mcp__app-services__log_event",
"mcp__app-services__send_notification",
"mcp__app-services__check_health"
],
model: "sonnet"
},
"monitoring-agent": {
description: "Monitors system metrics, health checks, and alerts on issues",
prompt: `You monitor systems.
Monitoring tasks:
- Check application metrics
- Analyze error rates
- Monitor response times
- Verify system health
- Alert on anomalies
Report issues immediately.`,
tools: [
"Bash",
"Read",
"mcp__app-services__log_event",
"mcp__app-services__send_notification",
"mcp__app-services__check_health"
],
model: "haiku" // Fast, cost-effective for monitoring
},
"security-agent": {
description: "Performs security audits, vulnerability scanning, and compliance checks",
prompt: `You ensure security.
Security checks:
- Scan for exposed secrets
- Check dependency vulnerabilities
- Verify access controls
- Validate compliance (OWASP, SOC2)
- Audit infrastructure config
Block deployments if critical issues found.`,
tools: [
"Bash",
"Read",
"Grep",
"mcp__app-services__log_event",
"mcp__app-services__send_notification"
],
model: "sonnet"
},
"performance-agent": {
description: "Analyzes performance metrics, identifies bottlenecks, and suggests optimizations",
prompt: `You optimize performance.
Performance analysis:
- Database query times
- API response times
- Memory/CPU usage
- Network latency
- Caching effectiveness
Identify bottlenecks and optimization opportunities.`,
tools: [
"Bash",
"Read",
"Grep",
"mcp__app-services__log_event",
"mcp__app-services__check_health"
],
model: "sonnet"
}
},
// Permission control
permissionMode: "default",
canUseTool: async (toolName, input) => {
// Log all tool usage
console.log(`🔧 [${new Date().toISOString()}] ${toolName}`);
// Prevent destructive operations
if (toolName === 'Bash') {
const dangerous = ['rm -rf', 'dd if=', 'mkfs', '> /dev/', 'shutdown'];
if (dangerous.some(pattern => input.command.includes(pattern))) {
return {
behavior: "deny",
message: `Destructive command blocked: ${input.command}`
};
}
}
// Require confirmation for production deployments
if (input.command?.includes('deploy --production') ||
input.command?.includes('kubectl apply -n production')) {
return {
behavior: "ask",
message: `⚠️ PRODUCTION DEPLOYMENT: ${input.command}\n\nConfirm?`
};
}
return { behavior: "allow" };
}
}
});
// Track execution
const agentsUsed = new Set<string>();
const toolsExecuted: string[] = [];
let sessionId: string | undefined;
try {
for await (const message of response) {
switch (message.type) {
case 'system':
if (message.subtype === 'init') {
sessionId = message.session_id;
console.log(`✨ Session: ${sessionId}\n`);
}
break;
case 'assistant':
console.log('📋 Orchestrator:', message.content);
break;
case 'tool_call':
console.log(`\n🔧 Executing: ${message.tool_name}`);
toolsExecuted.push(message.tool_name);
break;
case 'tool_result':
console.log(`${message.tool_name} completed`);
break;
case 'error':
console.error('❌ Error:', message.error.message);
break;
}
}
console.log(`\n\n✅ Task completed successfully`);
console.log(`Session ID: ${sessionId}`);
console.log(`Tools executed: ${toolsExecuted.length}`);
} catch (error) {
console.error('💥 Fatal error:', error);
throw error;
}
}
// Usage examples
async function main() {
try {
// Example 1: Deployment
await runDevOpsAgent(
"Deploy version 2.5.0 to production with full validation and monitoring"
);
// Example 2: Incident Response
// await runDevOpsAgent(
// "API response time increased by 300% in last hour. Investigate, identify root cause, and fix"
// );
// Example 3: Security Audit
// await runDevOpsAgent(
// "Perform comprehensive security audit of the application and infrastructure"
// );
// Example 4: Performance Optimization
// await runDevOpsAgent(
// "Analyze application performance and implement optimizations for the checkout flow"
// );
} catch (error) {
console.error('Workflow failed:', error);
process.exit(1);
}
}
main();

29
templates/package.json Normal file
View File

@@ -0,0 +1,29 @@
{
"name": "claude-agent-sdk-examples",
"version": "1.0.0",
"description": "Claude Agent SDK usage examples",
"type": "module",
"scripts": {
"basic-query": "tsx templates/basic-query.ts",
"query-with-tools": "tsx templates/query-with-tools.ts",
"custom-mcp-server": "tsx templates/custom-mcp-server.ts",
"subagents": "tsx templates/subagents-orchestration.ts",
"sessions": "tsx templates/session-management.ts",
"permissions": "tsx templates/permission-control.ts",
"settings": "tsx templates/filesystem-settings.ts",
"errors": "tsx templates/error-handling.ts",
"workflow": "tsx templates/multi-agent-workflow.ts"
},
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.1.0",
"zod": "^3.23.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"tsx": "^4.0.0",
"typescript": "^5.3.0"
},
"engines": {
"node": ">=18.0.0"
}
}

View File

@@ -0,0 +1,211 @@
import { query } from "@anthropic-ai/claude-agent-sdk";
/**
* Permission Control Template
*
* Demonstrates:
* - Permission modes (default, acceptEdits, bypassPermissions)
* - Custom canUseTool callback
* - Safety controls for dangerous operations
* - Conditional tool approval
*/
// Example 1: Accept Edits Mode (auto-approve file edits)
async function autoApproveEdits() {
const response = query({
prompt: "Refactor the user service to use async/await throughout",
options: {
model: "claude-sonnet-4-5",
workingDirectory: "/path/to/project",
permissionMode: "acceptEdits" // Auto-approve file edits
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Example 2: Bypass Permissions (use with caution!)
async function bypassAllPermissions() {
const response = query({
prompt: "Run comprehensive test suite and fix all failures",
options: {
model: "claude-sonnet-4-5",
permissionMode: "bypassPermissions"
// ⚠️ CAUTION: Skips ALL permission checks
// Use only in trusted, sandboxed environments
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Example 3: Custom Permission Logic
async function customPermissions() {
const response = query({
prompt: "Deploy the application to production",
options: {
model: "claude-sonnet-4-5",
permissionMode: "default",
canUseTool: async (toolName, input) => {
// Allow read-only operations
if (['Read', 'Grep', 'Glob'].includes(toolName)) {
return { behavior: "allow" };
}
// Deny destructive bash commands
if (toolName === 'Bash') {
const dangerous = [
'rm -rf',
'dd if=',
'mkfs',
'> /dev/',
'shutdown',
'reboot'
];
if (dangerous.some(pattern => input.command.includes(pattern))) {
return {
behavior: "deny",
message: `Destructive command blocked: ${input.command}`
};
}
}
// Require confirmation for deployments
if (input.command?.includes('deploy') ||
input.command?.includes('kubectl apply') ||
input.command?.includes('terraform apply')) {
return {
behavior: "ask",
message: `Confirm deployment: ${input.command}?`
};
}
// Require confirmation for file writes to sensitive paths
if (toolName === 'Write' || toolName === 'Edit') {
const sensitivePaths = [
'/etc/',
'/root/',
'.env',
'credentials',
'secrets',
'config/production'
];
if (sensitivePaths.some(path => input.file_path?.includes(path))) {
return {
behavior: "ask",
message: `Modify sensitive file ${input.file_path}?`
};
}
}
// Allow by default
return { behavior: "allow" };
}
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Example 4: Environment-Based Permissions
async function environmentBasedPermissions(environment: 'development' | 'staging' | 'production') {
const response = query({
prompt: "Deploy the latest changes",
options: {
model: "claude-sonnet-4-5",
permissionMode: "default",
canUseTool: async (toolName, input) => {
// Production requires approval for everything
if (environment === 'production') {
if (toolName === 'Bash' || toolName === 'Write' || toolName === 'Edit') {
return {
behavior: "ask",
message: `PRODUCTION: Approve ${toolName}?`
};
}
}
// Staging auto-approves edits
if (environment === 'staging') {
if (toolName === 'Write' || toolName === 'Edit') {
return { behavior: "allow" };
}
}
// Development bypasses most checks
if (environment === 'development') {
return { behavior: "allow" };
}
return { behavior: "allow" };
}
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Example 5: Logging & Auditing
async function loggingPermissions() {
const toolLog: Array<{ tool: string; input: any; decision: string; timestamp: Date }> = [];
const response = query({
prompt: "Implement new feature X",
options: {
model: "claude-sonnet-4-5",
permissionMode: "default",
canUseTool: async (toolName, input) => {
// Log all tool usage
console.log(`[${new Date().toISOString()}] Tool requested: ${toolName}`);
const decision = { behavior: "allow" as const };
// Audit log
toolLog.push({
tool: toolName,
input,
decision: decision.behavior,
timestamp: new Date()
});
// Could also send to external logging service
// await logToDatabase(toolName, input, decision);
return decision;
}
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
// Print audit log
console.log('\n\n=== Audit Log ===');
toolLog.forEach(entry => {
console.log(`${entry.timestamp.toISOString()} - ${entry.tool} - ${entry.decision}`);
});
}
// Run
customPermissions().catch(console.error);

View File

@@ -0,0 +1,54 @@
import { query } from "@anthropic-ai/claude-agent-sdk";
/**
* Query with Tool Control Template
*
* Demonstrates:
* - Allowing/disallowing tools
* - System prompts
* - Tool execution monitoring
*/
async function queryWithTools() {
const response = query({
prompt: "Review the authentication module for security issues and fix any vulnerabilities",
options: {
model: "claude-sonnet-4-5",
workingDirectory: "/path/to/project",
systemPrompt: `You are a security-focused code reviewer.
Analyze code for:
- SQL injection vulnerabilities
- XSS vulnerabilities
- Authentication bypass issues
- Insecure direct object references
- Security misconfiguration
Provide detailed recommendations and fix critical issues.`,
// Allow reading and modification, but not bash execution
allowedTools: ["Read", "Grep", "Glob", "Write", "Edit"],
disallowedTools: ["Bash"]
}
});
// Track tool usage
const toolsUsed = new Set<string>();
for await (const message of response) {
if (message.type === 'assistant') {
console.log('\nAssistant:', message.content);
} else if (message.type === 'tool_call') {
console.log(`\n🔧 Executing: ${message.tool_name}`);
console.log(`Input:`, JSON.stringify(message.input, null, 2));
toolsUsed.add(message.tool_name);
} else if (message.type === 'tool_result') {
console.log(`${message.tool_name} completed`);
}
}
console.log(`\n\nTools used: ${Array.from(toolsUsed).join(', ')}`);
}
// Run
queryWithTools().catch(console.error);

View File

@@ -0,0 +1,151 @@
import { query } from "@anthropic-ai/claude-agent-sdk";
/**
* Session Management Template
*
* Demonstrates:
* - Starting sessions
* - Resuming sessions
* - Forking sessions (alternative paths)
* - Session lifecycle management
*/
// Start a new session
async function startSession(prompt: string): Promise<string> {
let sessionId: string | undefined;
const response = query({
prompt,
options: {
model: "claude-sonnet-4-5"
}
});
for await (const message of response) {
if (message.type === 'system' && message.subtype === 'init') {
sessionId = message.session_id;
console.log(`✨ Session started: ${sessionId}`);
} else if (message.type === 'assistant') {
console.log('Assistant:', message.content);
}
}
if (!sessionId) {
throw new Error('Failed to start session');
}
return sessionId;
}
// Resume an existing session
async function resumeSession(sessionId: string, prompt: string): Promise<void> {
const response = query({
prompt,
options: {
resume: sessionId,
model: "claude-sonnet-4-5"
}
});
console.log(`\n↪ Resuming session: ${sessionId}`);
for await (const message of response) {
if (message.type === 'assistant') {
console.log('Assistant:', message.content);
}
}
}
// Fork a session (explore alternative path)
async function forkSession(sessionId: string, prompt: string): Promise<void> {
const response = query({
prompt,
options: {
resume: sessionId,
forkSession: true, // Creates new branch
model: "claude-sonnet-4-5"
}
});
console.log(`\n🔀 Forking session: ${sessionId}`);
for await (const message of response) {
if (message.type === 'system' && message.subtype === 'init') {
console.log(`New session ID: ${message.session_id}`);
} else if (message.type === 'assistant') {
console.log('Assistant:', message.content);
}
}
}
// Pattern 1: Sequential Development
async function sequentialDevelopment() {
console.log("🚀 Sequential Development Pattern\n");
// Step 1: Initial implementation
let session = await startSession("Create a user authentication system with JWT");
// Step 2: Add feature
await resumeSession(session, "Add OAuth 2.0 support (Google and GitHub)");
// Step 3: Add tests
await resumeSession(session, "Write comprehensive integration tests");
// Step 4: Deploy
await resumeSession(session, "Deploy to production with monitoring");
console.log("\n✅ Sequential development complete");
}
// Pattern 2: Exploration & Decision
async function explorationAndDecision() {
console.log("🔍 Exploration & Decision Pattern\n");
// Start main conversation
let mainSession = await startSession("Design a payment processing system");
// Explore option A
console.log("\n--- Option A: Stripe ---");
await forkSession(mainSession, "Implement using Stripe API");
// Explore option B
console.log("\n--- Option B: PayPal ---");
await forkSession(mainSession, "Implement using PayPal API");
// After decision, continue with chosen approach
console.log("\n--- Chosen: Stripe ---");
await resumeSession(mainSession, "Implement the Stripe integration with webhooks");
console.log("\n✅ Exploration complete");
}
// Pattern 3: Multi-User Collaboration
async function multiUserCollaboration() {
console.log("👥 Multi-User Collaboration Pattern\n");
// Developer A starts work
let sessionA = await startSession("Implement user profile page with avatar, bio, and settings");
// Developer B forks for different feature
await forkSession(sessionA, "Add real-time notifications system with WebSockets");
// Developer C forks for another feature
await forkSession(sessionA, "Implement search functionality with filters and sorting");
// All developers can work independently without interfering
console.log("\n✅ Multi-user collaboration setup complete");
}
// Run examples
async function main() {
try {
// Choose one pattern to run
await sequentialDevelopment();
// await explorationAndDecision();
// await multiUserCollaboration();
} catch (error) {
console.error('Error:', error);
}
}
main();

View File

@@ -0,0 +1,166 @@
import { query } from "@anthropic-ai/claude-agent-sdk";
/**
* Subagent Orchestration Template
*
* Demonstrates:
* - Defining specialized subagents
* - Different models for different agents
* - Tool restrictions per agent
* - Multi-agent workflows
*/
async function deployWithAgents(version: string) {
const response = query({
prompt: `Deploy version ${version} to production with full validation`,
options: {
model: "claude-sonnet-4-5",
workingDirectory: process.cwd(),
systemPrompt: `You are a DevOps orchestrator.
Coordinate specialized agents to:
1. Run tests (test-runner agent)
2. Check security (security-checker agent)
3. Deploy application (deployer agent)
4. Monitor systems (monitoring-agent agent)
Ensure all validation passes before deployment.`,
agents: {
"test-runner": {
description: "Run automated test suites and verify coverage",
prompt: `You run tests.
Execute test commands, parse results, report coverage.
FAIL the deployment if any tests fail.
Report clear error messages for failures.`,
tools: ["Bash", "Read", "Grep"],
model: "haiku" // Fast, cost-effective for testing
},
"security-checker": {
description: "Security audits and vulnerability scanning",
prompt: `You check security.
Scan for:
- Exposed secrets or API keys
- Outdated dependencies
- Incorrect file permissions
- OWASP compliance issues
Verify all security checks pass before deployment.`,
tools: ["Read", "Grep", "Bash"],
model: "sonnet" // Balance for security analysis
},
"deployer": {
description: "Application deployment and rollbacks",
prompt: `You deploy applications.
Deployment process:
1. Deploy to staging environment
2. Verify health checks pass
3. Deploy to production
4. Create rollback plan
ALWAYS have a rollback ready.`,
tools: ["Bash", "Read"],
model: "sonnet" // Reliable for critical operations
},
"monitoring-agent": {
description: "System monitoring and alerting",
prompt: `You monitor systems.
Check:
- Application metrics
- Error rates
- Response times
- System health
Alert on issues immediately.`,
tools: ["Bash", "Read"],
model: "haiku" // Fast monitoring checks
}
}
}
});
// Track which agents were used
const agentsUsed = new Set<string>();
for await (const message of response) {
if (message.type === 'assistant') {
console.log('\n📋 Orchestrator:', message.content);
} else if (message.type === 'tool_call') {
console.log(`\n🔧 Tool: ${message.tool_name}`);
}
}
}
// Example: Complex DevOps workflow
async function complexWorkflow() {
const response = query({
prompt: "API response time increased by 300% in last hour. Investigate and fix",
options: {
model: "claude-sonnet-4-5",
systemPrompt: "You coordinate incident response across specialized teams.",
agents: {
"incident-responder": {
description: "Diagnose and respond to production incidents",
prompt: `You handle incidents.
Steps:
1. Assess impact (users affected, services down)
2. Identify root cause
3. Implement immediate fixes
4. Communicate status updates
Work with monitoring and deployment agents.`,
tools: ["Bash", "Read", "Grep"],
model: "sonnet"
},
"performance-analyst": {
description: "Analyze performance metrics and bottlenecks",
prompt: `You analyze performance.
Investigate:
- Database query times
- API response times
- Memory/CPU usage
- Network latency
Identify bottlenecks and optimization opportunities.`,
tools: ["Bash", "Read", "Grep"],
model: "sonnet"
},
"fix-implementer": {
description: "Implement performance fixes and optimizations",
prompt: `You implement fixes.
Apply optimizations:
- Database query optimization
- Caching improvements
- Code refactoring
- Infrastructure scaling
Test fixes before deploying.`,
tools: ["Read", "Edit", "Bash"],
model: "sonnet"
}
}
}
});
for await (const message of response) {
if (message.type === 'assistant') {
console.log(message.content);
}
}
}
// Run
deployWithAgents("2.5.0").catch(console.error);

22
templates/tsconfig.json Normal file
View File

@@ -0,0 +1,22 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"lib": ["ES2022"],
"moduleResolution": "node",
"esModuleInterop": true,
"skipLibCheck": true,
"strict": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./",
"types": ["node"]
},
"include": ["**/*.ts"],
"exclude": ["node_modules", "dist"]
}