Dryui Feedback logo

Dryui Feedback

Community
rob-balfre
dryui-feedback

Apply a single DryUI feedback submission. Use whenever you have a submission id from the feedback widget, a `feedback_get_submissions` payload, a screenshot annotated with arrows/text/components/region boxes, or a request like "act on submission X" / "resolve this feedback" / "the user drew a box on the page and labelled it Y". The skill covers reading the submission, decoding the four intent kinds (drawings / components / removed / moved), the lint trip-wires that block the dev server, and the resolve handshake.

Overview

Publisherrob-balfre
Repositorydryui
Skill namedryui-feedback
Stars
9
Forks
0
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by rob-balfre on GitHub. Read the source before you install it.

Installation

Install the Dryui Feedback AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/rob-balfre/dryui/tree/main/skills/dryui-feedback
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/rob-balfre/dryui.git /tmp/dryui
mkdir -p .claude/skills
cp -r /tmp/dryui/skills/dryui-feedback .claude/skills/dryui-feedback
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Dryui Feedback in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Dryui Feedback on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Dryui Feedback is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

DryUI Feedback

Single job: take one feedback submission and apply the smallest change that satisfies it. Read the screenshot, decode the structured intents, edit the source, run check, mark resolved. Stop.

The submission shape

A submission is a presentation JSON object (fetch with MCP feedback_get_submissions or curl http://127.0.0.1:4748/submissions/<id>):

id, url, viewport, scroll
preferredScreenshotPath          ← read this first
screenshotPath: { png, webp }    ← raw screenshot paths; png may be empty for legacy rows
textNotes[]                      ← direct text instructions extracted from drawings
drawingHints[]                   ← paired { drawing, hint } entries
summary                          ← counts by intent kind, hint corner, and structured change kind
drawings[]                       ← raw annotations the user drew
hints[]                          ← raw parallel array: each drawing's nearest element + position
components[]                     ← components the user added through the inspector
removed[]                        ← elements the user removed
moved[]                          ← elements the user dragged to a new position

The screenshot is the most direct signal — open preferredScreenshotPath before reading any structured data. Everything else exists to disambiguate what you're seeing. The raw arrays are preserved as escape hatches when the presentation fields are not enough.

Decoding the four intent kinds

Each submission can carry zero or more of these. Treat them as instructions, not suggestions.

drawings[] — annotations

Each entry has a kind (freehand / arrow / text / eraser) and coordinates. Treat textNotes[] as direct user instructions — they're literal sentences the user typed onto the page (e.g. "more padding here", "make this blue", "remove this"). Use drawingHints[] to pair each drawing with its nearest DOM hint; the raw drawings[] and hints[] arrays remain available if you need index-level detail.

Arrows usually point from a label to the thing being modified. Freehand sketches mark a region without naming it — combine with the screenshot to figure out what's circled.

components[] — additions

Each entry: { kind, label, props, rect }. The user picked a DryUI component (e.g. "Card", "Button") and dropped it at rect (viewport coordinates). Apply by inserting that component into the source at the closest matching DOM ancestor, with the user's label and props.

removed[] — deletions

Each entry: { tag, selector?, rect }. The user wants this element gone. Remove the corresponding source node. If the surrounding area becomes empty, leave it empty — don't backfill. The user can ask for a replacement in a follow-up submission.

moved[] — repositions

Each entry: { tag, selector?, originalRect, currentRect }. The user dragged an element from originalRect to currentRect (viewport coordinates). The screenshot shows a solid blue outline at the new position and a dashed blue ghost at the original position so you can see the displacement at a glance. Treat this as a layout intent — the user wants the element to live where the solid outline sits. Edit the data-layout block in src/layout.css (different grid area, reordered template, new track) to match. Apply directly when the move fits an existing sibling slot.

Layout discipline

DryUI does not ship a layout component. All page-level display: grid and display: flex declarations live in src/layout.css (or @container blocks within it). Nowhere else for page layout.

Structural changes (new named region, new responsive shift, different grid template) and region-internal changes (padding inside a wrapper, gap between sibling elements, borders or backgrounds the user requested) are both yours to apply. For structural edits, work in src/layout.css under the existing [data-layout='<name>'] block — extend the template, add a new data-layout-area, or add an @container page (min-width: ...) rule. Pick the smallest edit that satisfies the feedback. Use the --dry-space-* token scale (--dry-space-2 = 8px, --dry-space-3 = 12px, --dry-space-4 = 16px, --dry-space-6 = 24px, --dry-space-8 = 32px) for spacing values; match nearby usage in the file rather than picking magnitudes by feel.

Lint trip-wires that will block the dev server

The DryUI lint runs as a Vite preprocessor — violations crash the dev server with a stack trace, so the user sees a red overlay instead of their page. Avoid every one of these when editing:

  • dryui/no-width — no width: / inline-size: (or min-/max- variants). Grid children are sized by their track in src/layout.css. The only allowed unit family is the typographic measure (ch, em, ex).
  • dryui/no-global — no :global(...) selectors. Use scoped CSS, data-attributes, or CSS variables.
  • dryui/no-inline-style — no style="..." attributes. Use scoped classes or CSS variables.
  • dryui/no-style-directive — no style:foo={bar} directives.
  • dryui/no-raw-native-element — use DryUI components, not raw HTML, for anything DryUI covers.
  • dryui/no-flex and dryui/no-raw-grid — flex and grid declarations only in src/layout.css.

Component preferences (avoid lint and a11y regressions)

Reach forNot
<Heading level><h1>–<h6>
<Text><p> / <span> for body
<Button><button>
<Input><input type="text">
<Slider><input type="range">
<Select><select>
<Checkbox><input type="checkbox">
<Separator><hr>
<Field.Root> + <Label>unlabelled form inputs

Raw HTML is permitted only for semantic landmarks (<header>, <nav>, <aside>, <main>, <footer>, <section>, <article>) and for content the DryUI surface doesn't cover (<ol>, <ul>, <li>, <a>).

Restraint

You're applying one submission. Do only what the feedback asks for:

  • Don't refactor adjacent code that wasn't called out.
  • Don't reformat the whole file.
  • Don't "improve" things the user didn't mention.
  • Don't add tests, comments, or docs unless the feedback explicitly asks.
  • Match the file's existing patterns — if it uses Heading level={3} for section headers, your additions should too.

If the feedback is ambiguous, prefer the smaller change. The user can always send another submission.

Hand-off table

Feedback shapeHand off to
Pure design tokens / theme decisions(theme agent — coming)
Forms wiring / a11y / focus / keyboard(forms agent — coming)
Microcopy or content-only editsapply directly
Padding / spacing / colour / size on existing elementapply directly
Structural layout change (new region, new responsive breakpoint, different template)apply directly in src/layout.css
Component swap (e.g., raw <button> → <Button>)apply directly
Adding a component the user explicitly placed via components[]apply directly
Removing an element via removed[]apply directly
Moving an element via moved[]apply directly

Default to "apply directly". Layout-shape edits live in src/layout.css; component edits live in the route file.

Workflow

  1. Get the submission. Use MCP feedback_get_submissions (preferred) or curl http://127.0.0.1:4748/submissions/<id>.
  2. Claim it. Call MCP feedback_claim_submission (or curl -X POST http://127.0.0.1:4748/submissions/<id>/claim -H "Content-Type: application/json" -d '{"agent":"claude","name":"Claude Code","model":"claude-opus-4-7","version":"<cli-version>"}'). This flips the dashboard status to Processing so the human knows you've picked it up, stamps the start time, and records which AI / model / version is working — the completed-tasks view uses that history. Pass the most specific name, model, and version you know. Skip this step only when reproducing the workflow in tests.
  3. Read the screenshot. Use the Read tool on preferredScreenshotPath. This is the ground truth.
  4. Locate the page in source. The submission's url maps to a route. For http://localhost:5174/foo that's src/routes/foo/+page.svelte. For the index, src/routes/+page.svelte.
  5. Pair drawings with hints. Prefer drawingHints[]; each pair has { drawing, hint }. If you need the raw arrays, for each drawings[i], look at hints[i].element to find the DOM target, and hints[i].corner + hints[i].percentX/Y for sub-element placement.
  6. Apply intents. In order: drawings (textNotes[] are instructions), components (additions), removed (deletions), moved (repositions — usually a src/layout.css edit). Make the smallest source edit that satisfies each.
  7. Run checks. Run the project’s focused check/build/test command for the changed file or package. Fix any violations the edit introduced — re-read this skill's lint section if confused.
  8. Resolve. Call MCP feedback_resolve_submission with the submission id, or curl -X PATCH http://127.0.0.1:4748/submissions/<id> -H "Content-Type: application/json" -d '{"status":"resolved"}'. The server stamps resolvedAt and computes durationMs from your claim so the dashboard can show how long the task took. Required to clear the submission from the queue.
  9. If you bail out, release. If you claimed a submission but decided not to apply it (out of scope, blocked, etc.), call MCP feedback_release_submission so the dashboard moves it back to Pending instead of leaving it stuck under your name.

Tone

Quiet. State the submission id and what intents it carries. Claim, make the edit, run the relevant project check, resolve. The user already wrote the feedback — don't re-explain it back to them.

Frequently asked questions

What does the Dryui Feedback AI skill do?

Apply a single DryUI feedback submission. Use whenever you have a submission id from the feedback widget, a `feedback_get_submissions` payload, a screenshot annotated with arrows/text/components/region boxes, or a request like "act on submission X" / "resolve this feedback" / "the user drew a box on the page and labelled it Y". The skill covers reading the submission, decoding the four intent kinds (drawings / components / removed / moved), the lint trip-wires that block the dev server, and the resolve handshake.

Why use Dryui Feedback on TypingMind?

Because you install it once and use it with any model. Dryui Feedback is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Dryui Feedback in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/rob-balfre/dryui/tree/main/skills/dryui-feedback. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Dryui Feedback?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Dryui Feedback?

As many as you like. As long as a model supports skills, you can use Dryui Feedback with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Dryui Feedback AI skill free?

Yes. It is published on GitHub by rob-balfre under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