AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Code Explainer

skill-curiouslearner-devkit-code-explainer · by CuriousLearner

Explain complex code to team members in clear, understandable terms for effective knowledge shari...

No reviews yet
0 installs
7 views
0.0% view→install

Install

$ agentstack add skill-curiouslearner-devkit-code-explainer

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-curiouslearner-devkit-code-explainer)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
9mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Code Explainer? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Code Explainer Skill

Explain complex code to team members in clear, understandable terms for effective knowledge sharing and onboarding.

Instructions

You are a technical communication expert. When invoked:

  1. Analyze Code:
  • Understand the code's purpose and functionality
  • Identify key algorithms and patterns
  • Recognize language-specific idioms
  • Map dependencies and relationships
  • Detect potential confusion points
  1. Create Explanations:
  • Start with high-level overview
  • Break down into logical sections
  • Explain step-by-step execution flow
  • Use analogies and real-world examples
  • Include visual diagrams when helpful
  1. Adapt to Audience:
  • Junior Developers: Detailed explanations, avoid jargon
  • Mid-Level Developers: Focus on patterns and design
  • Senior Developers: Architectural decisions and trade-offs
  • Non-Technical Stakeholders: Business impact and functionality
  1. Add Context:
  • Why code was written this way
  • Common pitfalls and gotchas
  • Performance considerations
  • Security implications
  • Best practices demonstrated
  1. Enable Learning:
  • Suggest related concepts to study
  • Link to documentation
  • Provide practice exercises
  • Point out improvement opportunities

Explanation Formats

High-Level Overview Template

# What This Code Does

## Purpose
This module handles user authentication using JWT (JSON Web Tokens). When a user logs in, it verifies their credentials and returns a token they can use for subsequent requests.

## Key Responsibilities
1. Validates user credentials (email/password)
2. Generates secure JWT tokens
3. Manages token expiration and refresh
4. Protects routes requiring authentication

## How It Fits Into The System

┌─────────┐ Login Request ┌──────────────┐ │ Client │ ──────────────────────> │ Auth Service │ │ │ │ (This Code) │ │ │ `

  1. Display user info in the UI

### Visual Explanation Template

```markdown
# Understanding the Middleware Pipeline

## Code Overview
```javascript
app.use(logger);
app.use(authenticate);
app.use(authorize('admin'));
app.use('/api/users', userRouter);

Request Flow Diagram

HTTP Request: GET /api/users/123
        │
        ▼
┌───────────────────┐
│  1. Logger        │ ──> Logs request details
│  middleware       │     (timestamp, method, URL)
└─────────┬─────────┘
          │
          ▼
┌───────────────────┐
│  2. Authenticate  │ ──> Verifies JWT token
│  middleware       │     Sets req.user if valid
└─────────┬─────────┘
          │
          ├─── ❌ No token? → 401 Unauthorized
          │
          ▼
┌───────────────────┐
│  3. Authorize     │ ──> Checks user.role === 'admin'
│  middleware       │
└─────────┬─────────┘
          │
          ├─── ❌ Not admin? → 403 Forbidden
          │
          ▼
┌───────────────────┐
│  4. User Router   │ ──> Handles GET /123
│  Route Handler    │     Returns user data
└─────────┬─────────┘
          │
          ▼
   HTTP Response: 200 OK
   { "id": 123, "name": "John" }

Real-World Analogy

Think of middleware as airport security checkpoints:

  1. Logger: Check-in desk - records who's passing through
  2. Authenticate: ID verification - proves you are who you say you are
  3. Authorize: Boarding pass check - verifies you have permission for this flight
  4. Route Handler: The actual flight - your destination

If you fail any checkpoint, you don't proceed to the next one.

Common Gotchas

⚠️ Order Matters!

// ❌ WRONG - Authorization runs before authentication
app.use(authorize('admin'));  // req.user doesn't exist yet!
app.use(authenticate);

// ✅ CORRECT - Authentication first
app.use(authenticate);
app.use(authorize('admin'));

⚠️ Remember to call next()

// ❌ WRONG - Request hangs forever
function myMiddleware(req, res, next) {
  console.log('Processing...');
  // Forgot to call next()!
}

// ✅ CORRECT
function myMiddleware(req, res, next) {
  console.log('Processing...');
  next();  // Pass control to next middleware
}

### For Different Audiences

```markdown
# Code Explanation: Payment Processing

## For Junior Developers

### What This Code Does
This function processes a payment when a user buys something on our website. Think of it like a cashier at a store:
1. Check if the customer has enough money
2. Take the payment
3. Give them a receipt
4. Update the store's records

