nestjs-agent
- Custom param decorators extract from the request — they never authenticate, authorize, or run business logic. Auth lives in guards. - Default to `Scope.DEFAULT` (singleton). Use `Scope.REQUEST` only when state must be per-request and an `AsyncLocalStorage`-based context wouldn't do.
Install / Use
npx skills add LOsioChico/nestjs-agentInstalls into whichever agent you are using.
Devin Config
Devin AI agent config
Quality Score
Category
Development & EngineeringSupported Platforms
Tags
Our assessment of nestjs-agent
nestjs-agent scores 67/100 on our quality scale, 3906th of 4,647 Development & Engineering skills we index.
Its Devin Config is 7.5 KB long, well organised into 10 sections with 2 code examples: a thorough specification that gives an agent plenty to work with.
It has no GitHub stars yet, so there is no community track record; judge it on its content.
Maintenance, license and trust
- We could not determine when the repository was last updated.
- No license is declared. By default that means all rights are reserved: you can read it, but reusing or redistributing it is not clearly permitted. Ask the author before building on it commercially.
- Its trust signals score 68/100, with 3 cautions from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
nestjs-agent compared with similar skills
All 4 of these similar skills score higher than nestjs-agent; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| nestjs-agent (this skill)by LOsioChico | 67 | 0 | — | Devin Config |
| taste-skillby Leonxlnx | 100 | 104.3k | today | CLAUDE.md |
| ai-job-searchby ai-job-search-dev | 100 | 67.1k | 1d ago | CLAUDE.md |
| claude-howtoby luongnv89 | 100 | 45.8k | 1d ago | CLAUDE.md |
| algorithmic-artby anthropics | 100 | 177.9k | 36d ago | SKILL.md |
Frequently asked questions
- How do I install nestjs-agent?
- Run
npx skills add LOsioChico/nestjs-agent. The install tabs above show the steps for each supported agent. - Which AI agents does nestjs-agent work with?
- It is written for Devin, as a Devin Config file. Other agents that read the same format can often use it too.
- Is nestjs-agent safe to use?
- It declares no license and scores 68/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is nestjs-agent still maintained?
- We could not determine when the repository was last updated.
Skill content
View source on GitHub38 — Custom Decorators, Provider Scopes, Dynamic Modules
TL;DR
- Custom param decorators extract from the request — they never authenticate, authorize, or run business logic. Auth lives in guards.
- Default to
Scope.DEFAULT(singleton). UseScope.REQUESTonly when state must be per-request and anAsyncLocalStorage-based context wouldn't do. Scope.REQUESTcascades up the dependency chain — every consumer becomes per-request. Treat that as a perf decision, not a free knob.- Dynamic modules (
forRoot/forRootAsync/forFeature) are for configurable infrastructure: DB clients, HTTP clients, mailers, queue registrations. Feature modules don't need them. - Use typed DI tokens (
InjectionToken<T>or aSymbol) forprovide:values — string tokens collide silently across modules. forwardRefis a smell, not a fix. Prefer breaking the cycle; reach forforwardRefonly when both sides genuinely need each other.
Why it matters
These three primitives are where senior NestJS code goes wrong silently. Wrong decorator usage puts trust on the request body. Wrong provider scope tanks throughput by rebuilding the graph per request. Wrong dynamic-module shape leaks config across tests and prod.
Custom param decorators
- Read from
ExecutionContext. Do not call services or run business logic. - Returning a typed value from a decorator is a contract — keep it stable.
- Auth-context decorators (
@CurrentUser(),@TenantId()) read fromrequest.userpopulated by a guard. They do not authenticate; they just expose what the guard already proved. - Validation belongs in pipes and DTOs, not in decorators. A decorator that throws on bad shape is a hidden pipe.
- A decorator may assert its own preconditions (e.g., the guard ran) — that's a contract check, not authentication or validation.
// good — pure extraction; the guard already authenticated, this just asserts it ran
export const CurrentUser = createParamDecorator(
(_: unknown, ctx: ExecutionContext): AuthenticatedUser => {
const user = ctx.switchToHttp().getRequest().user;
// defensive assertion that the auth guard populated the request.
// if this throws, the route is misconfigured (missing @UseGuards), not under attack.
if (!user) {
throw new UnauthorizedException({
code: 'AUTH.UNAUTHENTICATED',
message: 'No authenticated user on the request.',
});
}
return user;
},
);
Provider scopes
| Scope | When |
|---|---|
| DEFAULT (singleton) | Most services, repositories, gateways |
| REQUEST | Per-request mutable state that must not leak — and only when AsyncLocalStorage won't fit |
| TRANSIENT | Per-consumer instances that need the consumer's identity (e.g., a child logger bound to the importing class) |
- Per-request data (user, tenant, correlation id) belongs in
AsyncLocalStorage-backed context, not inScope.REQUESTproviders. - A single
Scope.REQUESTprovider forces every dependent provider to also be request-scoped, which means a graph rebuild per request and lost provider lifecycle hooks. - Loggers and tracers usually do not need
REQUESTscope — they accept context per call. TRANSIENTis legitimate but uncommon: prefer it only when each consumer genuinely needs its own instance (e.g., a logger that capturesMyService.nameat injection time). Otherwise it's a smell.
Dynamic modules
- Use for infrastructure that needs config: DB modules, queue modules, mail, storage, feature flags.
forRoot(options)for static config;forRootAsync({ useFactory, inject })for config derived at boot fromConfigService.forFeature(...)registers per-module pieces against an already-rooted module — e.g.,TypeOrmModule.forFeature([Entity]),BullModule.forFeature({ name }). Use it inside the feature module that owns the entities/queues; do not callforRootagain.- For new modules with several options, prefer
ConfigurableModuleBuilderover hand-rollingforRoot/forRootAsync— it generates a typed builder, async wiring, andMODULE_OPTIONS_TOKENfor you. - Export
Global()only when the module is truly app-wide infra; feature modules import explicitly. - Keep options strongly typed; validate at boot (Zod) the same way you validate env.
- Use a typed DI token for
provide:—const STRIPE_CLIENT = Symbol('STRIPE_CLIENT')or anInjectionToken<Stripe>. String literals collide silently across modules and lose type information at the injection site.
// good — async config wired through ConfigService, typed token
export const STRIPE_CLIENT = Symbol('STRIPE_CLIENT');
@Module({})
export class StripeModule {
static forRootAsync(): DynamicModule {
return {
module: StripeModule,
imports: [ConfigModule],
providers: [
{
provide: STRIPE_CLIENT,
inject: [ConfigService],
useFactory: (cfg: ConfigService) => new Stripe(cfg.getOrThrow('STRIPE_SECRET')),
},
],
exports: [STRIPE_CLIENT],
};
}
}
Circular dependencies and forwardRef
- A circular dep almost always means the boundary is wrong. Two services that need each other are usually one service split too eagerly, or two services that should communicate via an event.
- Refactor first: extract the shared logic into a third service, or invert the dependency by emitting an event.
- Only when both directions are genuinely required (e.g.,
UserServicereads notification preferences whileNotificationServiceresolves the recipient's user record), useforwardRef(() => OtherModule)and document why in a comment above the import.
Anti-patterns
- A param decorator that runs queries or calls services.
- A param decorator that "validates" — that's a pipe.
- Marking a service
Scope.REQUESTto carry a user id; useAsyncLocalStorageinstead. - A feature module exposing
forRootfor config it doesn't actually need. - String literals as DI tokens (
provide: 'STRIPE_CLIENT') — use aSymbolorInjectionToken<T>. - Using
forwardRefto "make it compile" without understanding the cycle. - Re-exporting an internal provider from
index.tsso other modules can DI it directly — that breaks module boundaries.
Review checklist
- [ ] Param decorators only read from the request; no logic, no IO, no service calls.
- [ ] Auth-context decorators rely on a guard having populated
request.user; the only thrown error is a contract assertion. - [ ] No
Scope.REQUESTunless explicitly justified;AsyncLocalStoragepreferred for per-request context. - [ ]
Scope.TRANSIENTis used only when each consumer genuinely needs its own instance. - [ ] Dynamic modules are reserved for configurable infra; options are typed and validated;
forFeatureis used for per-module registration. - [ ] DI tokens are
SymbolorInjectionToken<T>, not bare strings. - [ ] No
forwardRefwithout a comment explaining why the cycle is real. - [ ] Module boundaries respected: external callers go through the module's exported service, not internal providers.
See also
03-module-design.md— module boundaries and exports04-code-quality.md— DI, layering12-authentication-patterns.md—request.userand the auth guard17-pipelines-interceptors-guards.md— pipe vs decorator boundary20-configuration.md— env validation for dynamic-module options41-n-plus-one-elimination.md— per-request DataLoader held inAsyncLocalStorageinstead ofScope.REQUEST
Related Skills
taste-skill
104.3kAgent skills that give coding agents taste: art direction, reference images and a browser check instead of generic AI pages
ai-job-search
67.1kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
claude-howto
45.8kA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
