joshi-chinmay-016/AgentProof

Melhores práticas para implementar e aplicar Guards, Interceptors, Middleware, Pipes e Exception Filters no SDK NitroStack.

O que é AgentProof?

Este skill fornece as melhores práticas para implementar e aplicar Guards, Interceptors, Middleware, Pipes e Exception Filters no SDK NitroStack. Ele é útil para desenvolvedores que desejam adicionar validação de requisições, verificação de autorização, mapeamento de respostas, logging, tratamento de erros e rastreamento de desempenho em seus métodos de ferramentas NitroStack. O skill suporta o SDK NitroStack e demonstra como usar decoradores como @UseGuards, @UseInterceptors, @UseFilters, @UseMiddleware e @UsePipes para integrar esses recursos de forma declarativa. Cada seção inclui interfaces TypeScript e exemplos práticos que mostram como criar e aplicar guards de função, interceptors de temporização, filtros de exceção, middleware de logging e pipes de transformação de entrada.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/joshi-chinmay-016/AgentProof/tree/HEAD/agentproof/.agents/skills/middleware-pipeline

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Quando Usar

Use este skill ao implementar validação de requisições, verificações de autorização, mapeamento de respostas, logging, tratamento de erros ou rastreamento de desempenho em métodos de ferramentas NitroStack.


1. Guards (Guard e @UseGuards)

Guards determinam se uma requisição deve ser processada por um manipulador de ferramenta com base em autenticação, autorização ou outras condições.

Interface:

import { Guard, ExecutionContext } from '@nitrostack/core';

export interface Guard {
  canActivate(context: ExecutionContext): boolean | Promise<boolean>;
}

Exemplo:

import { Guard, ExecutionContext, Injectable } from '@nitrostack/core';

@Injectable()
export class RolesGuard implements Guard {
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const userRoles = context.clientMetadata?.roles || [];
    return userRoles.includes('admin');
  }
}

Aplique o guard usando @UseGuards(...):

import { Tool, UseGuards, z } from '@nitrostack/core';
import { RolesGuard } from './roles.guard.js';

export class AdminTools {
  @Tool({
    name: 'delete_system_logs',
    description: 'Deletar todos os logs do sistema do servidor.',
    inputSchema: z.object({}),
  })
  @UseGuards(RolesGuard)
  async deleteLogs() {
    return { success: true };
  }
}

2. Interceptors (InterceptorInterface e @UseInterceptors)

Interceptors podem transformar/interceptar argumentos de entrada ou a saída mapeada da execução de um método de ferramenta.

Interface:

import { ExecutionContext } from '@nitrostack/core';

export interface InterceptorInterface {
  intercept(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown>;
}

Exemplo:

import { InterceptorInterface, ExecutionContext, Injectable } from '@nitrostack/core';

@Injectable()
export class TimingInterceptor implements InterceptorInterface {
  async intercept(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown> {
    const start = Date.now();
    const result = await next();
    const duration = Date.now() - start;
    context.logger.info(`Execução levou ${duration}ms`);
    return {
      ...result,
      _meta: { durationMs: duration }
    };
  }
}

3. Exception Filters (ExceptionFilterInterface e @UseFilters)

Exception Filters capturam quaisquer erros lançados dentro de guards, interceptors ou os próprios manipuladores de ferramenta, mapeando-os em payloads JSON amigáveis ao usuário.

Interface:

import { ExecutionContext } from '@nitrostack/core';

export interface ExceptionFilterInterface {
  catch(exception: unknown, context: ExecutionContext): unknown | Promise<unknown>;
}

Exemplo:

import { ExceptionFilterInterface, ExecutionContext, Injectable } from '@nitrostack/core';

@Injectable()
export class CustomExceptionFilter implements ExceptionFilterInterface {
  catch(exception: unknown, context: ExecutionContext) {
    const message = exception instanceof Error ? exception.message : 'Erro desconhecido';
    return {
      error: true,
      message,
      timestamp: new Date().toISOString()
    };
  }
}

Aplique o filtro usando @UseFilters(...) em um método de ferramenta:

import { Tool, UseFilters, z } from '@nitrostack/core';
import { CustomExceptionFilter } from './custom-exception.filter.js';

export class LoggingTools {
  @Tool({
    name: 'generate_report',
    description: 'Gera relatórios de uso do sistema.',
    inputSchema: z.object({}),
  })
  @UseFilters(CustomExceptionFilter)
  async generateReport() {
    throw new Error('A geração de relatório ainda não foi implementada.');
  }
}

4. Middleware (MiddlewareInterface, @Middleware e @UseMiddleware)

Middleware executa antes da requisição chegar ao manipulador da ferramenta e pode envolver a execução do manipulador invocando next().

Interface:

import { ExecutionContext } from '@nitrostack/core';

export interface MiddlewareInterface {
  use(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown>;
}

Exemplo:

import { Middleware, MiddlewareInterface, ExecutionContext } from '@nitrostack/core';

@Middleware()
export class LoggingMiddleware implements MiddlewareInterface {
  async use(context: ExecutionContext, next: () => Promise<unknown>): Promise<unknown> {
    context.logger.info(`Entrando na ferramenta: ${context.toolName}`);
    try {
      const result = await next();
      context.logger.info(`Saindo da ferramenta: ${context.toolName}`);
      return result;
    } catch (error) {
      context.logger.error(`Erro na ferramenta: ${error}`);
      throw error;
    }
  }
}

Aplique o middleware usando @UseMiddleware(...) em um método de ferramenta:

import { Tool, UseMiddleware, z } from '@nitrostack/core';
import { LoggingMiddleware } from './logging.middleware.js';

export class StationTools {
  @Tool({
    name: 'fetch_logs',
    description: 'Buscar logs de operações da estação.',
    inputSchema: z.object({}),
  })
  @UseMiddleware(LoggingMiddleware)
  async fetchLogs() {
    return { status: 'operational' };
  }
}

5. Pipes (PipeInterface, @Pipe e @UsePipes)

Pipes são usados para transformar ou validar argumentos de entrada antes que eles cheguem ao método manipulador da ferramenta.

Interface:

import { ArgumentMetadata } from '@nitrostack/core';

export interface PipeInterface<T = unknown, R = unknown> {
  transform(value: T, metadata: ArgumentMetadata): R | Promise<R>;
}

Exemplo:

import { Pipe, PipeInterface, ArgumentMetadata } from '@nitrostack/core';

@Pipe()
export class TrimPipe implements PipeInterface<Record<string, unknown>, Record<string, unknown>> {
  transform(value: Record<string, unknown>, metadata: ArgumentMetadata) {
    const trimmed: Record<string, unknown> = {};
    for (const [key, val] of Object.entries(value)) {
      trimmed[key] = typeof val === 'string' ? val.trim() : val;
    }
    return trimmed;
  }
}

Aplique o pipe usando @UsePipes(...) em um método de ferramenta:

import { Tool, UsePipes, z } from '@nitrostack/core';
import { TrimPipe } from './trim.pipe.js';

export class MessagingTools {
  @Tool({
    name: 'send_message',
    description: 'Enviar uma mensagem para outras estações.',
    inputSchema: z.object({ text: z.string() }),
  })
  @UsePipes(TrimPipe)
  async sendMessage(input: { text: string }) {
    return { sentText: input.text };
  }
}

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Habilidades Relacionadas