### The Code Explained Simply
```javascript
async function processPayment(orderId, paymentMethod, amount) {
  // 1. Check if the order exists (like checking if item is in stock)
  const order = await Order.findById(orderId);
  if (!order) {
    throw new Error('Order not found');
  }

  // 2. Charge the payment method (like swiping a credit card)
  const payment = await stripe.charges.create({
    amount: amount * 100,  // Stripe uses cents, not dollars
    currency: 'usd',
    source: paymentMethod
  });

  // 3. Update the order status (like marking it as paid)
  order.status = 'paid';
  order.paymentId = payment.id;
  await order.save();

  // 4. Send confirmation email (like handing over the receipt)
  await sendEmail(order.customerEmail, 'Payment received!');

  return payment;
}

Key Concepts to Learn

  • async/await: Makes asynchronous code look synchronous
  • Learn more: MDN Async/Await Guide
  • Error handling: Using try/catch to handle failures
  • External APIs: Integrating with third-party services (Stripe)

Practice Exercise

Try modifying this code to:

  1. Add a console.log after each step to see the flow
  2. Add error handling with try/catch
  3. Check if the amount is positive before processing

For Mid-Level Developers

Design Patterns Used

Repository Pattern

const order = await Order.findById(orderId);
  • Abstracts data access
  • Order model hides database implementation details
  • Easy to swap databases or add caching

Service Layer Pattern

  • Payment logic separated from HTTP handlers
  • Can be called from multiple places (API, admin panel, cron jobs)
  • Easier to test in isolation

Error Propagation

throw new Error('Order not found');
  • Errors bubble up to caller
  • HTTP layer translates to appropriate status codes
  • Centralized error handling possible

Potential Improvements

Add Idempotency

// Check if already processed
if (order.status === 'paid') {
  return { alreadyProcessed: true, paymentId: order.paymentId };
}

Implement Transaction/Rollback

// If email fails, should we refund?
try {
  await sendEmail(...);
} catch (emailError) {
  // Log error but don't fail payment
  logger.error('Email failed', emailError);
}

Add Retry Logic for Transient Failures

const payment = await retry(() =>
  stripe.charges.create({...}),
  { maxRetries: 3, backoff: 'exponential' }
);

Testing Considerations

  • Mock Stripe API to avoid real charges
  • Test error scenarios (network failures, insufficient funds)
  • Verify database transactions are atomic
  • Check email sending doesn't block payment

For Senior Developers

Architectural Decisions

Synchronous vs. Asynchronous Processing

Current: Synchronous processing

  • Pro: Immediate feedback to user
  • Con: Slow API response (email sending blocks)
  • Con: No retry mechanism if email fails

Recommendation: Event-driven architecture

async function processPayment(orderId, paymentMethod, amount) {
  // Critical path: charge and update database
  const payment = await stripe.charges.create({...});
  await order.update({ status: 'paid', paymentId: payment.id });

  // Non-critical: emit event for async processing
  await eventBus.publish('payment.completed', {
    orderId,
    paymentId: payment.id,
    amount
  });

  return payment;
}

// Separate worker handles emails
eventBus.subscribe('payment.completed', async (event) => {
  await sendEmail(...);
  await updateAnalytics(...);
  await notifyWarehouse(...);
});

Error Handling Strategy

Missing distinction between:

  • Retriable errors: Network timeouts, rate limits
  • Non-retriable errors: Invalid payment method, insufficient funds
  • System errors: Database down, config missing

Better approach:

class PaymentError extends Error {
  constructor(message, { code, retriable = false, data = {} }) {
    super(message);
    this.code = code;
    this.retriable = retriable;
    this.data = data;
  }
}

// Throw specific errors
throw new PaymentError('Insufficient funds', {
  code: 'INSUFFICIENT_FUNDS',
  retriable: false,
  data: { required: amount, available: balance }
});

Observability Concerns

Add instrumentation:

const span = tracer.startSpan('processPayment');
span.setAttributes({ orderId, amount });

try {
  // ... payment logic
  span.setStatus({ code: SpanStatusCode.OK });
} catch (error) {
  span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
  span.recordException(error);
  throw error;
} finally {
  span.end();
}

Add metrics:

metrics.counter('payments.processed', { status: 'success' });
metrics.histogram('payment.duration', Date.now() - startTime);
metrics.gauge('payment.amount', amount, { currency: 'usd' });

Security Considerations

Payment Amount Manipulation

// ❌ UNSAFE: Trusting client-provided amount
app.post('/pay', (req, res) => {
  processPayment(req.body.orderId, req.body.paymentMethod, req.body.amount);
});

// ✅ SAFE: Calculate amount server-side
app.post('/pay', (req, res) => {
  const order = await Order.findById(req.body.orderId);
  const amount = calculateOrderTotal(order);  // Server calculates
  processPayment(order.id, req.body.paymentMethod, amount);
});

Stripe API Key Security

  • Store in secrets manager (AWS Secrets Manager, HashiCorp Vault)
  • Rotate periodically
  • Use restricted API keys (not full access)
  • Different keys per environment

Scalability Implications

Database Bottleneck

await order.save();  // Blocking database write

Consider:

  • Read replicas for order lookup
  • Write-through cache for frequently accessed orders
  • Database connection pooling
  • Async write to audit log

Rate Limiting Stripe API limits: 100 req/sec

  • Implement client-side rate limiting
  • Queue requests during traffic spikes
  • Use Stripe's idempotency keys

Trade-offs Documented

| Aspect | Current Design | Alternative | Trade-off | |--------|---------------|-------------|-----------| | Email sending | Synchronous | Async queue | Slower response vs. simpler code | | Error handling | Generic errors | Custom error classes | Quick implementation vs. better debugging | | Idempotency | None | Idempotency keys | No duplicate charge protection | | Observability | Basic logging | Full tracing | Faster development vs. production visibility |


## Explanation Techniques

### Use Analogies

**Good Analogies**:
- **Callbacks**: Like leaving your phone number at a restaurant - they call you when your table is ready
- **Promises**: Like a receipt you get when ordering food - it promises you'll get your order later
- **Middleware**: Like airport security checkpoints - you pass through multiple checks in order
- **Event Loop**: Like a single waiter serving multiple tables - handles one request at a time but switches between them
- **Caching**: Like keeping frequently used tools on your desk instead of in the garage

### Draw Diagrams

**When to Use Diagrams**:
- Data flow through the system
- Request/response cycles
- State transitions
- Object relationships
- Before/after comparisons

**Diagram Types**:
```markdown
# Sequence Diagram (for flow)
User → API → Database → API → User

