agentleFS
nonlinear-xyznonlinear-xyz/factory-kit/skills/factory-frontend-engineer/SKILL.md

factory-frontend-engineer

Skill9 starsChanged 4 months agoMITView on GitHub

Use when scaffolding any frontend surface that touches lists, forms, drawers, tables, or entity editing. Carries the factory's CRUD conventions — DataTable + drawer with mode union, RowActions primitive, per-context Zod schema variants, query-key naming, format helpers as single source, tier-based heading components, semantic color tokens. Picks Mantine vs shadcn per project criteria. Returns code that fits the house style — not a generic React component.

The file

Show its rules and text

We split this skill into the rules it gives an agent

13 rules. About 0 are common, 7 are distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈7

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

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

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

    Is this CRUD?: If yes, the default shape is DataTable + drawer with mode union.

    line 17
  2. Very specific:

    Which component library?: Check the project's CLAUDE.md or DECISIONS.md.

    line 21
  3. Very specific:

    Mantine: when CRUD-heavy / internal tool / form-table dense.

    line 22
  4. Very specific:

    shadcn: when there's a marketing site, design flexibility matters, or Tailwind muscle memory dominates.

    line 23
  5. Distinctive:

    What primitives already exist?: Before writing anything new, check:

    line 26
  6. Distinctive:

    If a primitive is missing where it should exist, *create it first* — don't inline.

    line 31
  7. Very specific:

    All three live in features/<entity>/schema.ts.

    line 37
  8. Distinctive:

    What's the data path?: Default: server action wrapped by TanStack Query mutation.

    line 39
  9. Distinctive:

    What's the smallest correct change?: If asked for a table, build the table — don't redesign the whole space.

    line 52
  10. Distinctive:

    When asked to scaffold:

    line 70
  11. Distinctive:

    When asked to review an existing surface, swap "Files to create" → "Issues found" and "Code" → "Suggested diffs." Lead every review with …

    line 102
  12. Very specific:

    Don't inline currency / percent / date math: Use src/lib/format.ts — create it if missing.

    line 107
  13. Distinctive:

    If the user asks for a one-line color tweak, a copy change, or a single Tailwind class adjustment, just do it directly.

    line 116

≈ “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

Apply the frontend-engineer specialist workflow. Scaffold UI surfaces grounded in the factory's CRUD conventions, not generic React. Load factory-frontend, factory-state-modeling, factory-design, and factory-stack through the host's skill capability when needed. factory-design owns visual coherence; factory-frontend owns CRUD shape; factory-state-modeling owns how the states are counted before either.

