SkillAgentSearch skills...

skrift-forms

Skrift form system — Pydantic-backed forms with CSRF protection, template rendering, and hook integration.

Install / Use

npx skills add Smarter-Dev/smarter-dev --skill skrift-forms

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

66/100

Supported Platforms

Universal

Tags

Our assessment of skrift-forms

skrift-forms scores 66/100 on our quality scale, 3914th of 4,617 Development & Engineering skills we index.

Its SKILL.md is 6.8 KB long, well organised into 18 sections with 10 code examples: a thorough specification that gives an agent plenty to work with.

It has no GitHub stars yet, so there is no community track record; judge it on its content.

Substance
29/30
Structure
20/20
Description
12/15
Adoption
0/20
Freshness
5/15

Maintenance, license and trust

  • We could not determine when the repository was last updated.
  • Our last check on 2026-10-19 found the source still online.
  • No license is declared. By default that means all rights are reserved: you can read it, but reusing or redistributing it is not clearly permitted. Ask the author before building on it commercially.
  • Its trust signals score 68/100, with 3 cautions from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

Safety scan

No issues found

Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful.

AI review by kimi-k2.7-code on 2026-09-24. Automated pattern scan on 2026-09-24. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.

skrift-forms compared with similar skills

All 4 of these similar skills score higher than skrift-forms; compare them before choosing.

SkillScoreStarsUpdatedFormat
skrift-forms (this skill)by Smarter-Dev660—SKILL.md
taste-skillby Leonxlnx100110.6ktodayCLAUDE.md
ai-job-searchby ai-job-search-dev10069.8ktodayCLAUDE.md
claude-howtoby luongnv8910046.6k2d agoCLAUDE.md
algorithmic-artby anthropics100177.9k44d agoSKILL.md

Frequently asked questions

How do I install skrift-forms?
Run npx skills add Smarter-Dev/smarter-dev --skill skrift-forms. The install tabs above show the steps for each supported agent.
Which AI agents does skrift-forms work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is skrift-forms safe to use?
Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful. It declares no license and scores 68/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is skrift-forms still maintained?
We could not determine when the repository was last updated.

name: skrift-forms description: "Skrift form system — Pydantic-backed forms with CSRF protection, template rendering, and hook integration."

Skrift Form System

Skrift forms combine Pydantic validation with CSRF protection, template rendering, and hook integration.

Architecture

FormModel/BaseModel → Form(model, request) → validate() → hooks → data
      │                      │                    │           │
      │                      │                    │           ├─ form_{name}_validated
      │                      │                    │           └─ form_validated
      │                      │                    │
      │                      │                    ├─ CSRF verify (hmac.compare_digest)
      │                      │                    ├─ Token rotation (single-use)
      │                      │                    ├─ Checkbox injection (bool fields)
      │                      │                    └─ Pydantic validation
      │                      │
      │                      ├─ render() → Template("form", name).try_render()
      │                      ├─ csrf_field() → hidden input
      │                      ├─ fields → dict[str, BoundField]
      │                      └─ errors → dict[str, str]
      │
      └─ Registered in _form_registry (by form_name)

Defining Forms

FormModel (auto-registers)

from skrift.forms import FormModel
from pydantic import Field, EmailStr

class ContactForm(FormModel, form_name="contact"):
    name: str
    email: EmailStr
    message: str = Field(json_schema_extra={"widget": "textarea"})

@form() Decorator (registers a plain BaseModel)

from pydantic import BaseModel
from skrift.forms import form

@form("newsletter", action="/subscribe", method="post")
class NewsletterForm(BaseModel):
    email: str

Field Customization via json_schema_extra

| Key | Values | Purpose | |-----|--------|---------| | label | str | Custom label text | | widget | "textarea", "select", "checkbox" | Widget type | | input_type | "email", "password", etc. | HTML input type | | help_text | str | Help text below field | | choices | list[tuple[str, str]] | Options for select widget | | attrs | dict[str, str] | Extra HTML attributes |

Full example:

