Agent skill

Equatable Linkedhashmap Lru Reorder

by divinevideo in divinevideo/divine-mobile

Fix LRU-bounded Flutter/bloc state classes that silently lose insertion-order updates.

MPL-2.0Auto-check passedMobile

Install Equatable Linkedhashmap Lru Reorder

skills CLI
$ npx skills add divinevideo/divine-mobile --skill equatable-linkedhashmap-lru-reorder -a claude-code

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

GitHub CLI
$ gh skill install divinevideo/divine-mobile equatable-linkedhashmap-lru-reorder --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/divinevideo/divine-mobile.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/equatable-linkedhashmap-lru-reorder .claude/skills/equatable-linkedhashmap-lru-reorder && 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
equatable-linkedhashmap-lru-reorder
GitHub stars
266
Token cost
~2k tokens
SKILL.md length
555 words
Files
1
Skills in repo
103
Repo updated
First seen
Licence
MPL-2.0

At a glance

Fix LRU-bounded Flutter/bloc state classes that silently lose insertion-order updates.

  • Works in 2 steps: Defensive-copy in the constructor if it… → Short-circuit redundant writes in the…
  • A state class uses Equatable with a LinkedHashMap<K
  • SKILL.md covers Problem, Context / Trigger Conditions, Solution and Verification, plus 3 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Equatable Linkedhashmap Lru Reorder is an agent skill from divinevideo/divine-mobile. Fix LRU-bounded Flutter/bloc state classes that silently lose insertion-order updates. Use when: (1) a state class uses Equatable with a LinkedHashMap<K, V field to preserve insertion order (LRU, MRU, recent-items caches), (2) Cubit.emit appears to drop emissions when an existing key is re-inserted or moved to most-recent, (3) LRU eviction evicts the "wrong" entry after a refresh, (4) a test that reports the same key twice and then overflows the cap sees the refreshed entry evicted instead of the oldest. Root…

Its SKILL.md is about 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 Mobile, covering Cross-platform mobile apps and Root cause analysis. It works with Flutter. The licence is MPL-2.0.

When your agent uses it

  • A state class uses Equatable with a LinkedHashMap<K
  • V field to preserve insertion order (LRU
  • Recent-items caches)
  • Cubit.emit appears to drop emissions when an existing key is re-inserted

Example prompts

  • “/equatable-linkedhashmap-lru-reorder”

Workflow steps

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

  1. Defensive-copy in the constructor if it accepts an externally-built
  2. Short-circuit redundant writes in the cubit to avoid allocating a

What it can do on your machine

Read from SKILL.md and the folder at commit 6487b05. 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 dart).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • pub.dev
    • api.dart.dev

    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

Equatable Linkedhashmap Lru Reorder loads about 2k tokens when it runs. Until then it costs about 181 tokens; SKILL.md has 555 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~181
When it runs · the whole SKILL.md, loaded when a task matches
~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 divinevideo/divine-mobile at commit 6487b05, republished under its MPL-2.0 licence (© divinevideo). 555 words, ~2,030 tokens.

