Token导航 LogoToken导航TokenDH.com
研究检索操作浏览器github未标认证来源可访问许可证需确认审计通过

angular-agent-skillAngular Agent 技能

Agent Skill

angular-agent-skill 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

285

周安装

12

GitHub Stars

公开资料未说明

下载量

169
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:angular-agent-skill(Angular Agent 技能)
来源仓库:https://github.com/erikarens/angular-agent-skill
仓库路径:skills/angular-agent-skill
安装命令:
npx skills add https://github.com/erikarens/angular-agent-skill --skill angular-agent-skill
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/erikarens/angular-agent-skill --skill angular-agent-skill

简介

angular-agent-skill 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。

  • 适用于 Angular 项目结构规划、核心架构设计、TypeScript 接口与类型定义管理,以及服务层和工具函数的组织。
  • 通过 npx skills add 命令从指定 GitHub 仓库安装,需结合原始 README 和 SKILL.md 进一步确认具体用法和功能范围。
  • 安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写操作。
  • 适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

SKILL.md

Angular Development

Expert guidance for building scalable Angular applications using modern APIs: signals, standalone components, built-in control flow, and strict TypeScript.

Core Architecture

Project Structure

src/
└── app/
    ├── core/           # Non-business features (layout, auth, guards)
    ├── features/       # Business domain features
    ├── shared/         # Reusable "dumb" components, pipes, directives
    ├── services/       # Global and feature-specific services
    ├── interfaces/     # TypeScript interfaces
    ├── types/          # Type definitions, DTOs (requests/, responses/)
    ├── enums/          # Enums
    ├── utils/          # Pure utility functions
    ├── app.component.ts
    ├── app.config.ts
    └── app.routes.ts

Feature folders follow: pages/ (routed), components/ (non-routed), guards/, feature.routes.ts.

Coding Standards

  • Single quotes, 2-space indent, const by default
  • Kebab-case file names with Angular suffixes (.component.ts, .service.ts)
  • Strict typing, never use any — define explicit types
  • Optional chaining (?.) and nullish coalescing (??)
  • Template literals for string interpolation
  • Always declare methods and properties explicitly as public or private — never rely on implicit public
  • Prefix private properties with underscore: private _state, private readonly _http = inject(HttpClient)
  • Use private readonly for all DI injections: private readonly _http = inject(HttpClient)
  • File structure: imports, class, properties, lifecycle, public methods, private methods

Signals (State Management)

Use Angular's signal system as the primary state management approach.

Signal Primitives

// Writable signal
count = signal(0);
count.set(3);
count.update(v => v + 1);

// Read-only exposure
private readonly _count = signal(0);
readonly count = this._count.asReadonly();

// Computed (lazy, memoized, read-only)
doubleCount = computed(() => this.count() * 2);

// Custom equality for objects
data = signal(['test'], { equal: (a, b) => a.length === b.length });

Signal Inputs, Outputs & Queries

Use function-based APIs instead of decorators:

// Inputs
value = input(0);                                    // InputSignal<number>
name = input<string>();                              // InputSignal<string | undefined>
label = input.required<string>();                    // Required, no undefined
disabled = input(false, { transform: booleanAttribute });

// Outputs
closed = output<void>();                             // OutputEmitterRef<void>
valueChanged = output<number>();
this.valueChanged.emit(42);

// Model inputs (two-way binding)
checked = model(false);                              // ModelSignal<boolean>
// Parent: <my-comp [(checked)]="isChecked" />

// Queries
header = viewChild(HeaderComponent);                 // Signal<HeaderComponent | undefined>
items = viewChildren(ItemComponent);                 // Signal<readonly ItemComponent[]>
toggle = contentChild.required(ToggleComponent);     // Signal<ToggleComponent>

linkedSignal

Writable signal that resets when dependencies change. Use for selections that depend on changing data:

// Shorthand
selectedOption = linkedSignal(() => this.options()[0]);