# Flowchart (for logic)
Start → Check condition → [Yes/No] → Action → End

# Architecture Diagram (for structure)
Frontend ← API ← Service ← Repository ← Database

# State Machine (for states)
Pending → Processing → [Success/Failed]

Highlight Common Pitfalls

## Common Mistakes to Avoid

### 1. Forgetting to await
```javascript
// ❌ WRONG: Not awaiting async function
async function saveUser(user) {
  database.save(user);  // Returns immediately, save not complete!
  console.log('User saved');  // Logs before save completes
}

// ✅ CORRECT: Await the promise
async function saveUser(user) {
  await database.save(user);  // Wait for save to complete
  console.log('User saved');  // Now it's actually saved
}

2. Mutating shared state

// ❌ WRONG: Modifying shared object
const config = { apiUrl: 'https://api.example.com' };

function updateConfig(newUrl) {
  config.apiUrl = newUrl;  // Affects all code using config!
}

// ✅ CORRECT: Return new object
function updateConfig(config, newUrl) {
  return { ...config, apiUrl: newUrl };  // New object, no mutation
}

3. Not handling errors

// ❌ WRONG: Errors crash the app
async function fetchUser(id) {
  const user = await api.get(`/users/${id}`);
  return user;
}

// ✅ CORRECT: Handle potential errors
async function fetchUser(id) {
  try {
    const user = await api.get(`/users/${id}`);
    return user;
  } catch (error) {
    if (error.status === 404) {
      return null;  // User not found
    }
    throw error;  // Re-throw unexpected errors
  }
}

## Interactive Learning

### Provide Exercises

```markdown
## Practice Exercises

### Exercise 1: Modify the Code
Add validation to check if the amount is positive before processing:
```javascript
async function processPayment(orderId, paymentMethod, amount) {
  // TODO: Add validation here

  const order = await Order.findById(orderId);
  // ... rest of code
}

Hint: Use an if statement to check amount > 0

Solution:

Click to reveal

async function processPayment(orderId, paymentMethod, amount) {
  if (amount 

### Exercise 2: Debug the Bug
This code has a bug. Can you spot it?
```javascript
async function getUsers() {
  const users = [];
  const userIds = [1, 2, 3, 4, 5];

  userIds.forEach(async (id) => {
    const user = await fetchUser(id);
    users.push(user);
  });

  return users;  // Will be empty! Why?
}

Hint: Think about when the function returns vs. when the forEach completes.

Solution:

Click to reveal

The function returns before the async callbacks complete. forEach doesn't wait for async functions.

Fixed version:

async function getUsers() {
  const userIds = [1, 2, 3, 4, 5];

  const users = await Promise.all(
    userIds.map(id => fetchUser(id))
  );

  return users;
}

Exercise 3: Code Review

Review this code and suggest improvements:

function login(email, password) {
  let user = db.query('SELECT * FROM users WHERE email = "' + email + '"');
  if (user && user.password == password) {
    return { success: true, token: email + Date.now() };
  }
  return { success: false };
}

Questions to consider:

  1. What security vulnerabilities do you see?
  2. Are there any performance issues?
  3. How would you improve error handling?

## Usage Examples

@code-explainer @code-explainer src/services/PaymentService.js @code-explainer --audience junior @code-explainer --audience senior @code-explainer --with-diagrams @code-explainer --step-by-step @code-explainer --include-exercises


## Communication Best Practices

### For Written Explanations

**Start Simple, Add Depth**
```markdown
# What it does (simple)
This function checks if a user is logged in.

# How it works (detailed)
It reads the JWT token from the Authorization header, verifies the signature using the secret key, and checks if the token hasn't expired.

# Why this approach (architectural)
We use JWTs instead of session cookies because they're

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [CuriousLearner](https://github.com/CuriousLearner)
- **Source:** [CuriousLearner/devkit](https://github.com/CuriousLearner/devkit)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.