From evertask
Interactive playbook for integrating the EverTask .NET background-task library into an application: install the right packages, wire up `AddEverTask(...)` with the correct storage/resilience/scheduling/rate-limiting/monitoring options, and scaffold task records + handlers that satisfy the System.Text.Json payload contract (analyzers ET0001–ET0007). Use when the user asks to "add/integrate/set up EverTask", "create a background task / recurring task / scheduled job with EverTask", "configure EverTask storage/retry/rate-limiting/monitoring", or to pick between the SQL Server / PostgreSQL / SQLite / In-Memory storage providers. The skill ASKS the user the decisions it cannot infer (via the AskUserQuestion tool) and reads the matching references/*.md only for the features actually chosen. Do NOT use it to ADD A NEW storage provider package (that is the `new-relational-storage-provider` skill) or to author EverTask's own internals.
How this skill is triggered — by the user, by Claude, or both
Slash command
/evertask:integrate-evertaskThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill turns a vague "add background tasks with EverTask" request into a correct,
references/01-setup.mdreferences/02-tasks-and-handlers.mdreferences/03-storage.mdreferences/04-resilience.mdreferences/05-scheduling.mdreferences/06-rate-limiting-queues.mdreferences/07-monitoring-logging.mdreferences/08-payload-contract.mdreferences/09-orchestration.mdreferences/packages.mdtemplates/Program.registration.mdtemplates/RecurringRegistrar.mdtemplates/Task.and.Handler.mdThis skill turns a vague "add background tasks with EverTask" request into a correct, minimal, working integration. It is interactive and progressive: you ask the user only the decisions you cannot infer, then read only the reference files for the features they actually want. Never dump every option at once: that is what the references are for.
EverTask is a MediatR-inspired, persistent background-task library: a task is a
record … : IEverTask (the message), a handler is EverTaskHandler<TTask> (the logic),
and ITaskDispatcher.Dispatch(...) persists + queues it. Tasks survive restarts, support
delayed/scheduled/recurring execution, retry policies, timeouts, keyed rate limiting,
multi-queue isolation, and monitoring. Multi-targets net8.0/net9.0/net10.0.
AddEverTask(...) must be followed by exactly one of
.AddMemoryStorage(), .AddSqlServerStorage(...), .AddPostgresStorage(...),
.AddSqliteStorage(...). Without it the app fails at startup.RegisterTasksFromAssembly(...)), or AddEverTask throws ArgumentException.EverTask.Abstractions
(no install needed). Every task you scaffold must use public properties only, no
public fields, IDs not entities. See references/08-payload-contract.md: getting
this wrong corrupts recovery, the one moment persistence matters.MaxDegreeOfParallelism, channel capacity, retry,
timeout, or rate-limiter knobs unless the user has a reason. The library auto-sizes
sensibly (e.g. MaxDegreeOfParallelism = max(4, CPU×2)).Program.cs diff before
writing. Confirm before editing existing files.| Feature the user wants | Read this |
|---|---|
Registration entry point, all AddEverTask options, concurrency/channel sizing, queues | references/01-setup.md |
Defining task records + handlers, dispatch overloads, lifecycle callbacks, taskKey idempotency, cancel | references/02-tasks-and-handlers.md |
Choosing & configuring a storage provider, audit levels, retention/cleanup, custom ITaskStorage | references/03-storage.md |
| Retry policies, exception filtering (whitelist/blacklist/predicate), timeout, cancellation, graceful shutdown | references/04-resilience.md |
| Delayed / scheduled / recurring tasks, fluent builder, cron, idempotent startup registration, drift | references/05-scheduling.md |
| Keyed (per-tenant) rate limiting, named multi-queues, scalability, sharded scheduler | references/06-rate-limiting-queues.md |
| Monitoring events, SignalR, dashboard + REST API (JWT), Serilog, persistent execution logs | references/07-monitoring-logging.md |
| System.Text.Json payload contract + every analyzer rule ET0001–ET0007 + payload checklist | references/08-payload-contract.md |
| Chaining/orchestrating tasks (continuations, compensation, sagas) via lifecycle callbacks | references/09-orchestration.md |
| Which NuGet package ships which feature | references/packages.md |
| Copy-paste code (registration, task+handler, recurring registrar) | templates/*.md |
Run these phases in order. Phases 3–6 only happen if the user wants them.
Look before you ask. Inspect the project to avoid asking what you can read:
.csproj and Program.cs (or Startup.cs). Determine the
host type: ASP.NET Core web app, Worker Service (Microsoft.NET.Sdk.Worker /
AddHostedService), or plain console / Generic Host. This decides whether monitoring
(which needs ASP.NET Core endpoint mapping) is even applicable.AddEverTask: if present, this is a modify, not a fresh setup;
read the current config and only add what is missing.appsettings.json /
Aspire / env) so you can reuse it for storage.Summarize what you found in one or two lines before moving on.
Ask only what the prompt did not already specify. If the user's prompt already says e.g. "recurring job that hits the Stripe API per tenant, store in Postgres", infer storage = Postgres, scheduling = recurring, rate-limiting = yes, and skip those questions.
Use one AskUserQuestion call with the still-open questions below (max 4 per call; if
more remain, do a second call). Recommended option goes first, labelled "(Recommended)".
Storage backend (single-select): drives persistence and packages.
Options: SQL Server, PostgreSQL, SQLite (single-server / edge),
In-Memory (dev/test only, lost on restart). Recommend based on Phase-0 findings
(existing DB wins; otherwise PostgreSQL for greenfield server apps, SQLite for
desktop/edge, In-Memory only if they said "just trying it out"). See 03-storage.md
for the full decision matrix and the SQLite write-concurrency / large-backlog caveats.
Which capabilities? (multi-select): only wire what is chosen.
Options: Scheduled / recurring tasks, Custom retry / timeout policies,
Per-key rate limiting (per tenant/account/resource),
Real-time monitoring dashboard, Dedicated Serilog pipeline,
Persist handler logs to DB. (Immediate fire-and-forget dispatch always works with no
extra wiring, so it is not an option here.)
Concurrency / throughput profile (single-select): only ask if the user signals
scale concerns or asks; otherwise SKIP and keep defaults.
Options: Use defaults (Recommended), I/O-bound, expect bursts (raise parallelism + capacity), Need workload isolation (separate critical vs background queues).
Phrase questions in the user's own domain terms when their prompt gave them (e.g. "How many Stripe calls per tenant per minute?" rather than abstract "permits/period").
AddEverTaskreferences/packages.md for the chosen storage + capabilities.Directory.Packages.props): if so, add <PackageVersion> there and a
versionless <PackageReference> in the .csproj; otherwise a normal dotnet add package.templates/Program.registration.md + 01-setup.md,
including ONLY the options the user opted into. Show it as a diff against Program.cs.If the user described a concrete task ("send welcome email", "nightly cleanup"), scaffold it; otherwise scaffold one representative example so they have a working pattern.
templates/Task.and.Handler.md. Task = record … : IEverTask with public properties,
primitives/Guid/DateTimeOffset, IDs not entities.08-payload-contract.md before writing: no public fields
(ET0001), reachable setters or matching ctor params (ET0002), no Newtonsoft attributes
(ET0003), polymorphic props annotated (ET0004), avoid object/Dictionary<string,object>
(ET0005), no Stream/DbContext/ValueTuple/delegates (ET0006), class payloads ctor-
resolvable (ET0007).DbContext) is safe.For each capability selected in Phase 1, read the matching reference and apply:
05-scheduling.md): pick Dispatch(task, TimeSpan) /
Dispatch(task, DateTimeOffset) for one-shots, or the fluent recurring builder. For
recurring, register at startup via an IHostedService with a stable taskKey for
idempotency (templates/RecurringRegistrar.md). Warn: UseCron(...) overrides all other
interval calls; all schedules are UTC.04-resilience.md): override RetryPolicy / Timeout on the handler,
or set queue/global defaults. Default is LinearRetryPolicy(3, 500ms) retrying everything
except OperationCanceledException/TimeoutException.06-rate-limiting-queues.md): override RateLimitPolicy on the handler;
carry the key via IRateLimitedTask or GetRateLimitKey. Note rate limiting is
per-instance: divide external budgets across instances in multi-instance deployments.07-monitoring-logging.md): AddMonitoringApi(...) for the full dashboard
(web apps only) + app.MapEverTaskApi(), or AddSignalRMonitoring() + MapEverTaskMonitorHub()
for events only, or subscribe to IEverTaskWorkerExecutor.TaskEventOccurredAsync in code.
Change the default admin/admin credentials.07-monitoring-logging.md): .AddSerilog(...) for a dedicated pipeline.07-monitoring-logging.md): .WithPersistentLogger(...); pair with
AddAuditCleanup(...) retention to prevent unbounded table growth.09-orchestration.md): if the task is one step in a larger flow
(continuation, compensation/rollback, fan-out, saga), there is no dedicated workflow API; chain
from OnCompleted/OnError by dispatching the next task, passing handoff data as IDs in its payload.Run dotnet build (Release; the repo treats warnings as errors and the payload analyzers run
at compile time). Fix any ET0001–ET0007 diagnostics on scaffolded payloads before declaring
done. If a DB provider was chosen, mention that the first run auto-applies migrations
(AutoApplyMigrations = true by default) unless they opted to manage migrations manually.
AddEverTask(o => o.RegisterTasksFromAssembly(typeof(Program).Assembly)).AddMemoryStorage();MapEverTaskApi) + retention cleanup.IRateLimitedTask per tenant + retry policy.When unsure which detail applies, open the specific reference file rather than guessing; the
references are exact (cross-checked against source, with file:line) and call out the known
docs-vs-code gotchas (OnLast is not implemented; GetAllRecurringTasksAsync is illustrative).
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub giampaologabba/evertask --plugin evertask