// Full form — preserves selection across data changes
selectedOption = linkedSignal({
  source: this.options,
  computation: (newOptions, previous) =>
    newOptions.find(o => o.id === previous?.value.id) ?? newOptions[0],
});

resource / httpResource

Integrate async data into signals. Experimental but ready for use:

userResource = resource({
  params: () => ({ id: this.userId() }),
  loader: ({ params, abortSignal }) =>
    fetch(`/api/users/${params.id}`, { signal: abortSignal }).then(r => r.json()),
});

// Access: userResource.value(), .status(), .isLoading(), .error(), .hasValue()
// Actions: userResource.reload(), .set(), .update()

effect

For side effects only — logging, localStorage sync, DOM interop. Never use for state propagation (use computed or linkedSignal instead):

constructor() {
  effect((onCleanup) => {
    const user = this.currentUser();
    const timer = setTimeout(() => console.log(user), 1000);
    onCleanup(() => clearTimeout(timer));
  });
}

RxJS Interop

// Observable → Signal
counter = toSignal(this.counter$, { initialValue: 0 });
// Use requireSync: true for BehaviorSubject

// Signal → Observable
query$ = toObservable(this.query);

For detailed signal patterns, see references/signals.md.

Templates

Built-in Control Flow

Always use the built-in block syntax. Never use *ngIf, *ngFor, *ngSwitch:

@if (user(); as user) {
  <h1>{{ user.name }}</h1>
} @else {
  <p>Loading...</p>
}

@for (item of items(); track item.id) {
  <li>{{ item.name }}</li>
} @empty {
  <li>No items found.</li>
}

@switch (role()) {
  @case ('admin') { <admin-panel /> }
  @case ('editor') { <editor-panel /> }
  @default { <viewer-panel /> }
}

@for requires track. Use a unique identifier; use $index only for static lists. Available context: $index, $first, $last, $even, $odd, $count.

Deferrable Views

Reduce initial bundle size by deferring non-critical content:

@defer (on viewport; prefetch on idle) {
  <heavy-chart [data]="chartData()" />
} @placeholder (minimum 200ms) {
  <div class="skeleton"></div>
} @loading (after 100ms; minimum 500ms) {
  <spinner />
} @error {
  <p>Failed to load chart.</p>
}

Triggers: on idle, on viewport, on interaction, on hover, on timer(500ms), on immediate, when condition.

For detailed template patterns, see references/templates.md.

Components & DI

Standalone by Default

All components are standalone by default (Angular 19+). Import dependencies directly:

@Component({
  selector: 'app-user-card',
  imports: [DatePipe, RouterLink],
  templateUrl: './user-card.component.html',
  styleUrl: './user-card.component.css',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class UserCardComponent {
  user = input.required<User>();
  selected = output<void>();
}

Dependency Injection

Use inject() function, not constructor injection. Always use private readonly with underscore prefix:

export class UserService {
  private readonly _http = inject(HttpClient);
  private readonly _config = inject(ConfigService);
}

Services use providedIn: 'root' for tree-shakeable singletons.

HTTP

Convert observables to promises with firstValueFrom:

public async getUser(id: string): Promise<User> {
  return firstValueFrom(
    this._http.get<User>(`/api/users/${id}`)
  );
}

Configure with functional API:

provideHttpClient(
  withInterceptors([authInterceptor]),
  withFetch(),  // Use Fetch API, required for SSR streaming
)

Functional Interceptors

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const token = inject(AuthService).getToken();
  if (token) {
    req = req.clone({ setHeaders: { Authorization: `Bearer ${token}` } });
  }
  return next(req);
};

Lifecycle & Cleanup

  • Use afterNextRender() / afterRenderEffect() for DOM operations (browser-only)
  • Prefer DestroyRef + takeUntilDestroyed() for subscription cleanup:
// In constructor (injection context) — no argument needed
this.route.params.pipe(takeUntilDestroyed()).subscribe(/*...*/);

// Outside constructor — pass DestroyRef
private readonly _destroyRef = inject(DestroyRef);
public ngOnInit() {
  this.obs$.pipe(takeUntilDestroyed(this._destroyRef)).subscribe(/*...*/);
}
  • Render phases: earlyReadwritemixedReadWriteread

Routing

Use functional guards and resolvers. Lazy-load feature routes:

export const routes: Routes = [
  {
    path: 'dashboard',
    loadComponent: () => import('./features/dashboard/pages/dashboard.component'),
    canActivate: [() => inject(AuthService).isAuthenticated()],
  },
  {
    path: 'user/:id',
    loadComponent: () => import('./features/user/pages/user-detail.component'),
    resolve: { user: (route: ActivatedRouteSnapshot) => inject(UserService).getUser(route.paramMap.get('id')!) },
  },
];

Enable withComponentInputBinding() to automatically bind route params, query params, and resolve data to component inputs:

// app.config.ts
provideRouter(routes, withComponentInputBinding(), withViewTransitions())

// Component — 'id' auto-bound from route param ':id', 'user' from resolve
export class UserDetailComponent {
  id = input<string>();
  user = input<User>();
}

App Configuration

// app.config.ts
export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes, withComponentInputBinding(), withViewTransitions()),
    provideHttpClient(withInterceptors([authInterceptor]), withFetch()),
    provideAnimationsAsync(),
    provideClientHydration(withEventReplay()),
    // provideExperimentalZonelessChangeDetection(), // Zoneless (experimental)
  ],
};