class ContactForm(FormModel, form_name="contact"):
    name: str = Field(json_schema_extra={
        "label": "Your Name",
        "attrs": {"placeholder": "Jane Doe"},
    })
    email: EmailStr = Field(json_schema_extra={
        "label": "Email Address",
        "input_type": "email",
        "help_text": "We'll never share your email.",
    })
    subject: str = Field(json_schema_extra={
        "widget": "select",
        "choices": [
            ("general", "General Inquiry"),
            ("support", "Technical Support"),
        ],
    })
    message: str = Field(json_schema_extra={
        "widget": "textarea",
        "attrs": {"rows": "6"},
    })
    subscribe: bool = Field(default=False, json_schema_extra={
        "label": "Subscribe to newsletter",
    })

Controller GET/POST Pattern

from litestar import Controller, get, post, Request
from litestar.response import Template as TemplateResponse, Redirect
from skrift.forms import Form

class ContactController(Controller):
    path = "/contact"

    @get("/")
    async def show(self, request: Request) -> TemplateResponse:
        form = Form(ContactForm, request)
        return TemplateResponse("contact.html", context={"form": form})

    @post("/")
    async def submit(self, request: Request) -> TemplateResponse | Redirect:
        form = Form(ContactForm, request)
        if await form.validate():
            # form.data is a validated ContactForm instance
            await process_contact(form.data)
            return Redirect("/contact?thanks=1")
        return TemplateResponse("contact.html", context={"form": form})

Template Rendering

Automatic

{{ form.render() }}
{{ form.render(submit_label="Send") }}

Manual

<form method="{{ form.method }}">
    {{ form.csrf_field() }}
    {% for field in form %}
        {{ field.label_tag() }}
        {{ field.widget() }}
    {% endfor %}
    <button type="submit">Send</button>
</form>

Custom Form Template

Template hierarchy: form-{name}.html → form.html → programmatic fallback.

{# templates/form-contact.html #}
<form method="{{ form.method }}" class="contact-form">
    {{ form.csrf_field() }}

    {% if form.form_error %}
        <div class="alert">{{ form.form_error }}</div>
    {% endif %}

    <div class="row">
        <div class="col">
            {{ form['name'].label_tag() }}
            {{ form['name'].widget(class_="form-input") }}
        </div>
        <div class="col">
            {{ form['email'].label_tag() }}
            {{ form['email'].widget(class_="form-input") }}
        </div>
    </div>

    {{ form['message'].label_tag() }}
    {{ form['message'].widget(class_="form-input", rows="8") }}

    <button type="submit">{{ submit_label }}</button>
</form>

CSRF Flow

  1. Form.__init__() — Creates secrets.token_urlsafe(32) in session if absent (key: _csrf_token)
  2. csrf_field() — Renders <input type="hidden" name="_csrf" value="{token}">
  3. validate() — Checks submitted _csrf against session token via hmac.compare_digest()
  4. Token rotation — New token generated after successful check (single-use)

Registration Mechanism

Forms are registered in a global _form_registry dict (in model.py):

  • FormModel.__init_subclass__() auto-registers on class creation
  • @form() decorator registers explicitly
  • get_form_model(name) retrieves by name, raises LookupError if missing

Hook Integration

Two filter hooks fire after successful validation:

# Form-specific: e.g. "form_contact_validated"
self.data = await hooks.apply_filters(f"form_{self.name}_validated", self.data)

# Global: "form_validated"
self.data = await hooks.apply_filters("form_validated", self.data, self.name)

Example hook:

from skrift.hooks import filter

@filter("form_contact_validated")
async def sanitize_contact(data):
    data.message = data.message.strip()
    return data

@filter("form_validated")
async def log_all_forms(data, name):
    print(f"Form '{name}' submitted")
    return data

Jinja2 Global

The Form class is registered as a Jinja2 global, making it accessible in templates without passing it through context.

Key Files

| File | Purpose | |------|---------| | skrift/forms/core.py | Form — CSRF, validation, rendering | | skrift/forms/model.py | FormModel base class, _form_registry, get_form_model() | | skrift/forms/fields.py | BoundField — field bound to form instance | | skrift/forms/decorators.py | @form() decorator | | skrift/templates/form.html | Default form template |

Related Skills

View on GitHub
GitHub Stars0
CategoryDevelopment
UpdatedNaNy ago
Forks0

Trust signals

68/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

2 medium1 low