AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Ui Scaffold

skill-srnichols-plan-forge-ui-scaffold · by srnichols

Scaffold a new Blazor page with proper layering — service interface, page component (markup + code-behind split), DTO, validation, error handling, and bUnit test. Enforces architecture-principles + blazor-fluent-ui conventions. Use when adding any new UI surface to a Blazor Server app.

No reviews yet
0 installs
14 views
0.0% view→install

Install

$ agentstack add skill-srnichols-plan-forge-ui-scaffold

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-srnichols-plan-forge-ui-scaffold)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
26d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Ui Scaffold? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

UI Scaffold Skill (Blazor + Fluent UI)

Trigger

"Scaffold a Clients page" / "Add a UI for invoices" / "Create a Blazor form for time entries" / /ui-scaffold Clients --crud

Why This Skill Exists

A naïve scaffold produces a .razor file that injects the DbContext, queries directly, and ships with no tests, no error UI, no accessibility. That's vibe-coded UI — exactly what Plan-Forge exists to prevent. This skill enforces the layered architecture from architecture-principles.instructions.md and the component discipline from blazor-fluent-ui.instructions.md on every new page.

Preconditions (verify before scaffolding)

  1. The project is a Blazor Server app (or Blazor United host) on .NET 8+
  2. Microsoft.FluentUI.AspNetCore.Components is referenced in the Web project
  3. The entity model exists in a Core/Domain project (e.g., TimeTracker.Core/Models/Client.cs)
  4. .github/instructions/blazor-fluent-ui.instructions.md is present (loaded by setup)

If any precondition fails, stop and surface the gap — do not scaffold against an incompatible project.

Steps

1. Confirm Scope

Read the entity model and any existing service for the same entity.

read_file path: src/.Core/Models/.cs
file_search query: src/**/Services/IService.cs

If a service already exists, scaffold the UI against it. If not, scaffold the service interface first (Step 2). Do not let the page reach into the DbContext even temporarily — every shortcut becomes permanent.

2. Service Layer (if missing)

Generate or update:

  • src//Services/IService.cs — interface with GetAllAsync(CancellationToken), GetByIdAsync(Guid, CancellationToken), plus CreateAsync/UpdateAsync/DeleteAsync for --crud mode.
  • src//Services/Service.cs — implementation that takes DbContext (or repository) via constructor injection.

Register the service in Program.cs:

builder.Services.AddScoped();

3. Form Model / DTO (for --crud and --form-only)

Create a DTO under src//Models/FormModel.cs. Never bind EditForm to the EF entity directly. Decorate with DataAnnotations for client-side validation:

public class ClientFormModel
{
    [Required, StringLength(200)]
    public string Name { get; set; } = "";

    [Range(0.01, 10_000)]
    public decimal HourlyRate { get; set; }

    public bool IsActive { get; set; } = true;
}

Add ToCommand() / FromEntity() mapping methods on the DTO.

4. Page Component (Markup + Code-Behind Split)

For non-trivial pages, always use the .razor + .razor.cs partial-class pattern. Single-file @code blocks are reserved for trivial display components.

src//Pages/.razor (markup):

  • @page "/"
  • @rendermode InteractiveServer at the page boundary
  • `` set
  • Layout via FluentStack / FluentGrid — no inline style for spacing
  • Three render branches: _loading → `, _loadError, success → `
  • All interactive elements have visible text or aria-label

src//Pages/.razor.cs (code-behind):

  • partial class implementing IDisposable
  • [Inject] properties (never @inject directives in code-behind pages)
  • Single CancellationTokenSource _cts = new(); cancelled in Dispose
  • OnInitializedAsync wrapped in try/catch with three branches:
  • OperationCanceledException → silent (navigation aborted)
  • Exception → log structured + set _loadError
  • finally_loading = false;
  • ILogger injected for structured logging

For --crud add: Edit/Create.razor + code-behind with EditForm, DataAnnotationsValidator, submit-disabled-while-in-flight, success/error FluentToast via IToastService.

5. bUnit Test (skip with --no-test only when explicitly justified)

tests/.Tests/Pages/Tests.cs:

public class ClientsTests : TestContext
{
    [Fact]
    public void Renders_progress_ring_while_loading()
    {
        var service = Substitute.For();
        service.GetAllAsync(Arg.Any())
               .Returns(new TaskCompletionSource>().Task);
        Services.AddSingleton(service);

        var cut = RenderComponent();

        cut.Markup.ShouldContain("FluentProgressRing");
    }

    [Fact]
    public async Task Renders_grid_with_data_after_load() { /* … */ }

    [Fact]
    public async Task Renders_error_message_when_service_throws() { /* … */ }
}

At minimum cover: loading state, success state with non-empty data, error state when the service throws.

6. Accessibility Pass (mandatory)

Before declaring the scaffold done, verify against blazor-fluent-ui.instructions.md:

  • [ ] `` set
  • [ ] Every FluentButton has visible text OR aria-label
  • [ ] Every form field has Label="…"
  • [ ] Loading/error regions have aria-live (or use Fluent components that handle it)
  • [ ] No CSS overrides removing the focus ring

7. Hand-off Report

UI Scaffold Complete: 

Created:
  ✓ src/.Web/Services/IService.cs (if missing)
  ✓ src/.Web/Services/Service.cs   (if missing)
  ✓ src/.Web/Models/FormModel.cs    (--crud / --form-only)
  ✓ src/.Web/Pages/.razor + .razor.cs
  ✓ src/.Web/Pages/Edit.razor + .razor.cs (--crud)
  ✓ tests/.Web.Tests/Pages/Tests.cs

Modified:
  ✓ src/.Web/Program.cs (service registration)

Verified:
  ✓ No DbContext injected into components
  ✓ Code-behind split (markup ≤ 100 lines, code-behind ≤ 250 lines)
  ✓ CancellationToken propagated through all async lifecycle methods
  ✓ Loading + success + error states all render
  ✓ Accessibility checklist passes
  ✓ bUnit tests cover loading / success / error

Run:
  dotnet build
  dotnet test --filter "FullyQualifiedName~Tests"
  dotnet run --project src/.Web

Constraints

  • Never scaffold a page that injects DbContext directly. If the service interface is missing, scaffold it first (Step 2). No exceptions.
  • Never bind EditForm to an EF entity. Always go through a DTO.
  • Never skip the test (--no-test) without an explicit, recorded justification. The test is part of the scaffold; it is what makes the scaffold "enterprise-grade" instead of vibe-coded.
  • Never reach across UI frameworks. If the project uses Fluent UI, the scaffold uses Fluent UI — do not introduce Bootstrap, MudBlazor, or hand-rolled CSS just because a snippet is faster to write.
  • Match the project's existing folder structure — read presets/dotnet/.github/instructions/blazor-fluent-ui.instructions.md for the canonical patterns.

Modes

| Flag | Generates | |---|---| | --read-only (default) | List page only — .razor with FluentDataGrid | | --crud | List + Create + Edit + Delete confirm + DTO + form | | --form-only | Just the form (Create/Edit) — for sub-pages of an existing parent | | --no-test | Skip bUnit test (must be justified — surface a warning) |

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.