Agent skill

Flurryx

by fmflurry in fmflurry/settings-opencode

Signal-first reactive state management for Angular. An agent skill from fmflurry/settings-opencode.

MITAuto-check passedFrontend & Design

Install Flurryx

skills CLI
$ npx skills add fmflurry/settings-opencode --skill flurryx -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install fmflurry/settings-opencode flurryx --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ 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-src

Use ~/.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/

Facts

Skill name
flurryx
GitHub stars
171
Token cost
~4.2k tokens
SKILL.md length
964 words
Files
1
Skills in repo
20
Repo updated
First seen
Licence
MIT

At a glance

Signal-first reactive state management for Angular. An agent skill from fmflurry/settings-opencode.

  • Works in 4 steps: { error: { errors: [...] } } -> returns… → { status, message } -> [{ code:… → Error -> [{ code: 'UNKNOWN', message:… → …
  • Modifying Angular code that uses flurryx for state management
  • SKILL.md covers When to Activate, Imports, Hard Rules and Core Flow, plus 7 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

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.

When your agent uses it

  • Modifying Angular code that uses flurryx for state management
  • Scaffolding new feature modules that follow the flurryx facade pattern

Example prompts

  • “/flurryx”

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. { error: { errors: [...] } } -> returns inner array
  2. { status, message } -> [{ code: String(status), message }]
  3. Error -> [{ code: 'UNKNOWN', message: err.message }]
  4. else -> [{ code: 'UNKNOWN', message: String(err) }]

What it can do on your machine

Read from SKILL.md and the folder at commit 0e6c33c. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    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.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

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.

Always · name and description, kept in context so the agent knows when to use it
~82
When it runs · the whole SKILL.md, loaded when a task matches
~4.2k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from fmflurry/settings-opencode at commit 0e6c33c, republished under its MIT licence (© fmflurry). 964 words, ~4,232 tokens.

Download SKILL.mdSave it as .claude/skills/flurryx/SKILL.md (or your agent's skills folder).
name
flurryx
description
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.

flurryx

Signal-first reactive state management for Angular. RxJS in, signals out.

When to Activate

  • Build/modify state with Store, syncToStore, syncToKeyedStore
  • Add facades/services exposing flurryx-backed signals
  • Scaffold feature modules using flurryx for async state, caching, keyed resources
  • Per-entity caches via KeyedResourceData<TKey, TValue>
  • Mirroring/derivation: mirror, mirrorSelf, derive, deriveSelf, mirrorKeyed, mirrorKey, deriveKey, collectKeyed
  • Channel persistence, history, replay, dead-letter recovery
  • Reviewing AI-generated Angular code for flurryx correctness

Imports

ts
// 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.

Hard Rules

  • Never any
  • Components read signals only. Facade/service owns subscriptions + writes
  • Prefer Store.for<Config>().build() interface builder
  • UPPER_SNAKE_CASE keys: LIST, DETAIL, ITEMS
  • @SkipIfCached outermost, @Loading directly beneath
  • Use @SkipIfCached only if cache hits are intended; else omit
  • Keyed resources -> syncToKeyedStore, not hand-rolled Record updates
  • Don't subclass BaseStore directly
  • Don't call component methods in templates -> use computed

Core Flow

Observable -> syncToStore / syncToKeyedStore -> Store signal -> Template

ResourceState<T>

Every slot wraps ResourceState<T>:

ts
interface ResourceState<T> {
  isLoading?: boolean;
  data?: T;
  status?: 'Success' | 'Error';
  errors?: Array<{ code: string; message: string }>;
}

Lifecycle: idle -> loading -> Success | Error.

KeyedResourceData

Per-entity cache:

ts
type KeyedResourceData<TKey extends string | number, TValue> =
  Partial<Record<TKey, ResourceState<TValue>>>;

Helpers:

  • createKeyedResourceData<TKey, TValue>() -> {}
  • isKeyedResourceData(val) -> type guard
  • isAnyKeyLoading(data) -> bool

Store Builder

Interface form (preferred)
ts
interface 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>.

Enum-constrained form
ts
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.

Fluent form
ts
export const ProductStore = Store
  .resource('LIST').as<Product[]>()
  .resource('DETAIL').as<Product>()
  .build();
Builder methods (all forms)
  • .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.

IStore API

store.get(key) returns:

  • non-keyed slot -> Signal<ResourceState<T>>
  • keyed slot -> KeyedStoreSignal<TData, K> = signal + .for(resourceKey | Signal<resourceKey>) -> Signal<ResourceState<TValue>>
Writes (publish broker messages)
  • update(key, partial, options?) -> merge partial; options.deadLetter?: StoreDeadLetterMeta
  • clear(key) -> reset slot to idle
  • clearAll() -> reset every slot
  • startLoading(key) / stopLoading(key)
  • updateKeyedOne(key, resourceKey, entity) -> sets entity status Success, recomputes top-level isLoading
  • clearKeyedOne(key, resourceKey) -> remove single keyed entry
  • startKeyedLoading(key, resourceKey) -> mark single key loading
Cache invalidation
  • invalidateCacheFor(key) -> invalidate slot cache only (state untouched)
  • invalidateCacheFor(key, resourceKey) -> invalidate one keyed entry's cache
Hooks
  • onUpdate(key, (next, prev) => …) -> () => void cleanup
  • onCacheInvalidate(key, ({ key, resourceKey }) => …) -> cleanup
  • Hook errors are caught + rethrown via queueMicrotask/AggregateError
History / Replay
  • replay(id | ids[]) -> re-execute persisted channel messages -> int (acked count)
  • restoreStoreAt(index) -> snapshot navigation (no message)
  • restoreResource(key, index?) -> restore single key from snapshot
  • undo() / redo() -> bool
  • getHistory() / getHistory(key) -> readonly entries
  • getMessages() / getMessages(key) -> channel records
  • getDeadLetters() -> dead-letter entries
  • replayDeadLetter(id) -> bool
  • replayDeadLetters() -> int (acked)
  • replayDeadLetterCommand(id, async resolver -> { resolved, clear }) -> Promise<bool>
  • getCurrentIndex() -> int
Reactive signals on store
  • history: Signal<readonly StoreHistoryEntry[]>
  • messages: Signal<readonly StoreMessageRecord[]>
  • currentIndex: Signal<number>
  • keys: Signal<readonly StoreKey[]> (LazyStore: grows on first access)
Global
  • clearAllStores() -> calls clearAll() on every tracked store. Use for logout/tenant switch.

Rx Operators

syncToStore
ts
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.

syncToKeyedStore
ts
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.

Decorators

@SkipIfCached
ts
@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
ts
@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.

Composition

@SkipIfCached MUST be outermost (short-circuits before loading). @Loading above @SkipIfCached -> potential infinite loading loops.

Standalone Functions

mirrorKey
ts
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 () => void
deriveKey
ts
deriveKey(source, sourceKey, target, targetKey, {
  mapData: (data, state) => mappedData,
  destroyRef?,
})
// returns cleanup. Mirrors isLoading/status/errors, maps data.
collectKeyed
ts
collectKeyed(source, sourceKey, target, targetKey?, {
  extractId: (entity | undefined) => key | undefined,
  destroyRef?,
})
// CollectKeyedOptions. Aggregates single-entity emissions into keyed cache.
Show full SKILL.md (402 more words)Show less

Message Channels

Default = in-memory.

ts
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 exceeded
  • createLocalStorageStoreMessageChannel({ storageKey, ... }) -- defaults storage to localStorage
  • createSessionStorageStoreMessageChannel({ storageKey, ... }) -- session-scoped
  • createCompositeStoreMessageChannel({ channels: [primary, ...replicas] }) -- fan-out writes; primary handles reads + id allocation

StoreMessageChannelStorage: getItem | setItem | removeItem. Serializer handles undefined, Date, Map, Set, Array, plain objects.

Error Normalizers

defaultErrorNormalizer(err) checks in order:

  1. { error: { errors: [...] } } -> returns inner array
  2. { status, message } -> [{ code: String(status), message }]
  3. Error -> [{ code: 'UNKNOWN', message: err.message }]
  4. else -> [{ code: 'UNKNOWN', message: String(err) }]

httpErrorNormalizer (from flurryx/http):

  • HttpErrorResponse with error.errors array -> as-is
  • else -> [{ code: status, message }]
  • non-HTTP -> fallback UNKNOWN

Patterns

Facade (preferred when codebase uses facades)
ts
@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.

Service-led (when no facade layer)

Same shape, @Injectable({ providedIn: 'root' }) service holds store.

Component
ts
@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.

Keyed reads in component
ts
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.

Mirroring at builder level
ts
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.

Lifecycle / Resets

  • store.clear('LIST') -> single slot
  • store.clearKeyedOne('ITEMS', id) -> one entry; also evicts that key's @SkipIfCached entries
  • store.invalidateCacheFor('ITEMS', id) -> invalidate cache only, keep state
  • store.clearAll() -> all slots in this store
  • clearAllStores() -> every flurryx store (logout/tenant switch)
  • cloneValue(v) -> deep clone (Date/Map/Set/Array/plain). Class instances with constructor side-effects don't survive
  • createSnapshotRestorePatch(current, snapshot) -> partial patch to restore

Replay & Dead Letters

ts
store.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.

Anti-Patterns

  • Component subscribes to flurryx fetches
  • Component mutates store directly
  • Component injects HttpClient when belongs in facade/adapter
  • DTOs into presentation models when mapper exists
  • @SkipIfCached on always-fresh flows
  • @Loading outside (above) @SkipIfCached
  • BehaviorSubject where store slot would own state
  • Subclassing BaseStore
  • Bypassing syncToStore / syncToKeyedStore for ad-hoc loading/error plumbing
  • Calling component methods in templates (use computed)

Quick Reference

TaskAPI
Define storeStore.for<Config>().build()
Read slotstore.get('LIST')
Read keyed entrystore.get('ITEMS').for(id)
Write slotstore.update('LIST', { data })
Write keyed entrystore.updateKeyedOne('ITEMS', id, entity)
Sync resourcesyncToStore(store, 'LIST', opts?)
Sync keyedsyncToKeyedStore(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 slotstore.clear('LIST')
Clear keyed entrystore.clearKeyedOne('ITEMS', id)
Invalidate cachestore.invalidateCacheFor('ITEMS', id?)
Reset all storesclearAllStores()
History`undo
Channel`createInMemory
Error normdefaultErrorNormalizer / 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

Files

Just SKILL.md in skills/flurryx of fmflurry/settings-opencode.

Open the folder on GitHubat commit 0e6c33c

Compare with similar skills

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.

Flurryx compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Flurryx this skillfmflurry/settings-opencode171—~4.2kAutomated safety check: PassMIT
Angular ArchitectJeffallan/claude-skills12k—~1.5kAutomated safety check: PassMIT
Angular Idioms and Patternsirahardianto/awesome-agv157—~3.8kAutomated safety check: PassMIT
Angular State Managementaiskillstore/marketplace4305 repos~3.9kAutomated safety check: PassNone
Tanstack Querybskimball/tanstack-hono1191 repos~5.4kAutomated safety check: PassMIT
Igniteui Angular ComponentsIgniteUI/igniteui-angular599—~1.7kAutomated safety check: PassMIT

Similar skills

  • 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.

    12k GitHub stars~1.5k tokensUpdated 6 days ago
    Frontend & DesignAuto-check passed
  • Angular Idioms and Patterns

    irahardianto/awesome-agv

    Coding conventions for Angular 19 and later: standalone components, signals, OnPush change detection, lazy routes and where RxJS still belongs.

    157 GitHub stars~3.8k tokensUpdated 5 days ago
    Frontend & DesignAuto-check passed
  • Angular State Management

    aiskillstore/marketplace

    Master modern Angular state management with Signals, NgRx, and RxJS.

    430 GitHub starsUsed in 5 repos~3.9k tokens
    Frontend & DesignAuto-check passed
  • Tanstack Query

    bskimball/tanstack-hono

    Powerful asynchronous state management, server-state utilities, and data fetching for TS/JS, React, Vue, Solid, Svelte & Angular.

    119 GitHub starsUsed in 1 repo~5.4k tokens
    Frontend & DesignAuto-check passed
  • Igniteui Angular Components

    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)…

    599 GitHub stars~1.7k tokensUpdated today
    Frontend & DesignAuto-check passed
  • Local tanstack-store documentation reference (latest). An agent skill from olorehq/olore.

    104 GitHub stars~1.2k tokensUpdated yesterday
    Frontend & DesignAuto-check passed

More from fmflurry/settings-opencode

All 20 skills in this repo
  • Show Your Work

    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).

    171 GitHub stars~1.8k tokensUpdated 2 days ago
    Auto-check passed
  • Playwright E2E Authoring

    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.

    171 GitHub stars~2.4k tokensUpdated 2 days ago
    Auto-check passed
  • Why

    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.

    171 GitHub stars~2k tokensUpdated 2 days ago
    Auto-check passed
  • Angular Accessibility

    fmflurry/settings-opencode

    Audit and fix common accessibility issues in Angular templates and Angular Material components.

    171 GitHub stars~2.7k tokensUpdated 2 days ago
    Auto-check passed
  • Angular Clean Architecture

    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…

    171 GitHub stars~3.6k tokensUpdated 2 days ago
    Auto-check passed
  • Angular Cop

    fmflurry/settings-opencode

    Pre-merge code review for Angular + TypeScript pull requests.

    171 GitHub stars~1.4k tokensUpdated 2 days ago
    Auto-check passed

Works with

Questions about Flurryx

What does Flurryx do?

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.

When should I use Flurryx?

Flurryx fits situations like: modifying Angular code that uses flurryx for state management; scaffolding new feature modules that follow the flurryx facade pattern.

How do I install Flurryx in Claude Code?

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.

How do I install Flurryx in Codex?

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.

Can I use Flurryx in Cursor, Gemini CLI or GitHub Copilot?

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.

What does Flurryx need to run?

SKILL.md names no scripts, command-line tools or credentials: Flurryx is instructions for the agent only.

Does Flurryx access the network?

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.

Is Flurryx safe to install?

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.

What licence does Flurryx use?

Flurryx is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Flurryx use?

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.

What are the alternatives to Flurryx?

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.

Who maintains Flurryx?

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.