How to think (in order)

  1. What surface is this? Restate the request in one sentence. Pick one:
    • List (queue of entities; filter/sort/paginate)
    • Detail (one entity's full view)
    • Form (create/edit, including multi-step)
    • Dashboard (rollup/chart heavy)
    • Hybrid — name it and split into two surfaces if you can.
  2. Is this CRUD? If yes, the default shape is DataTable + drawer with mode union. Don't deviate without naming why. The drawer mode is the tagged union {kind:'closed'}|{kind:'create'}|{kind:'edit'; entity}. The drawer edits only the clicked target; relations open their own drawers.
  3. What are the states? Write the legal states as a type before any markup. More than three boolean props on one component means propose a discriminated union with an exhaustive never check. For every control, filter or picker, name the RPC argument or predicate it changes; if none yet, say so instead of wiring it to nothing. Casts only at an import boundary beside a runtime parse. See factory-state-modeling.
  4. Which component library? Check the project's CLAUDE.md or DECISIONS.md. If unset:
    • Mantine when CRUD-heavy / internal tool / form-table dense. Pair with @mantine/form + schemaResolver.
    • shadcn when there's a marketing site, design flexibility matters, or Tailwind muscle memory dominates. Pair with react-hook-form + zodResolver.
    • Flag the choice in your output if you had to make it.
  5. What primitives already exist? Before writing anything new, check:
    • src/components/datatable/ — DataTable, RowActions, ColumnDef, ValidationRules
    • src/lib/format.ts — formatCurrency, formatInteger, formatPercent
    • src/components/PageHeader.tsx / CardHeader.tsx / FormSection.tsx — heading tiers
    • src/features/<sibling>/ — peer feature folders for the colocated shape
    • If a primitive is missing where it should exist, create it first — don't inline. Single source.
  6. What's the schema shape? Three Zod variants for a CRUD entity:
    • Input schema — server-side strict (UUIDs are UUIDs, no empty strings)
    • Form schema — client-side lenient (empty-string defaults, nullable().or(literal('')))
    • Patch schema — partial input for updates (input.partial() or .pick({}) per field)
    • All three live in features/<entity>/schema.ts.
  7. What's the data path? Default: server action wrapped by TanStack Query mutation. tRPC only if the project already commits to it.
    • Action in features/<entity>/actions.ts with "use server" directive
    • Hook in features/<entity>/hooks.ts wrapping the action with useMutation
    • Query keys: ['entity', 'list', filters] / ['entity', 'detail', id]
    • Invalidate at ['entity'] after mutations.
  8. What conventions must hold?
    • Semantic tokens only — consume named tokens (bg, surface, fg, fg-muted, accent, border, etc. — see factory-design.md). No hex literals in components, ever. No dark: variants on individual elements — let CSS-var swap handle modes.
    • Format helpers from src/lib/format.ts — never inline currency math.
    • Tier components — PageHeader / CardHeader / FormSection. Never freeform <h1>/<h2>.
    • Empty + error + loading states — required, not optional.
    • Feature folders are peers — code in features/cases/ doesn't import from features/products/. Shared logic goes to lib/.
  9. What's the smallest correct change? If asked for a table, build the table — don't redesign the whole space. If a change implies redesigning something else, name it and stop.

Reference: canonical feature folder shape

src/features/<entity>/
├── api.ts            # data access (auth-context-agnostic — takes client as arg)
├── actions.ts        # server actions ("use server")
├── hooks.ts          # TanStack Query wrappers around actions
├── schema.ts         # Zod input / form / patch schemas
├── types.ts          # types + label maps (STATUS_LABEL, etc.)
├── columns.tsx       # makeColumns factory returning ColumnDef[]
├── <Entity>Table.tsx # consumer of DataTable
└── <Entity>Drawer.tsx # consumer of drawer mode union

Output format

When asked to scaffold:

## Restated request
<one sentence>

## State model
- States: <the union, one line per kind>
- Removed booleans: <none / list>
- Controls → predicates: <control: RPC arg or 'none yet'>

## Surface + shape
- Surface: <list / detail / form / dashboard>
- Shape: <DataTable + drawer / form-only / etc.>
- Component lib: <Mantine / shadcn — and why if you picked>

## Files to create or modify
<bulleted list with paths>

## Code
<the actual code, organized by file>

## Conventions check
- Format helpers used: <which>
- Semantic colors: <how>
- Empty/loading/error states: <yes/no>
- Cross-feature imports: <none / flagged>

## Open questions
<things the user should confirm>

When asked to review an existing surface, swap "Files to create" → "Issues found" and "Code" → "Suggested diffs." Lead every review with the State model section: which states were added or removed, then the diff.

What you do NOT do

  • Don't pick the component library without checking CLAUDE.md / DECISIONS.md first. Flag if you had to.
  • Don't inline currency / percent / date math. Use src/lib/format.ts — create it if missing.
  • Don't use raw color names (red, blue). Always semantic tokens.
  • Don't skip empty / loading / error states. They're required, not optional.
  • Don't edit a relation from inside an entity's drawer. Open the relation's own drawer.
  • Don't import from a sibling feature folder. Lift to lib/ instead.
  • Don't build local components first. Extend shared primitives even for single-consumer needs.

When the request is too small for this framework

If the user asks for a one-line color tweak, a copy change, or a single Tailwind class adjustment, just do it directly. The framework is for surface-level or larger.

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.