Angular Architect
Jeffallan/claude-skills
Builds Angular 17+ features with standalone components, signals, NgRx state, RxJS patterns and lazy-loaded routing, then checks bundle size and test coverage.
Signal-first reactive state management for Angular. An agent skill from fmflurry/settings-opencode.
$ npx skills add fmflurry/settings-opencode --skill flurryx -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install fmflurry/settings-opencode flurryx --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/fmflurry/settings-opencode.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/flurryx .claude/skills/flurryx && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "flurryx" agent skill from https://github.com/fmflurry/settings-opencode/tree/master/skills/flurryx into .claude/skills/flurryx/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flurryx", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/fmflurry/settings-opencode/tree/master/skills/flurryxType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add fmflurry/settings-opencode --skill flurryx -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install fmflurry/settings-opencode flurryx --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/fmflurry/settings-opencode.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/flurryx .agents/skills/flurryx && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "flurryx" agent skill from https://github.com/fmflurry/settings-opencode/tree/master/skills/flurryx into .agents/skills/flurryx/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flurryx", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add fmflurry/settings-opencode --skill flurryx -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install fmflurry/settings-opencode flurryx --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/fmflurry/settings-opencode.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/flurryx .cursor/skills/flurryx && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "flurryx" agent skill from https://github.com/fmflurry/settings-opencode/tree/master/skills/flurryx into .cursor/skills/flurryx/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flurryx", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/fmflurry/settings-opencode.git --path skills/flurryx--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add fmflurry/settings-opencode --skill flurryx -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install fmflurry/settings-opencode flurryx --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/fmflurry/settings-opencode.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/flurryx .gemini/skills/flurryx && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "flurryx" agent skill from https://github.com/fmflurry/settings-opencode/tree/master/skills/flurryx into .gemini/skills/flurryx/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flurryx", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install fmflurry/settings-opencode flurryxInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add fmflurry/settings-opencode --skill flurryx -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/fmflurry/settings-opencode.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/flurryx .github/skills/flurryx && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "flurryx" agent skill from https://github.com/fmflurry/settings-opencode/tree/master/skills/flurryx into .github/skills/flurryx/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flurryx", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add fmflurry/settings-opencode --skill flurryx -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install fmflurry/settings-opencode flurryx --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/fmflurry/settings-opencode.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/flurryx .opencode/skills/flurryx && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "flurryx" agent skill from https://github.com/fmflurry/settings-opencode/tree/master/skills/flurryx into .opencode/skills/flurryx/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "flurryx", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
flurryxSignal-first reactive state management for Angular. An agent skill from fmflurry/settings-opencode.
Flurryx is an agent skill from fmflurry/settings-opencode. Signal-first reactive state management for Angular. Bridge RxJS streams into cache-aware stores, keyed resources, mirrored state, and replayable history. Use when generating or modifying Angular code that uses flurryx for state management, or when scaffolding new feature modules that follow the flurryx facade pattern.
Its SKILL.md is about 4.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Frontend & Design, covering State management and Project scaffolding. It works with Angular and RxJS. The repository describes itself as: Custom OpenCode settings. The licence is MIT.
4 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 0e6c33c. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Flurryx loads about 4.2k tokens when it runs. Until then it costs about 82 tokens; SKILL.md has 964 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from fmflurry/settings-opencode at commit 0e6c33c, republished under its MIT licence (© fmflurry). 964 words, ~4,232 tokens.
.claude/skills/flurryx/SKILL.md (or your agent's skills folder).Signal-first reactive state management for Angular. RxJS in, signals out.
Store, syncToStore, syncToKeyedStoreKeyedResourceData<TKey, TValue>mirror, mirrorSelf, derive, deriveSelf, mirrorKeyed, mirrorKey, deriveKey, collectKeyed// main API
import {
Store, BaseStore, LazyStore,
syncToStore, syncToKeyedStore,
SkipIfCached, Loading,
clearAllStores,
mirrorKey, deriveKey, collectKeyed,
cloneValue, createSnapshotRestorePatch,
createInMemoryStoreMessageChannel,
createStorageStoreMessageChannel,
createLocalStorageStoreMessageChannel,
createSessionStorageStoreMessageChannel,
createCompositeStoreMessageChannel,
isKeyedResourceData, createKeyedResourceData, isAnyKeyLoading,
CACHE_NO_TIMEOUT, DEFAULT_CACHE_TTL_MS,
defaultErrorNormalizer,
} from 'flurryx';
import type {
ResourceState, StoreEnum, ResourceStatus, ResourceErrors,
KeyedResourceData, KeyedResourceKey,
StoreSignal, KeyedStoreSignal, KeyedResourceState, ValueOrSignal,
StoreOptions, StoreCacheInvalidateEvent,
MirrorOptions, DeriveOptions, CollectKeyedOptions,
SyncToStoreOptions, SyncToKeyedStoreOptions, ErrorNormalizer,
// history
StoreHistory, StoreHistoryEntry,
StoreDeadLetterEntry, StoreDeadLetterCommand, StoreDeadLetterMeta,
DeadLetterCommandResolverResult,
// messages
StoreMessage, StoreSnapshot, StoreMessageStatus,
UpdateStoreMessage, ClearStoreMessage, ClearAllStoreMessage,
StartLoadingStoreMessage, StopLoadingStoreMessage,
UpdateKeyedOneStoreMessage, ClearKeyedOneStoreMessage,
StartKeyedLoadingStoreMessage, EnsureKeyedSlotStoreMessage,
// channels
StoreMessageRecord, StoreMessageChannel,
StoreMessageChannelStorage, StoreMessageChannelOptions,
CompositeStoreMessageChannelOptions,
StorageStoreMessageChannelOptions,
BrowserStorageStoreMessageChannelOptions,
} from 'flurryx';
// HTTP-only — pulls @angular/common/http
import { httpErrorNormalizer } from 'flurryx/http';Prefer flurryx. Use flurryx/http only for httpErrorNormalizer. Avoid direct @flurryx/core | @flurryx/store | @flurryx/rx unless host already depends.
anyStore.for<Config>().build() interface builderUPPER_SNAKE_CASE keys: LIST, DETAIL, ITEMS@SkipIfCached outermost, @Loading directly beneath@SkipIfCached only if cache hits are intended; else omitsyncToKeyedStore, not hand-rolled Record updatesBaseStore directlycomputedObservable -> syncToStore / syncToKeyedStore -> Store signal -> Template<T>Every slot wraps ResourceState<T>:
interface ResourceState<T> {
isLoading?: boolean;
data?: T;
status?: 'Success' | 'Error';
errors?: Array<{ code: string; message: string }>;
}Lifecycle: idle -> loading -> Success | Error.
Per-entity cache:
type KeyedResourceData<TKey extends string | number, TValue> =
Partial<Record<TKey, ResourceState<TValue>>>;Helpers:
createKeyedResourceData<TKey, TValue>() -> {}isKeyedResourceData(val) -> type guardisAnyKeyLoading(data) -> boolinterface ProductStoreConfig {
LIST: Product[];
DETAIL: Product;
ITEMS: KeyedResourceData<string, Item>;
}
export const ProductStore = Store.for<ProductStoreConfig>().build();Naming: <Feature>StoreConfig + <Feature>Store. Slots are raw types; flurryx wraps in ResourceState<T>.
const Keys = { LIST: 'LIST', DETAIL: 'DETAIL' } as const;
export const ProductStore = Store.for(Keys)
.resource('LIST').as<Product[]>()
.resource('DETAIL').as<Product>()
.build();.build() only callable when all enum keys defined.
export const ProductStore = Store
.resource('LIST').as<Product[]>()
.resource('DETAIL').as<Product>()
.build();.mirror(sourceToken, sourceKey, targetKey?) -> 1:1 cross-store mirror.mirrorSelf(sourceKey, targetKey) -> alias inside same store; keys must differ.derive(sourceToken, sourceKey, targetKey?, { mapData }) -> map source data into target slot.deriveSelf(sourceKey, targetKey, { mapData }) -> derived alias inside same store.mirrorKeyed(sourceToken, sourceKey, { extractId }, targetKey?) -> aggregate single-entity fetches into keyed slot.build(options?: StoreOptions) -> InjectionToken registered providedIn: 'root'StoreOptions extends StoreMessageChannelOptions -> supply channel to override default in-memory channel.
store.get(key) returns:
Signal<ResourceState<T>>KeyedStoreSignal<TData, K> = signal + .for(resourceKey | Signal<resourceKey>) -> Signal<ResourceState<TValue>>update(key, partial, options?) -> merge partial; options.deadLetter?: StoreDeadLetterMetaclear(key) -> reset slot to idleclearAll() -> reset every slotstartLoading(key) / stopLoading(key)updateKeyedOne(key, resourceKey, entity) -> sets entity status Success, recomputes top-level isLoadingclearKeyedOne(key, resourceKey) -> remove single keyed entrystartKeyedLoading(key, resourceKey) -> mark single key loadinginvalidateCacheFor(key) -> invalidate slot cache only (state untouched)invalidateCacheFor(key, resourceKey) -> invalidate one keyed entry's cacheonUpdate(key, (next, prev) => …) -> () => void cleanuponCacheInvalidate(key, ({ key, resourceKey }) => …) -> cleanupqueueMicrotask/AggregateErrorreplay(id | ids[]) -> re-execute persisted channel messages -> int (acked count)restoreStoreAt(index) -> snapshot navigation (no message)restoreResource(key, index?) -> restore single key from snapshotundo() / redo() -> boolgetHistory() / getHistory(key) -> readonly entriesgetMessages() / getMessages(key) -> channel recordsgetDeadLetters() -> dead-letter entriesreplayDeadLetter(id) -> boolreplayDeadLetters() -> int (acked)replayDeadLetterCommand(id, async resolver -> { resolved, clear }) -> Promise<bool>getCurrentIndex() -> inthistory: Signal<readonly StoreHistoryEntry[]>messages: Signal<readonly StoreMessageRecord[]>currentIndex: Signal<number>keys: Signal<readonly StoreKey[]> (LazyStore: grows on first access)clearAllStores() -> calls clearAll() on every tracked store. Use for logout/tenant switch.this.api.getProducts().pipe(
syncToStore(this.store, 'LIST', {
completeOnFirstEmission: true, // default true (take(1))
callbackAfterComplete: () => {},
errorNormalizer: defaultErrorNormalizer, // default
deadLetterCommand: { type: '...', payload: {} },
})
).subscribe();Success -> { data, isLoading: false, status: 'Success', errors: undefined }.
Error -> { data: undefined, isLoading: false, status: 'Error', errors: normalized } + DLQ meta from HTTP-like errors.
this.api.getInvoice(id).pipe(
syncToKeyedStore(this.store, 'ITEMS', id, {
mapResponse: (r) => r.data, // optional response unwrap
completeOnFirstEmission: true,
callbackAfterComplete: () => {},
errorNormalizer,
deadLetterCommand,
})
).subscribe();Bootstraps isLoading: true for that key on subscribe (via defer). Per-key Success/Error; recomputes top-level isLoading from remaining keys.
@SkipIfCached(
storeKey,
(i) => i.store,
returnObservable = false,
timeoutMs = DEFAULT_CACHE_TTL_MS, // CACHE_NO_TIMEOUT for infinite
)Cache hit (skip) when: status === 'Success' OR isLoading === true, args match (JSON.stringify), TTL not expired.
Cache miss when: idle, status === 'Error', expired, or args changed.
Keyed: if first arg is string|number AND slot is KeyedResourceData, tracks cache per resourceKey automatically.
returnObservable: true -> uses shareReplay({ bufferSize: 1, refCount: true }) for in-flight dedup; method must return Observable.
@Loading(storeKey, (i) => i.store)Calls startLoading(key) before method. If first arg is string|number and store has startKeyedLoading, calls startKeyedLoading(key, resourceKey) instead.
@SkipIfCached MUST be outermost (short-circuits before loading). @Loading above @SkipIfCached -> potential infinite loading loops.
mirrorKey(sourceStore, sourceKey, targetStore, targetKey?, options?: MirrorOptions)
// MirrorOptions: { destroyRef?, direction?: 'bidirectional' | 'source-to-target' }
// Default direction: 'bidirectional' — updates flow both ways with loop guard.
// Set direction: 'source-to-target' for one-way mirroring.
// returns cleanup () => voidderiveKey(source, sourceKey, target, targetKey, {
mapData: (data, state) => mappedData,
destroyRef?,
})
// returns cleanup. Mirrors isLoading/status/errors, maps data.collectKeyed(source, sourceKey, target, targetKey?, {
extractId: (entity | undefined) => key | undefined,
destroyRef?,
})
// CollectKeyedOptions. Aggregates single-entity emissions into keyed cache.Default = in-memory.
Store.for<Config>().build({
channel: createLocalStorageStoreMessageChannel({
storageKey: 'app.store',
serialize?, // optional
deserialize?,
}),
});Factories:
createInMemoryStoreMessageChannel<TData>()createStorageStoreMessageChannel({ storage, storageKey, serialize?, deserialize? }) -- custom adapter; auto-evicts oldest on quota exceededcreateLocalStorageStoreMessageChannel({ storageKey, ... }) -- defaults storage to localStoragecreateSessionStorageStoreMessageChannel({ storageKey, ... }) -- session-scopedcreateCompositeStoreMessageChannel({ channels: [primary, ...replicas] }) -- fan-out writes; primary handles reads + id allocationStoreMessageChannelStorage: getItem | setItem | removeItem. Serializer handles undefined, Date, Map, Set, Array, plain objects.
defaultErrorNormalizer(err) checks in order:
{ error: { errors: [...] } } -> returns inner array{ status, message } -> [{ code: String(status), message }]Error -> [{ code: 'UNKNOWN', message: err.message }][{ code: 'UNKNOWN', message: String(err) }]httpErrorNormalizer (from flurryx/http):
HttpErrorResponse with error.errors array -> as-is[{ code: status, message }]UNKNOWN@Injectable()
export class ProductFacade {
private readonly api = inject(GetProductsUseCase);
readonly store = inject(ProductStore);
getProducts() { return this.store.get('LIST'); }
getProduct(id: string) { return this.store.get('ITEMS').for(id); }
@SkipIfCached('LIST', (i: ProductFacade) => i.store)
@Loading('LIST', (i: ProductFacade) => i.store)
loadProducts() {
this.api.execute().pipe(syncToStore(this.store, 'LIST')).subscribe();
}
@SkipIfCached('ITEMS', (i: ProductFacade) => i.store)
@Loading('ITEMS', (i: ProductFacade) => i.store)
loadProduct(id: string) {
this.api.byId(id).pipe(syncToKeyedStore(this.store, 'ITEMS', id)).subscribe();
}
}store MUST be public + readonly so decorator getters can reach it.
Same shape, @Injectable({ providedIn: 'root' }) service holds store.
@Component({
template: `
@if (state().isLoading) { <app-spinner/> }
@for (p of products(); track p.id) { ... }
`,
})
export class ProductListComponent {
private readonly facade = inject(ProductFacade);
readonly state = this.facade.getProducts();
readonly products = computed(() => this.state().data ?? []);
constructor() { this.facade.loadProducts(); }
}Read state().data | isLoading | status | errors. Use computed() for derived UI.
readonly id = input.required<string>();
readonly invoiceState = computed(() => this.facade.store.get('ITEMS').for(this.id())());.for(idOrSignal) is computed-safe and supports raw or signal keys. Snapshot reads state().data?.[id] still work.
export const SessionStore = Store.for<SessionStoreConfig>()
.mirror(CustomerStore, 'CUSTOMERS')
.mirrorSelf('CUSTOMER_DETAILS', 'CUSTOMER_SNAPSHOT')
.derive(OrdersStore, 'TOTAL', { mapData: (data) => formatTotal(data) })
.mirrorKeyed(InvoiceStore, 'DETAIL', { extractId: (inv) => inv?.id }, 'INVOICES')
.build();Mirrors propagate update + onCacheInvalidate. Self-mirror with same source/target throws.
store.clear('LIST') -> single slotstore.clearKeyedOne('ITEMS', id) -> one entry; also evicts that key's @SkipIfCached entriesstore.invalidateCacheFor('ITEMS', id) -> invalidate cache only, keep statestore.clearAll() -> all slots in this storeclearAllStores() -> every flurryx store (logout/tenant switch)cloneValue(v) -> deep clone (Date/Map/Set/Array/plain). Class instances with constructor side-effects don't survivecreateSnapshotRestorePatch(current, snapshot) -> partial patch to restorestore.undo(); store.redo();
store.restoreStoreAt(0); // snapshot nav, no broker
store.restoreResource('LIST', 5); // single-key restore
store.replay(12); // re-publish via broker
store.replay([12, 13, 14]);
store.replayDeadLetters(); // bool/int per id
store.replayDeadLetterCommand(id, async (entry) => ({ resolved: true, clear: true }));Dead letter entry: { id, message, attempts, error, httpStatus, httpMessage, command, failedAt }.
DLQ command meta on update -> update(key, state, { deadLetter: { error, httpStatus?, httpMessage?, command? } }). syncToStore/syncToKeyedStore populate this from HTTP-like errors automatically.
HttpClient when belongs in facade/adapter@SkipIfCached on always-fresh flows@Loading outside (above) @SkipIfCachedBehaviorSubject where store slot would own stateBaseStoresyncToStore / syncToKeyedStore for ad-hoc loading/error plumbingcomputed)| Task | API |
|---|---|
| Define store | Store.for<Config>().build() |
| Read slot | store.get('LIST') |
| Read keyed entry | store.get('ITEMS').for(id) |
| Write slot | store.update('LIST', { data }) |
| Write keyed entry | store.updateKeyedOne('ITEMS', id, entity) |
| Sync resource | syncToStore(store, 'LIST', opts?) |
| Sync keyed | syncToKeyedStore(store, 'ITEMS', id, opts?) |
| Skip cache | @SkipIfCached(key, (i)=>i.store, retObs?, ttl?) |
| Mark loading | @Loading(key, (i)=>i.store) |
| Mirror state | `.mirror |
| Standalone mirror | `mirrorKey |
| Clear slot | store.clear('LIST') |
| Clear keyed entry | store.clearKeyedOne('ITEMS', id) |
| Invalidate cache | store.invalidateCacheFor('ITEMS', id?) |
| Reset all stores | clearAllStores() |
| History | `undo |
| Channel | `createInMemory |
| Error norm | defaultErrorNormalizer / httpErrorNormalizer (from flurryx/http) |
© fmflurry, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/flurryx of fmflurry/settings-opencode.
Open the folder on GitHubat commit 0e6c33c
Flurryx next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Flurryx this skillfmflurry/settings-opencode | 171 | — | ~4.2k | Automated safety check: Pass | MIT | |
| Angular ArchitectJeffallan/claude-skills | 12k | — | ~1.5k | Automated safety check: Pass | MIT | |
| Angular Idioms and Patternsirahardianto/awesome-agv | 157 | — | ~3.8k | Automated safety check: Pass | MIT | |
| Angular State Managementaiskillstore/marketplace | 430 | 5 repos | ~3.9k | Automated safety check: Pass | None | |
| Tanstack Querybskimball/tanstack-hono | 119 | 1 repos | ~5.4k | Automated safety check: Pass | MIT | |
| Igniteui Angular ComponentsIgniteUI/igniteui-angular | 599 | — | ~1.7k | Automated safety check: Pass | MIT |
Jeffallan/claude-skills
Builds Angular 17+ features with standalone components, signals, NgRx state, RxJS patterns and lazy-loaded routing, then checks bundle size and test coverage.
irahardianto/awesome-agv
Coding conventions for Angular 19 and later: standalone components, signals, OnPush change detection, lazy routes and where RxJS still belongs.
aiskillstore/marketplace
Master modern Angular state management with Signals, NgRx, and RxJS.
bskimball/tanstack-hono
Powerful asynchronous state management, server-state utilities, and data fetching for TS/JS, React, Vue, Solid, Svelte & Angular.
IgniteUI/igniteui-angular
Covers all non-grid Ignite UI for Angular UI components: application scaffolding and setup, form controls (inputs, combos, selects, date/time pickers, calendar, checkbox, radio, switch, slider)…
olorehq/olore
Local tanstack-store documentation reference (latest). An agent skill from olorehq/olore.
fmflurry/settings-opencode
Keep a reviewable decision trail for long-running or unattended work: a TSV log with one row per decision (what, why, evidence, result).
fmflurry/settings-opencode
Scaffold and extend Playwright E2E tests for the gc.platform suite (tests/playwright), wiring every artifact to the real frontend (localhost:4200) + real .NET backend — never mocks.
fmflurry/settings-opencode
A skill your agent uses for 'why does X work this way', 'why we picked Y', design rationale, regressions, postmortems, or data-backed thresholds.
fmflurry/settings-opencode
Audit and fix common accessibility issues in Angular templates and Angular Material components.
fmflurry/settings-opencode
Scaffolds and extends Angular standalone feature MODULES under src/app/modules/{name} using Clean Architecture layering (presentation/application/core/infrastructure), a self-registering module…
fmflurry/settings-opencode
Pre-merge code review for Angular + TypeScript pull requests.
Categories
Signal-first reactive state management for Angular. An agent skill from fmflurry/settings-opencode. Flurryx is an agent skill from fmflurry/settings-opencode. Signal-first reactive state management for Angular.
Flurryx fits situations like: modifying Angular code that uses flurryx for state management; scaffolding new feature modules that follow the flurryx facade pattern.
Run `npx skills add fmflurry/settings-opencode --skill flurryx -a claude-code`. Or copy the skill folder (skills/flurryx in fmflurry/settings-opencode) into .claude/skills/flurryx in your project. Claude Code loads it when a task matches its description.
Run `npx skills add fmflurry/settings-opencode --skill flurryx -a codex`. Or copy the skill folder (skills/flurryx in fmflurry/settings-opencode) into .agents/skills/flurryx in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add fmflurry/settings-opencode --skill flurryx -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/flurryx, .gemini/skills/flurryx, .github/skills/flurryx and .opencode/skills/flurryx in your project.
SKILL.md names no scripts, command-line tools or credentials: Flurryx is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Flurryx is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.2k tokens (SKILL.md is roughly 17k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Flurryx: Angular Architect (Jeffallan/claude-skills, 12k stars), Angular Idioms and Patterns (irahardianto/awesome-agv, 157 stars), Angular State Management (aiskillstore/marketplace, 430 stars) and Tanstack Query (bskimball/tanstack-hono, 119 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
fmflurry (a GitHub user) maintains it in fmflurry/settings-opencode, which has 171 GitHub stars. The repository holds 20 skills in this directory. The repository was last updated on October 7, 2026.
Source: fmflurry/settings-opencode on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.