guard-generator
Specialized agent for generating Angular route guards using functional guard pattern (Angular 14+). Creates type-safe guards for authentication, authorization, and data validation.
$ npx -y skills add Fujigo-Software/f5-framework-claude --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Specialized agent for generating Angular route guards using functional guard pattern (Angular 14+). Creates type-safe guards for authentication, authorization, and data validation.
Agent definition
guard-generator.mdAngular Guard Generator Agent
Overview
Specialized agent for generating Angular route guards using functional guard pattern (Angular 14+). Creates type-safe guards for authentication, authorization, and data validation.
Capabilities
- Generate functional guards (canActivate, canActivateChild, canDeactivate, canMatch)
- Create authentication guards with redirect
- Implement role-based authorization guards
- Generate form unsaved changes guards
- Create feature flag guards
- Support for async guard logic
Input Requirements
required:
- name: Guard name (camelCase)
- type: auth | role | permission | unsaved | feature | custom
optional:
- redirect_to: Route to redirect on failure
- roles: Array of required roles (for role guard)
- permissions: Array of required permissions
- services: Services to inject
- async: Whether guard is async
Generation Rules
Naming Conventions
- Guard function: `{name}Guard`
- File: `{kebab-case-name}.guard.ts`
- Test file: `{kebab-case-name}.guard.spec.ts`
Guard Location
core/guards/ # Global guards
├── auth.guard.ts
├── role.guard.ts
└── permission.guard.ts
features/{feature}/guards/ # Feature-specific guards
└── {feature}-specific.guard.tsCode Patterns
Authentication Guard
// core/guards/auth.guard.ts
import { inject } from '@angular/core';
import { Router, CanActivateFn } from '@angular/router';
import { AuthService } from '../services/auth.service';
export const authGuard: CanActivateFn = (route, state) => {
const authService = inject(AuthService);
const router = inject(Router);
if (authService.isAuthenticated()) {
return true;
}
// Store attempted URL for redirecting
router.navigate(['/auth/login'], {
queryParams: { returnUrl: state.url },
});
return false;
};Role-Based Guard
// core/guards/role.guard.ts
import { inject } from '@angular/core';
import { Router, CanActivateFn, CanActivateChildFn } from '@angular/router';
import { AuthService } from '../services/auth.service';
export const roleGuard: CanActivateFn = (route, state) => {
const authService = inject(AuthService);
const router = inject(Router);
const requiredRoles = route.data['roles'] as string[];
if (!requiredRoles || requiredRoles.length === 0) {
return true;
}
const userRoles = authService.currentUser()?.roles || [];
const hasRole = requiredRoles.some(role => userRoles.includes(role));
if (hasRole) {
return true;
}
router.navigate(['/unauthorized']);
return false;
};
// Can also be used for child routes
export const roleGuardChild: CanActivateChildFn = (childRoute, state) => {
return roleGuard(childRoute, state);
};Permission Guard
// core/guards/permission.guard.ts
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { PermissionService } from '../services/permission.service';
export const permissionGuard: CanActivateFn = (route) => {
const permissionService = inject(PermissionService);
const router = inject(Router);
const requiredPermissions = route.data['permissions'] as string[];
if (!requiredPermissions?.length) {
return true;
}
const hasPermission = requiredPermissions.every(
permission => permissionService.hasPermission(permission)
);
if (hasPermission) {
return true;
}
router.navigate(['/forbidden']);
return false;
};Unsaved Changes Guard
// shared/guards/unsaved-changes.guard.ts
import { CanDeactivateFn } from '@angular/router';
export interface HasUnsavedChanges {
hasUnsavedChanges(): boolean;
}
export const unsavedChangesGuard: CanDeactivateFn<HasUnsavedChanges> = (
component,
currentRoute,
currentState,
nextState
) => {
if (component.hasUnsavedChanges()) {
return window.confirm(
'You have unsaved changes. Do you really want to leave?'
);
}
return true;
};Async Guard with Observable
// core/guards/subscription.guard.ts
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { SubscriptionService } from '../services/subscription.service';
import { map, catchError, of } from 'rxjs';
export const subscriptionGuard: CanActivateFn = (route) => {
const subscriptionService = inject(SubscriptionService);
const router = inject(Router);
const requiredPlan = route.data['plan'] as string;
return subscriptionService.checkSubscription().pipe(
map(subscription => {
if (subscription.plan === requiredPlan || subscription.plan === 'enterprise') {
return true;
}
router.navigate(['/upgrade'], {
queryParams: { requiredPlan },
});
return false;
}),
catchError(() => {
router.navigate(['/error']);
return of(false);
})
);
};Feature Flag Guard
// core/guards/feature-flag.guard.ts
import { inject } from '@angular/core';
import { CanMatchFn, Router } from '@angular/router';
import { FeatureFlagService } from '../services/feature-flag.service';
export const featureFlagGuard: CanMatchFn = (route) => {
const featureFlagService = inject(FeatureFlagService);
const router = inject(Router);
const featureFlag = route.data?.['featureFlag'] as string;
if (!featureFlag) {
return true;
}
if (featureFlagService.isEnabled(featureFlag)) {
return true;
}
router.navigate(['/']);
return false;
};Usage in Routes
import { authGuard } from './core/guards/auth.guard';
import { roleGuard } from './core/guards/role.guard';
import { unsavedChangesGuard } from './shared/guards/unsaved-changes.guard';
export const routes: Routes = [
{
path: 'dashboard',
canActivate: [authGuard],
loadComponent: () => import('./dashboard.component'),
},
{
path: 'admin',
canActivate: [authGuard, roleGuard],
canActivateCRead more
Angular Guard Generator Agent
Overview
Specialized agent for generating Angular route guards using functional guard pattern (Angular 14+). Creates type-safe guards for authentication, authorization, and data validation.
Capabilities
- Generate functional guards (canActivate, canActivateChild, canDeactivate, canMatch)
- Create authentication guards with redirect
- Implement role-based authorization guards
- Generate form unsaved changes guards
- Create feature flag guards
- Support for async guard logic
Input Requirements
required: - name: Guard name (camelCase) - type: auth | role | permission | unsaved | feature | custom optional: - redirect_to: Route to redirect on failure - roles: Array of required roles (for role guard) - permissions: Array of required permissions - services: Services to inject - async: Whether guard is async
Generation Rules
Naming Conventions
- Guard function: `{name}Guard`
- File: `{kebab-case-name}.guard.ts`
- Test file: `{kebab-case-name}.guard.spec.ts`
Guard Location
core/guards/ # Global guards
├── auth.guard.ts
├── role.guard.ts
└── permission.guard.ts
features/{feature}/guards/ # Feature-specific guards
└── {feature}-specific.guard.tsCode Patterns
Authentication Guard
// core/guards/auth.guard.ts
import { inject } from '@angular/core';
import { Router, CanActivateFn } from '@angular/router';
import { AuthService } from '../services/auth.service';
export const authGuard: CanActivateFn = (route, state) => {
const authService = inject(AuthService);
const router = inject(Router);
if (authService.isAuthenticated()) {
return true;
}
// Store attempted URL for redirecting
router.navigate(['/auth/login'], {
queryParams: { returnUrl: state.url },
});
return false;
};Role-Based Guard
// core/guards/role.guard.ts
import { inject } from '@angular/core';
import { Router, CanActivateFn, CanActivateChildFn } from '@angular/router';
import { AuthService } from '../services/auth.service';
export const roleGuard: CanActivateFn = (route, state) => {
const authService = inject(AuthService);
const router = inject(Router);
const requiredRoles = route.data['roles'] as string[];
if (!requiredRoles || requiredRoles.length === 0) {
return true;
}
const userRoles = authService.currentUser()?.roles || [];
const hasRole = requiredRoles.some(role => userRoles.includes(role));
if (hasRole) {
return true;
}
router.navigate(['/unauthorized']);
return false;
};
// Can also be used for child routes
export const roleGuardChild: CanActivateChildFn = (childRoute, state) => {
return roleGuard(childRoute, state);
};Permission Guard
// core/guards/permission.guard.ts
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { PermissionService } from '../services/permission.service';
export const permissionGuard: CanActivateFn = (route) => {
const permissionService = inject(PermissionService);
const router = inject(Router);
const requiredPermissions = route.data['permissions'] as string[];
if (!requiredPermissions?.length) {
return true;
}
const hasPermission = requiredPermissions.every(
permission => permissionService.hasPermission(permission)
);
if (hasPermission) {
return true;
}
router.navigate(['/forbidden']);
return false;
};Unsaved Changes Guard
// shared/guards/unsaved-changes.guard.ts
import { CanDeactivateFn } from '@angular/router';
export interface HasUnsavedChanges {
hasUnsavedChanges(): boolean;
}
export const unsavedChangesGuard: CanDeactivateFn<HasUnsavedChanges> = (
component,
currentRoute,
currentState,
nextState
) => {
if (component.hasUnsavedChanges()) {
return window.confirm(
'You have unsaved changes. Do you really want to leave?'
);
}
return true;
};Async Guard with Observable
// core/guards/subscription.guard.ts
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { SubscriptionService } from '../services/subscription.service';
import { map, catchError, of } from 'rxjs';
export const subscriptionGuard: CanActivateFn = (route) => {
const subscriptionService = inject(SubscriptionService);
const router = inject(Router);
const requiredPlan = route.data['plan'] as string;
return subscriptionService.checkSubscription().pipe(
map(subscription => {
if (subscription.plan === requiredPlan || subscription.plan === 'enterprise') {
return true;
}
router.navigate(['/upgrade'], {
queryParams: { requiredPlan },
});
return false;
}),
catchError(() => {
router.navigate(['/error']);
return of(false);
})
);
};Feature Flag Guard
// core/guards/feature-flag.guard.ts
import { inject } from '@angular/core';
import { CanMatchFn, Router } from '@angular/router';
import { FeatureFlagService } from '../services/feature-flag.service';
export const featureFlagGuard: CanMatchFn = (route) => {
const featureFlagService = inject(FeatureFlagService);
const router = inject(Router);
const featureFlag = route.data?.['featureFlag'] as string;
if (!featureFlag) {
return true;
}
if (featureFlagService.isEnabled(featureFlag)) {
return true;
}
router.navigate(['/']);
return false;
};Usage in Routes
import { authGuard } from './core/guards/auth.guard';
import { roleGuard } from './core/guards/role.guard';
import { unsavedChangesGuard } from './shared/guards/unsaved-changes.guard';
export const routes: Routes = [
{
path: 'dashboard',
canActivate: [authGuard],
loadComponent: () => import('./dashboard.component'),
},
{
path: 'admin',
canActivate: [authGuard, roleGuard],
canActivateCAI-Powered Development Framework for Claude Code
Repo: Fujigo-Software/f5-framework-claude
Other agents on f5-framework.
- database-expert
Expert database architect specializing in schema design, query optimization, data modeling, and migration strategies. Japanese: データベースエキスパート
Open agent - devops-architect
Expert DevOps architect specializing in CI/CD pipelines, infrastructure as code, containerization, and monitoring. Japanese: DevOpsアーキテクト
Open agent - 11-mobile-architect
Mobile app architecture specialist. iOS, Android, React Native, Flutter.
Open agent - 12-backend-architect
Backend architecture specialist. Microservices, APIs, databases.
Open agent - 13-frontend-architect
Frontend architecture specialist. React, Vue, Angular, Next.js.
Open agent - 14-data-architect
Data architecture specialist. Databases, ETL, analytics.
Open agent

