用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/SAP/fundamental-ngx --skill migrate命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Add, rename, or remove i18n translation keys in fundamental-ngx (updates FdLanguage interface, .properties files, and generated types)
Audit existing code against project conventions and Angular 22+ best practices
Review a pull request against project conventions and Angular 22+ best practices
正在显示 SKILL.md
基于 SOC 职业分类
| name | migrate |
| description | Migrate a component or directive to Angular 22+ signal-based patterns |
| argument-hint | ["component-path-or-folder"] |
If $ARGUMENTS is empty, ask the user for a component path or folder before proceeding.
Read all files in the target path. For each component, directive, or service, scan for migration items below. If a folder is given, process all .ts and .html files within it.
Inputs / Outputs / Models:
@Input() → input() or input.required()@Input() with setter → input() + linkedSignal() (preferred) or effect() (only for DOM side effects)@Input() + @Output() pair (e.g. value / valueChange) → model()@Output() → output(){ transform: booleanAttribute }{ transform: numberAttribute }Host bindings:
@HostBinding('class.x') → host: { '[class.x]': 'expr()' }@HostBinding('attr.x') → host: { '[attr.x]': 'expr()' }@HostBinding('style.x') → host: { '[style.x]': 'expr()' }@HostListener('event') → host: { '(event)': 'handler($event)' }Queries:
@ViewChild() → viewChild() or viewChild.required()@ViewChildren() → viewChildren()@ContentChild() → contentChild()@ContentChildren() → contentChildren()Template syntax:
*ngIf → @if*ngFor → @for (requires track expression)*ngSwitch / *ngSwitchCase → @switch / @caseState management:
BehaviorSubject used for local component state → signal()BehaviorSubject + combineLatest → computed()Subject<void> used only to trigger side effects → effect()effect() that only calls signal.set() for derived state → computed() or linkedSignalmarkForCheck() after signal updates → removesignal.set() with same ref → immutable update with signal.update()CSS class building:
CssClassBuilder + @applyCssClass → computed() returning class string + host: { '[class]': '_cssClass()' }Cleanup patterns:
DestroyedService → DestroyRef + takeUntilDestroyed()ngOnDestroy only for destroy$.next() → remove entirely after migrationDecorator cleanup:
standalone: true (default since Angular 19)allowSignalWrites option in effect() (the option no longer exists)Imports:
*Module classes → individual component/directive importsMember ordering (ESLint enforced):
@Input, @Output, @ViewChild)input(), output(), model())Do NOT convert these — they should stay as-is:
switchMap, debounceTime, distinctUntilChanged, combineLatest with async sources → keep as RxJSsignal()The migration targets are recommendations, not mandatory fixes. Present all findings but let the user decide scope. Existing @Input() / @Output() decorators are valid — only migrate them if the user wants to or if the code is being substantially reworked.
Output a structured migration plan:
## Migration Plan: [component name]
### Files affected
- path/to/component.ts
- path/to/component.html
- path/to/component.spec.ts
### Inputs / Outputs
| Current | Migration | Notes |
|---------|-----------|-------|
| `@Input() label: string` | `readonly label = input<string>('')` | |
| `@Input() disabled: boolean` | `readonly disabled = input(false, { transform: booleanAttribute })` | |
| `@Input() value` + `@Output() valueChange` | `readonly value = model<T>()` | Two-way binding |
### Host Bindings
| Current | Migration |
|---------|-----------|
| `@HostBinding('class.is-open')` | `host: { '[class.is-open]': 'isOpen()' }` |
### Template Changes
| Current | Migration |
|---------|-----------|
| `*ngIf="condition"` | `@if (condition) { ... }` |
| `*ngFor="let item of items"` | `@for (item of items; track item.id) { ... }` |
### State Management
| Current | Migration | Reason |
|---------|-----------|--------|
| `BehaviorSubject<boolean>` | `signal(false)` | Local state, no async consumers |
### Skipped (intentionally not migrated)
| Item | Reason |
|------|--------|
| `httpData$` Observable | Async HTTP stream |
### Test Updates
- [ ] Replace `component.input = value` with `fixture.componentRef.setInput('input', value)`
- [ ] Update module imports to individual components
- [ ] Verify existing tests still pass after migration
### Docs Updates
- [ ] Update examples if public API changed (input names, usage patterns)
- [ ] Ensure examples use individual imports, not deprecated modules
### Breaking Changes
- [ ] List any renamed/removed inputs or outputs
- [ ] Draft BREAKING CHANGE footer if needed
Stop here and wait for approval before proceeding.
After approval:
yarn formatnx run <library>:buildnx run <library>:lintnx run <library>:test --testfile=<spec-file> --skip-nx-cache