Performance

  • ChangeDetectionStrategy.OnPush on all components
  • track with unique IDs in @for loops
  • @defer for below-fold and heavy components
  • NgOptimizedImage for all images with priority on LCP image
  • Pure pipes for repeated template computations
  • Signals automatically optimize re-renders with granular tracking
  • takeUntilDestroyed() to prevent subscription memory leaks

Accessibility (a11y)

Use semantic HTML first. Add ARIA attributes only when native elements aren't sufficient. Always bind ARIA attributes with [attr.aria-*] (not [aria-*]) since they have no DOM properties.

@angular/aria — Headless Accessible Components

For common interactive UI patterns, use @angular/aria (npm install @angular/aria). These headless directives implement WAI-ARIA patterns with full keyboard navigation, ARIA attributes, and focus management built in — you provide HTML structure and CSS styling.

Available components:

NeedComponentImport
Collapsible sectionsAccordion@angular/aria/accordion
Tabbed panelsTabs@angular/aria/tabs
Selection listListbox@angular/aria/listbox
Dropdown (<20 options)Select@angular/aria/combobox + listbox
Multi-select dropdownMultiselect@angular/aria/combobox + listbox
Searchable dropdownAutocomplete@angular/aria/combobox + listbox
Context/action menuMenu@angular/aria/menu
Navigation barMenubar@angular/aria/menu
Grouped actionsToolbar@angular/aria/toolbar
Interactive table/calendarGrid@angular/aria/grid
Hierarchical dataTree@angular/aria/tree

All components are headless (bring your own styles), support RTL, use Angular signals for state, and import directly into standalone components.

// Example: Accessible tabs with @angular/aria
import { Tabs, TabList, Tab, TabPanel, TabContent } from '@angular/aria/tabs';

@Component({
  imports: [Tabs, TabList, Tab, TabPanel, TabContent],
  template: `
    <div ngTabs>
      <div ngTabList selectionMode="follow" selectedTab="general">
        <div ngTab value="general">General</div>
        <div ngTab value="security">Security</div>
      </div>
      <div ngTabPanel [preserveContent]="true" value="general">
        <ng-template ngTabContent>General settings</ng-template>
      </div>
      <div ngTabPanel [preserveContent]="true" value="security">
        <ng-template ngTabContent>Security settings</ng-template>
      </div>
    </div>
  `,
})

For detailed API reference, inputs, keyboard interactions, and examples for all components, see references/angular-aria.md.

CDK a11y Module

For lower-level accessibility utilities (focus traps, focus monitoring, screen reader announcements, custom keyboard navigation), use @angular/cdk/a11y. Services are providedIn: 'root' — no module import needed:

