agentleFS
rosslevinskyrosslevinsky/portable-agent-skills/skills/extract-hooks/SKILL.md

extract-hooks

Skill12 starsChanged 43 days agoApache-2.0View on GitHub

Audit TSX files, identify non-UI logic, and extract it into custom hooks. Use when the user invokes /extract-hooks, or says "extract hooks", "move logic out of components", or "separate logic from layout".

The file

Show its rules and text

We split this skill into the rules it gives an agent

16 rules. About 0 are common, 12 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈12

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Do not propose a hook that is just a thin wrapper around a single useState — only extract when it improves reuse, readability, or separates …

    line 44
  2. Distinctive:

    After presenting the recommendation table, ask the user exactly this:

    line 52
  3. Distinctive:

    Do not proceed to Phase 4 until the user responds: If operating autonomously (no user available), default to implementing high priority …

    line 60
  4. Distinctive:

    If the hooks directory does not exist, create it at the project-appropriate path before writing any hooks.

    line 68
  5. Distinctive:

    Define the hook API: before writing any code:

    line 72
  6. Distinctive:

    Keep dependency arrays accurate

    line 85
  7. Distinctive:

    If extraction reveals unrelated responsibilities in the same block, split into multiple hooks rather than bundling them

    line 88
  8. Distinctive:

    Verify: after each hook:

    line 90
  9. Distinctive:

    Run existing tests if available

    line 91
  10. Distinctive:

    Run lint/typecheck if available

    line 92
  11. Very specific:

    When every approved hook is implemented — not every candidate.

    line 99
  12. Very specific:

    If the answer was none, the run ended at Phase 3 and there is nothing here to do.

    line 102
  13. Very specific:

    Run the cyw skill to review the work.

    line 104
  14. Distinctive:

    Prefer placing hooks close to the component that uses them unless the logic is clearly shared across multiple components.

    line 119
  15. Distinctive:

    Follow the project's existing naming conventions, import style, and file structure throughout.

    line 120
  16. Distinctive:

    Follow the project's CLAUDE.md / AGENTS.md conventions (whichever exists).

    line 121

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Extract Hooks

Move non-UI logic out of .tsx files into custom use*.ts hooks, so that .tsx files contain only layout and hook calls, without changing behavior.

Non-UI logic includes: useState, useEffect, event handlers, API calls, data fetching, data transforms, validation, derived state, and business rules.


Phase 1 — Inventory

  1. Find all .tsx files. For each, read it and record:
    • Total lines and approximate lines of non-UI logic vs. layout/JSX
    • Categories of logic present (state, API calls, event handlers, validation, derived state, etc.)
    • Whether the same or similar logic appears in another .tsx file (duplication)
  2. Find the existing hooks directory. Note whether it exists and where it should be created if not, based on project structure conventions.
  3. List any existing use*.ts or use*.tsx files and what they do — do not duplicate them.
  4. Present the inventory to the user as a table before proceeding. If no .tsx file contains extractable logic, report that and stop.

Phase 2 — Recommend

Propose a list of new hook files. For each hook:

  • Name and signature — e.g. useRoomForm(existingRoom?: Room): { fields, handlers, submit }
  • Encapsulates — what logic it extracts
  • Replaces logic in — which .tsx files benefit
  • Priority:
    • High — duplicated logic across multiple files, or a single file with >100 lines of non-UI logic
    • Medium — single file with 30–100 lines of non-UI logic
    • Low — any non-UI logic below the Medium threshold (under 30 lines), including minor state or trivial effects; extraction is optional

Do not propose a hook that is just a thin wrapper around a single useState — only extract when it improves reuse, readability, or separates a real concern. Do not move pure helper functions into hooks; keep them as plain functions.

Present the list as a table.


Phase 3 — Confirm

After presenting the recommendation table, ask the user exactly this:

"Which hooks should I implement?

  • all — implement everything above
  • high / medium / low — implement by priority level
  • list names — e.g. useVoting, useRoomForm
  • none — stop here"

Do not proceed to Phase 4 until the user responds. If operating autonomously (no user available), default to implementing high priority hooks and note the assumption.


Phase 4 — Implement

If the hooks directory does not exist, create it at the project-appropriate path before writing any hooks.

For each approved hook, in priority order:

  1. Define the hook API before writing any code:
    • Inputs (arguments)
    • Returned state values
    • Returned actions/handlers
    • Required side effects
  2. Name hooks after the domain behavior, not the component they came from (e.g. useVoting, not useRoomDetailVoting).
  3. Extract the logic from the source .tsx file(s) into the hooks directory. Preserve exact behavior — do not refactor or rename while moving.
  4. Update the .tsx file(s) to call the hook and remove the extracted code. The component should be left with only layout, JSX, and hook calls — no raw useState/useEffect/API calls.
  5. Correctness checks during extraction:
    • Keep dependency arrays accurate
    • Preserve referential stability where callers depend on it
    • Watch for stale closure bugs introduced by the move
    • If extraction reveals unrelated responsibilities in the same block, split into multiple hooks rather than bundling them
  6. Verify after each hook:
    • Run existing tests if available
    • Run lint/typecheck if available
    • Scan for changed render behavior

Phase 5 — Review

When every approved hook is implemented — not every candidate. Phase 3 lets the user take a subset, or none, and a candidate they declined is a decision that was made, not a gap to be closed. Review what was built; list what was declined once, without re-arguing it. If the answer was none, the run ended at Phase 3 and there is nothing here to do.

Run the cyw skill to review the work. If the skill is unavailable, do a self-check: re-read each modified file, confirm no logic remains inline in .tsx files, confirm all tests/lint still pass, and list any assumptions or risks that could not be verified locally.

Where no test exercises the logic that moved, report that hook as extracted but unverified, and name it. This skill's promise is that behavior is preserved, and "tests still pass" is not evidence of that when nothing covered the code in the first place — a green run over untouched tests reads exactly like a checked one.


Constraints

  • Move logic as-is. Do not rewrite, optimize, or rename things while extracting — that is a separate task.
  • Prefer placing hooks close to the component that uses them unless the logic is clearly shared across multiple components.
  • Follow the project's existing naming conventions, import style, and file structure throughout.
  • Follow the project's CLAUDE.md / AGENTS.md conventions (whichever exists).

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.