Download SKILL.mdSave it as .claude/skills/equatable-linkedhashmap-lru-reorder/SKILL.md (or your agent's skills folder).
name
equatable-linkedhashmap-lru-reorder
description
Fix LRU-bounded Flutter/bloc state classes that silently lose insertion-order updates. Use when: (1) a state class uses `Equatable` with a `LinkedHashMap<K, V>` field to preserve insertion order (LRU, MRU, recent-items caches), (2) `Cubit.emit` appears to drop emissions when an existing key is re-inserted or moved to most-recent, (3) LRU eviction evicts the "wrong" entry after a refresh, (4) a test that reports the same key twice and then overflows the cap sees the refreshed entry evicted instead of the oldest. Root cause: Equatable's default map comparison is structural (unordered), so reordering without changing keys/values produces an "equal" state that `Cubit.emit` suppresses.
author
Claude Code
version
1.0.0
date
2026-04-05

Equatable + LinkedHashMap LRU reorder suppression

Problem

A Flutter bloc/cubit state class uses an insertion-ordered LinkedHashMap<K, V> to implement LRU semantics (touch-on-access, evict oldest past a cap). The field is included in props for value equality. When an existing key is re-inserted to move it to most-recent, Cubit.emit drops the new state as equal to the previous one, leaving LRU order stale. On the next insert past the cap, the "touched" entry is evicted instead of the truly oldest one.

This is silent: no errors, no logs. Tests that only check the final status of each key pass. The bug surfaces only when a test specifically asserts that a refreshed key survives a later cap-overflow eviction.

Context / Trigger Conditions

  • State class extends Equatable with a LinkedHashMap<K, V> field
  • LRU behavior implemented via remove(key) + insert to move-to-most-recent
  • props includes the map directly: List<Object?> get props => [_map, ...]
  • Symptoms:
    • blocTest(..., expect: () => hasLength(N)) reports fewer emissions than expected
    • LRU eviction test like "refresh key A, then overflow — expect B evicted" fails with A evicted instead
    • Consumers using BlocListener or context.select don't react to touch-only updates

Solution

Add the keys list to props alongside the map so insertion-order changes produce a distinct state:

dart
@override
List<Object?> get props {
  // Both entries are required.
  //
  // Equatable's default map comparison is structural (unordered), so
  // `_statuses` alone catches value changes but NOT pure LRU reorders
  // where the key/value set is unchanged.
  // `_statuses.keys.toList()` catches those insertion-order changes.
  // Removing either would silently suppress a whole class of state
  // updates — do not "simplify" this.
  return [_statuses, _statuses.keys.toList(), maxEntries];
}

Keep the map in props as well — it catches value-only changes (same key, different value, no reorder). The keys list catches order-only changes. Together they cover both dimensions. Removing either re-opens the bug.

While you're here, also:

  1. Defensive-copy in the constructor if it accepts an externally-built LinkedHashMap. A caller can otherwise retain a reference and mutate the "immutable" state:

    dart
    VideoPlaybackStatusState({
      this.maxEntries = _defaultMaxEntries,
      LinkedHashMap<K, V>? statuses,
    }) : _statuses = statuses == null
              ? LinkedHashMap<K, V>()
              : LinkedHashMap<K, V>.from(statuses);
  2. Short-circuit redundant writes in the cubit to avoid allocating a new map on every no-op report (e.g. errorBuilder fires every frame during a retry):

    dart
    void report(K key, V value) {
      if (state.valueFor(key) == value) return;
      emit(state.withValue(key, value));
    }

Verification

Write an explicit props-inequality test that pins the invariant directly, rather than relying on higher-level LRU tests to transitively catch it:

dart
test('states with same entries but different LRU order are not equal', () {
  final a = MyState()
      .withStatus(idA, Status.foo)
      .withStatus(idB, Status.bar);
  final b = MyState()
      .withStatus(idB, Status.bar)
      .withStatus(idA, Status.foo);

  expect(a, isNot(equals(b)));
});

Mutation test: temporarily revert to props: [_map, maxEntries] (no keys list) and run the test. It MUST fail. Restore and confirm pass. This proves the assertion is load-bearing and guards the invariant.

Show full SKILL.md (216 more words)Show less

Example

Full state class shape (Dart):

dart
import 'dart:collection';
import 'package:equatable/equatable.dart';

class VideoPlaybackStatusState extends Equatable {
  VideoPlaybackStatusState({
    this.maxEntries = _defaultMaxEntries,
    LinkedHashMap<String, PlaybackStatus>? statuses,
  }) : _statuses = statuses == null
            ? LinkedHashMap<String, PlaybackStatus>()
            : LinkedHashMap<String, PlaybackStatus>.from(statuses);

  static const int _defaultMaxEntries = 100;
  final int maxEntries;
  final LinkedHashMap<String, PlaybackStatus> _statuses;

  PlaybackStatus statusFor(String id) =>
      _statuses[id] ?? PlaybackStatus.ready;

  VideoPlaybackStatusState withStatus(String id, PlaybackStatus status) {
    final next = LinkedHashMap<String, PlaybackStatus>.from(_statuses)
      ..remove(id)
      ..[id] = status;
    while (next.length > maxEntries) {
      next.remove(next.keys.first);
    }
    return VideoPlaybackStatusState(maxEntries: maxEntries, statuses: next);
  }

  @override
  List<Object?> get props => [_statuses, _statuses.keys.toList(), maxEntries];
  //                         ^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^
  //                         catches      catches reorders
  //                         value changes (LRU touches)
}

The LRU test that catches the bug:

dart
test('reporting same id twice moves it to most-recent', () {
  final cubit = VideoPlaybackStatusCubit(maxEntries: 2);
  cubit.report(id1, PlaybackStatus.forbidden);
  cubit.report(id2, PlaybackStatus.ageRestricted);
  cubit.report(id1, PlaybackStatus.forbidden); // refresh id1
  cubit.report(id3, PlaybackStatus.notFound);  // overflow

  // Without the fix: id1 is evicted (wrong — it was just touched)
  // With the fix: id2 is evicted (correct — it's the oldest)
  expect(cubit.state.statusFor(id2), PlaybackStatus.ready);
  expect(cubit.state.statusFor(id1), PlaybackStatus.forbidden);
});

Notes

  • Flutter lint interaction: Using an explicit LinkedHashMap<K, V>() literal trips prefer_collection_literals (the lint wants {}). But {} types as Map<K, V>, not LinkedHashMap, which loses the compile-time guarantee that insertion order is preserved across refactors. Keep the explicit type and suppress the lint locally (// ignore: prefer_collection_literals) if the constructor path triggers it.
  • Applies to any ordered collection in Equatable: Queue, SplayTreeMap, or any structure where order is semantic. Anywhere Equatable compares the structure contents unordered but your code depends on order, you need a secondary props entry that captures the order.
  • Not specific to bloc: the same bug appears with Riverpod's state notifier == checks and any equality-based diffing. Same fix applies.
  • TDD discipline: this bug was only caught because a test specifically asserted "refreshed key survives overflow." A test suite that only checks "status X maps to key Y" after individual writes would pass with the bug intact. When writing tests for ordered-collection state, always include at least one test that exercises the ordering itself (not just membership).

References

© divinevideo, MPL-2.0. 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 .agents/skills/equatable-linkedhashmap-lru-reorder of divinevideo/divine-mobile.

Open the folder on GitHubat commit 6487b05

Compare with similar skills

Equatable Linkedhashmap Lru Reorder 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.

Equatable Linkedhashmap Lru Reorder compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Equatable Linkedhashmap Lru Reorder this skilldivinevideo/divine-mobile266—~2kAutomated safety check: PassMPL-2.0
Add Flutter Docusaurus Localematthiasn/lotti1.2k—~1.2kAutomated safety check: PassGPL-3.0
Tm Launcher DesignFar-Se/tabame372—~3.1kAutomated safety check: PassMIT
Flutter Initbear2u/my-skills933—~2.5kAutomated safety check: PassNone
Mobile App UI Designceorkm/mobile-app-ui-design403—~2kAutomated safety check: PassNone
Marionette Flutter Drive Appleancodepl/marionette_mcp482—~11kAutomated safety check: PassApache-2.0

Similar skills

  • Add, complete, or audit a locale across a Flutter application's ARB catalogs and a localized Docusaurus manual, including generated localization code, locale selectors, native platform declarations…

    1.2k GitHub stars~1.2k tokensUpdated today
    MobileAuto-check passed
  • Tm Launcher Design

    Far-Se/tabame

    Create or revise Tabame's Flutter launcher designs: frames, search bars, result rows, palettes, typography, and action dialogs.

    372 GitHub stars~3.1k tokensUpdated 2 days ago
    MobileAuto-check passed
  • Flutter Init

    bear2u/my-skills

    A skill your agent uses when user wants to create a new Flutter project (Todo/Habit/Note/Expense/Custom domain) with Clean Architecture, Riverpod 3.0, Drift, and modern Flutter stack

    933 GitHub stars~2.5k tokensUpdated 3 mo ago
    MobileAuto-check passed
  • Mobile App UI Design

    ceorkm/mobile-app-ui-design

    Design high-quality mobile app UI/UX screens, flows, and components.

    403 GitHub stars~2k tokensUpdated 3 mo ago
    MobileAuto-check passed
  • Marionette Flutter Drive App

    leancodepl/marionette_mcp

    Set up and drive a running Flutter app (debug or profile) with Marionette — an AI agent's hands and eyes for the app.

    482 GitHub stars~11k tokensUpdated 4 days ago
    MobileAuto-check passed
  • Flutter Screenshot

    JustLookAtNow/pt_mate

    Capture and show two Flutter UI screenshots for this project: one landscape/large-screen preview and one portrait/mobile preview, without using Flutter Web.

    503 GitHub stars~511 tokensUpdated 4 days ago
    MobileAuto-check passed

More from divinevideo/divine-mobile

All 103 skills in this repo
  • Fix ArgoCD ExternalSecret deployment failing with "namespace X is not permitted in project Y".

    266 GitHub stars~931 tokensUpdated today
    Auto-check passed
  • Art Direct

    divinevideo/divine-mobile

    Art direction for any content — reads text, PDF, Word, HTML, PPT, then proposes 2-3 creative directions with photography style, mood, and visual language.

    266 GitHub stars~4.8k tokensUpdated today
    Auto-check passed
  • Async Await Null Race Condition

    divinevideo/divine-mobile

    Fix "Null check operator used on a null value" errors when an object is set to null during an async await.

    266 GitHub stars~881 tokensUpdated today
    Auto-check passed
  • AWS V4 Signing Custom Headers Gcs

    divinevideo/divine-mobile

    Add custom metadata headers (x-amz-meta-) to AWS v4 signed requests for GCS S3-compatible API.

    266 GitHub stars~1k tokensUpdated today
    Auto-check passed
  • Bash Herestring Newline Secrets

    divinevideo/divine-mobile

    Fix password/secret authentication failures caused by trailing newlines when creating Google Cloud secrets (or similar) with bash here-strings.

    266 GitHub stars~791 tokensUpdated today
    Auto-check passed
  • Fix silent video/media processing failures caused by URL extraction code that filters on file extensions (.mp4, .webm, .webp).

    266 GitHub stars~1.1k tokensUpdated today
    Auto-check passed

Works with

Categories

Questions about Equatable Linkedhashmap Lru Reorder

What does Equatable Linkedhashmap Lru Reorder do?

Fix LRU-bounded Flutter/bloc state classes that silently lose insertion-order updates. Equatable Linkedhashmap Lru Reorder is an agent skill from divinevideo/divine-mobile. Fix LRU-bounded Flutter/bloc state classes that silently lose insertion-order updates.

When should I use Equatable Linkedhashmap Lru Reorder?

Equatable Linkedhashmap Lru Reorder fits situations like: A state class uses Equatable with a LinkedHashMap<K; V field to preserve insertion order (LRU; recent-items caches); cubit.emit appears to drop emissions when an existing key is re-inserted.

How do I install Equatable Linkedhashmap Lru Reorder in Claude Code?

Run `npx skills add divinevideo/divine-mobile --skill equatable-linkedhashmap-lru-reorder -a claude-code`. Or copy the skill folder (.agents/skills/equatable-linkedhashmap-lru-reorder in divinevideo/divine-mobile) into .claude/skills/equatable-linkedhashmap-lru-reorder in your project. Claude Code loads it when a task matches its description.

How do I install Equatable Linkedhashmap Lru Reorder in Codex?

Run `npx skills add divinevideo/divine-mobile --skill equatable-linkedhashmap-lru-reorder -a codex`. Or copy the skill folder (.agents/skills/equatable-linkedhashmap-lru-reorder in divinevideo/divine-mobile) into .agents/skills/equatable-linkedhashmap-lru-reorder in your project. Codex loads it when a task matches its description.

Can I use Equatable Linkedhashmap Lru Reorder 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 divinevideo/divine-mobile --skill equatable-linkedhashmap-lru-reorder -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/equatable-linkedhashmap-lru-reorder, .gemini/skills/equatable-linkedhashmap-lru-reorder, .github/skills/equatable-linkedhashmap-lru-reorder and .opencode/skills/equatable-linkedhashmap-lru-reorder in your project.

What does Equatable Linkedhashmap Lru Reorder need to run?

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

Does Equatable Linkedhashmap Lru Reorder access the network?

SKILL.md names 2 domains. As links in the text: pub.dev and api.dart.dev. This is read from the text; nothing was executed.

Is Equatable Linkedhashmap Lru Reorder 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 Equatable Linkedhashmap Lru Reorder use?

Equatable Linkedhashmap Lru Reorder is published under the MPL-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Equatable Linkedhashmap Lru Reorder use?

About 2k tokens (SKILL.md is roughly 8.1k 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 Equatable Linkedhashmap Lru Reorder?

Skills that share tags, products or a category with Equatable Linkedhashmap Lru Reorder: Add Flutter Docusaurus Locale (matthiasn/lotti, 1.2k stars), Tm Launcher Design (Far-Se/tabame, 372 stars), Flutter Init (bear2u/my-skills, 933 stars) and Mobile App UI Design (ceorkm/mobile-app-ui-design, 403 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Equatable Linkedhashmap Lru Reorder?

divinevideo (a GitHub organization) maintains it in divinevideo/divine-mobile, which has 266 GitHub stars. The repository holds 103 skills in this directory. The repository was last updated on October 9, 2026.

Source: divinevideo/divine-mobile on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.