import { CdkTrapFocus, CdkMonitorFocus, CdkAriaLive } from '@angular/cdk/a11y';

Focus Management

Use CdkTrapFocus for modals/dialogs to trap Tab focus. Use cdkFocusInitial to mark the initial focus target:

<div role="dialog" aria-modal="true" [attr.aria-labelledby]="titleId"
     cdkTrapFocus [cdkTrapFocusAutoCapture]="true">
  <h2 [id]="titleId">{{ title() }}</h2>
  <input cdkFocusInitial />
  <button (click)="close()">Close</button>
</div>

Use FocusMonitor to detect how an element received focus and show keyboard-only focus rings:

private readonly _focusMonitor = inject(FocusMonitor);
// _focusMonitor.monitor(el) → Observable<FocusOrigin>
// _focusMonitor.focusVia(el, 'keyboard') → programmatic focus with origin

Screen Reader Announcements

Use LiveAnnouncer for dynamic status updates:

private readonly _liveAnnouncer = inject(LiveAnnouncer);
this._liveAnnouncer.announce('Item saved', 'polite');    // Waits for current speech
this._liveAnnouncer.announce('Error occurred', 'assertive'); // Interrupts

Or CdkAriaLive in templates: <div [cdkAriaLive]="'polite'">{{status()}}</div>

Keyboard Navigation

FocusKeyManager — roving tabindex pattern (moves DOM focus between items):

keyManager = new FocusKeyManager(this.items()).withWrap().withVerticalOrientation();
// Items implement: focus(), disabled?, getLabel?()

ActiveDescendantKeyManager — uses aria-activedescendant (focus stays on host, e.g. combobox):

keyManager = new ActiveDescendantKeyManager(this.options()).withWrap().withTypeAhead();
// Items implement: setActiveStyles(), setInactiveStyles(), disabled?
// Host: [attr.aria-activedescendant]="keyManager.activeItem?.id"

Accessible Forms

<label for="email">Email</label>
<input id="email" type="email"
  [attr.aria-invalid]="emailInvalid() ? 'true' : null"
  [attr.aria-describedby]="emailInvalid() ? 'email-error' : null"
  [attr.aria-required]="'true'" />
@if (emailInvalid()) {
  <span id="email-error" role="alert">Please enter a valid email.</span>
}

For detailed CDK a11y patterns and full API reference, see references/accessibility.md.

Security

  • Never use innerHTML — rely on Angular's built-in sanitization
  • Sanitize dynamic content with Angular's DomSanitizer when necessary

Testing

  • Arrange-Act-Assert pattern
  • Test services, components, and utilities with high coverage

SSR / Hybrid Rendering

Configure per-route rendering in app.routes.server.ts:

export const serverRoutes: ServerRoute[] = [
  { path: '', renderMode: RenderMode.Client },
  { path: 'about', renderMode: RenderMode.Prerender },
  { path: 'profile', renderMode: RenderMode.Server },
];

Use afterNextRender() for browser-only code. @defer blocks render @placeholder on server.

References

  • references/signals.md — Detailed signal API reference, patterns for resource, linkedSignal, effect cleanup, and RxJS interop
  • references/templates.md — Control flow details, @defer triggers, SSR considerations, and template best practices
  • references/angular-aria.md@angular/aria headless accessible components: Accordion, Tabs, Listbox, Select, Multiselect, Autocomplete, Combobox, Menu, Menubar, Toolbar, Grid, Tree — with full API, inputs, keyboard interactions, and examples
  • references/accessibility.md — CDK a11y utilities: FocusTrap, FocusMonitor, LiveAnnouncer, AriaDescriber, KeyManagers, InteractivityChecker, InputModalityDetector, HighContrastModeDetector, and accessible component patterns

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

34.96%
按下载量换算59

Claude

28.92%
按下载量换算49

Cursor

20.34%
按下载量换算34

Gemini CLI

10.34%
按下载量换算17

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills