Windmill Trigger Type Checklist
windmill-labs/windmill
Checklist of every backend, frontend, CLI and capture change needed to add a new TriggerCrud-based trigger type, such as Azure, GCP or Kafka, to Windmill.
A skill your agent uses when designing or debugging an event-driven system — choosing Kafka partitioning strategies, implementing the outbox pattern, handling dead-letter queues, ensuring idempotent…
$ npx skills add kid-sid/claude-spellbook --skill event-driven -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install kid-sid/claude-spellbook event-driven --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/event-driven .claude/skills/event-driven && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "event-driven" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/event-driven into .claude/skills/event-driven/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "event-driven", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/kid-sid/claude-spellbook/tree/main/skills/event-drivenType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add kid-sid/claude-spellbook --skill event-driven -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install kid-sid/claude-spellbook event-driven --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/event-driven .agents/skills/event-driven && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "event-driven" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/event-driven into .agents/skills/event-driven/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "event-driven", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kid-sid/claude-spellbook --skill event-driven -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install kid-sid/claude-spellbook event-driven --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/event-driven .cursor/skills/event-driven && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "event-driven" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/event-driven into .cursor/skills/event-driven/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "event-driven", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/kid-sid/claude-spellbook.git --path skills/event-driven--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add kid-sid/claude-spellbook --skill event-driven -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install kid-sid/claude-spellbook event-driven --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/event-driven .gemini/skills/event-driven && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "event-driven" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/event-driven into .gemini/skills/event-driven/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "event-driven", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install kid-sid/claude-spellbook event-drivenInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add kid-sid/claude-spellbook --skill event-driven -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/event-driven .github/skills/event-driven && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "event-driven" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/event-driven into .github/skills/event-driven/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "event-driven", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add kid-sid/claude-spellbook --skill event-driven -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install kid-sid/claude-spellbook event-driven --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/kid-sid/claude-spellbook.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/event-driven .opencode/skills/event-driven && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "event-driven" agent skill from https://github.com/kid-sid/claude-spellbook/tree/main/skills/event-driven into .opencode/skills/event-driven/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "event-driven", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
event-drivenA skill your agent uses when designing or debugging an event-driven system — choosing Kafka partitioning strategies, implementing the outbox pattern, handling dead-letter queues, ensuring idempotent…
Event Driven is an agent skill from kid-sid/claude-spellbook. Use when designing or debugging an event-driven system — choosing Kafka partitioning strategies, implementing the outbox pattern, handling dead-letter queues, ensuring idempotent consumers, or making event sourcing decisions.
Its SKILL.md is about 3.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Backend & APIs, covering Event-driven systems. It works with Apache Kafka. The repository describes itself as: A curated collection of skills, prompts, and workflows that extend Claude's capabilities — your personal grimoire for AI-powered development. The licence is MIT.
Read from SKILL.md and the folder at commit a7c2ac9. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are python, typescript, json and go).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Event Driven loads about 3.6k tokens when it runs. Until then it costs about 60 tokens; SKILL.md has 659 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from kid-sid/claude-spellbook at commit a7c2ac9, republished under its MIT licence (© kid-sid). 659 words, ~3,602 tokens.
.claude/skills/event-driven/SKILL.md (or your agent's skills folder).Design and implementation patterns for reliable, scalable asynchronous systems using message brokers.
| Broker | Retention | Ordering | Throughput | Best For |
|---|---|---|---|---|
| Kafka | Days–forever (log) | Per partition | Very high | Event streaming, audit log, replay |
| RabbitMQ | Until consumed | Per queue | High | Task queues, RPC, routing flexibility |
| AWS SQS | Up to 14 days | None (FIFO available) | High | Simple queues, AWS-native workloads |
| Redis Streams | Configurable | Per stream | High | Low-latency, simple consumers |
| GCP Pub/Sub | 7 days default | None | Very high | GCP-native, push subscriptions |
| Semantic | How | Tradeoff |
|---|---|---|
| At-least-once | Commit offset only after processing | Duplicates possible; consumer must be idempotent |
| At-most-once | Commit before processing | No duplicates; messages can be lost |
| Exactly-once | Transactional producer + idempotent consumer | Highest complexity; use outbox pattern instead |
Default to at-least-once with idempotent consumers — it's simpler than exactly-once and eliminates loss.
{
"event_id": "01HXK4...",
"event_type": "order.placed",
"schema_version": "1.0",
"occurred_at": "2025-06-01T12:00:00Z",
"aggregate_id": "order-abc-123",
"aggregate_type": "Order",
"correlation_id": "req-xyz-456",
"payload": {
"customer_id": "cust-789",
"total": "59.99",
"currency": "USD",
"items": [{ "sku": "WIDGET-01", "qty": 2, "unit_price": "29.99" }]
}
}Rules:
event_id: globally unique (ULID or UUID v7) — used for idempotency keysoccurred_at: when the fact happened, not when publishedcorrelation_id: propagate from the originating request for distributed tracing# GOOD: backward-compatible change — add optional field with default
{
"event_type": "order.placed",
"schema_version": "1.1", # minor bump — consumers on 1.0 still work
"payload": {
"customer_id": "...",
"total": "...",
"promo_code": null # new optional field, defaults to null
}
}
# BAD: breaking changes
# - removing a field consumers depend on
# - renaming a field
# - changing a field type (string → int)
# → always create a new event type or bump major version# Naming: <domain>.<entity>.<event-type> or <domain>.<entity>
orders.placed
orders.cancelled
payments
inventory.stock-updates
# Partition key selection — determines ordering guarantee
producer.produce(topic="orders", key=order.customer_id, ...) # all orders per customer are ordered
producer.produce(topic="payments", key=payment.order_id, ...) # all events per order are ordered
# Partition count tradeoffs
low partitions (1–6): easy rebalancing, less parallelism
high partitions (12+): more parallelism, more consumer instances, slower rebalance
rule: start with max(consumer_instances * 2, 12), increase laterfrom confluent_kafka import Producer, KafkaException
import json, uuid
from datetime import datetime, timezone
producer = Producer({
"bootstrap.servers": "kafka:9092",
"acks": "all", # wait for all ISR replicas
"retries": 5,
"retry.backoff.ms": 500,
"enable.idempotence": True, # exactly-once producer semantics
"compression.type": "lz4",
})
def publish_event(topic: str, key: str, event_type: str, payload: dict):
event = {
"event_id": str(uuid.uuid4()),
"event_type": event_type,
"schema_version": "1.0",
"occurred_at": datetime.now(timezone.utc).isoformat(),
"payload": payload,
}
producer.produce(
topic=topic,
key=key.encode(),
value=json.dumps(event).encode(),
on_delivery=_delivery_report,
)
producer.poll(0) # trigger callbacks without blocking
def _delivery_report(err, msg):
if err:
logger.error("delivery_failed", topic=msg.topic(), error=str(err))
producer.flush() # call at shutdownfrom confluent_kafka import Consumer, KafkaError
import json
consumer = Consumer({
"bootstrap.servers": "kafka:9092",
"group.id": "notification-service",
"auto.offset.reset": "earliest",
"enable.auto.commit": False, # manual commit after processing
"max.poll.interval.ms": 300_000,
})
consumer.subscribe(["orders"])
try:
while True:
msg = consumer.poll(timeout=1.0)
if msg is None:
continue
if msg.error():
if msg.error().code() == KafkaError.PARTITION_EOF:
continue
raise KafkaException(msg.error())
event = json.loads(msg.value())
try:
handle_event(event)
consumer.commit(message=msg) # commit only after success
except Exception as e:
logger.error("processing_failed", event_id=event["event_id"], error=str(e))
# don't commit — message will be redelivered
finally:
consumer.close()import { Kafka } from "kafkajs";
const kafka = new Kafka({ brokers: ["kafka:9092"] });
const consumer = kafka.consumer({ groupId: "notification-service" });
await consumer.connect();
await consumer.subscribe({ topics: ["orders"], fromBeginning: false });
await consumer.run({
autoCommit: false,
eachMessage: async ({ topic, partition, message, heartbeat }) => {
const event = JSON.parse(message.value!.toString());
try {
await handleEvent(event);
await consumer.commitOffsets([{
topic, partition,
offset: (Number(message.offset) + 1).toString(),
}]);
} catch (err) {
logger.error({ eventId: event.event_id, err }, "processing_failed");
throw err; // re-throw to pause and retry
}
},
});import "github.com/IBM/sarama"
type OrderHandler struct{ db *sql.DB }
func (h *OrderHandler) Setup(_ sarama.ConsumerGroupSession) error { return nil }
func (h *OrderHandler) Cleanup(_ sarama.ConsumerGroupSession) error { return nil }
func (h *OrderHandler) ConsumeClaim(sess sarama.ConsumerGroupSession, claim sarama.ConsumerGroupClaim) error {
for msg := range claim.Messages() {
var event Event
if err := json.Unmarshal(msg.Value, &event); err != nil {
logger.Error("unmarshal_failed", "offset", msg.Offset)
sess.MarkMessage(msg, "") // skip unparseable messages
continue
}
if err := h.handle(sess.Context(), event); err != nil {
return err // stop processing; session will restart
}
sess.MarkMessage(msg, "")
}
return nil
}Consumers must handle duplicate messages — at-least-once delivery guarantees redelivery on failure.
# Pattern: idempotency key in a processed-events table
def handle_order_placed(event: dict, db: Session):
event_id = event["event_id"]
# Check if already processed
if db.query(ProcessedEvent).filter_by(event_id=event_id).first():
logger.info("duplicate_skipped", event_id=event_id)
return
# Process in a transaction that also inserts the idempotency record
with db.begin():
create_notification(event["payload"])
db.add(ProcessedEvent(event_id=event_id, processed_at=datetime.utcnow()))// Alternative: upsert on natural key (e.g. order_id)
await db.transaction(async (trx) => {
await trx("notifications")
.insert({ order_id: event.payload.order_id, customer_id: event.payload.customer_id })
.onConflict("order_id")
.ignore(); // safe to call multiple times
});Solves dual-write: never publish directly from application code after a DB write — they can desync.
# BAD: dual write (either step can fail independently)
BEGIN TRANSACTION
INSERT INTO orders (...)
COMMIT
kafka.produce("order.placed", ...) # ← this can fail silently
# GOOD: outbox pattern
BEGIN TRANSACTION
INSERT INTO orders (...)
INSERT INTO outbox (event_type, payload, published=false, ...) # same transaction
COMMIT
# Separate relay process (Debezium CDC or polling relay)
SELECT * FROM outbox WHERE published = false ORDER BY created_at LIMIT 100
→ produce to Kafka
→ UPDATE outbox SET published = true WHERE id IN (...)# Polling relay (simple, no CDC dependency)
def relay_outbox(db: Session, producer: Producer):
events = db.query(OutboxEvent).filter_by(published=False).limit(100).all()
for event in events:
producer.produce(
topic=event.topic,
key=event.aggregate_id.encode(),
value=event.payload.encode(),
)
producer.flush()
for event in events:
event.published = True
db.commit()# Python — send to DLQ after max retries
MAX_RETRIES = 3
def handle_with_dlq(consumer, dlq_producer, msg):
retry_count = int(msg.headers().get("retry-count", b"0"))
event = json.loads(msg.value())
try:
process_event(event)
consumer.commit(message=msg)
except Exception as e:
if retry_count >= MAX_RETRIES:
dlq_producer.produce(
topic=f"{msg.topic()}.dlq",
key=msg.key(),
value=msg.value(),
headers={"original-topic": msg.topic(), "error": str(e)},
)
consumer.commit(message=msg) # move past it
logger.error("sent_to_dlq", event_id=event["event_id"])
else:
# Re-queue with incremented retry count (or let Kafka retry via pause)
logger.warning("retry", attempt=retry_count + 1, event_id=event["event_id"])DLQ naming convention: <original-topic>.dlq
DLQ review: alert on DLQ lag > 0; investigate and replay or discard manually.
Store state as an append-only log of events; derive current state by replaying.
# Events are facts, not commands
EVENTS = [
{"type": "OrderCreated", "payload": {"customer_id": "c1", "items": [...]}},
{"type": "ItemAdded", "payload": {"sku": "X", "qty": 1}},
{"type": "OrderConfirmed", "payload": {"confirmed_at": "2025-01-01T..."}},
]
def replay(events: list[dict]) -> Order:
order = Order()
for event in events:
match event["type"]:
case "OrderCreated": order.apply_created(event["payload"])
case "ItemAdded": order.apply_item_added(event["payload"])
case "OrderConfirmed": order.apply_confirmed(event["payload"])
return order
# Snapshot: periodically persist current state to avoid full replay
# Projection: consume event stream to build read models (CQRS read side)| Use Event Sourcing When | Avoid When |
|---|---|
| Audit trail is a first-class requirement | Simple CRUD with no history needs |
| Need to replay history for new features | Team unfamiliar with the pattern |
| Multiple read models from one write model | Strong consistency required across aggregates |
| Temporal queries ("state at time T") | Simple, low-volume domain |
See also:
microservices,observability
event_type as the partition key routes all messages of one type to one partition; choose a high-cardinality key like entity_id for even distributionevent_id, event_type, schema_version, occurred_at, correlation_idacks=all and enable.idempotence=trueevent_id handled gracefully)© kid-sid, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/event-driven of kid-sid/claude-spellbook.
Open the folder on GitHubat commit a7c2ac9
Event Driven next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Event Driven this skillkid-sid/claude-spellbook | 189 | — | ~3.6k | Automated safety check: Pass | MIT | |
| Windmill Trigger Type Checklistwindmill-labs/windmill | 18k | — | ~4.7k | Automated safety check: Pass | Custom licence | |
| FoundatioFoundatioFx/Foundatio | 2.1k | — | ~3.9k | Automated safety check: Pass | Apache-2.0 | |
| Opensource Guide Coachcalf-ai/calfkit-sdk | 149 | 1 repos | ~2.1k | Automated safety check: Pass | Apache-2.0 | |
| Create Environmentgodatadriven/whirl | 205 | — | ~1.9k | Automated safety check: Pass | Apache-2.0 | |
| Monstermq Graphql Configvogler75/monster-mq | 143 | — | ~2.3k | Automated safety check: Pass | GPL-3.0 |
windmill-labs/windmill
Checklist of every backend, frontend, CLI and capture change needed to add a new TriggerCrud-based trigger type, such as Azure, GCP or Kafka, to Windmill.
FoundatioFx/Foundatio
A skill your agent uses when working with Foundatio infrastructure abstractions for .NET -- caching, queuing, messaging, file storage, distributed locking, or background jobs.
calf-ai/calfkit-sdk
A skill your agent uses when a user wants guidance on starting, contributing to, growing, governing, funding, securing, or sustaining an open source project, or asks about contributor onboarding…
godatadriven/whirl
Create a new Whirl environment in the envs/ directory. An agent skill from godatadriven/whirl.
vogler75/monster-mq
Guide for configuring, managing, and mutating MonsterMQ settings, devices, flows, AI agents, users, loggers, archive groups, topic schemas, and publishing messages via the GraphQL API.
wshobson/agents
Designs event stores for event-sourced systems: requirements, a comparison of EventStoreDB, PostgreSQL, Kafka, DynamoDB and Marten, and stream and versioning practices.
kid-sid/claude-spellbook
A skill your agent uses when building or reviewing UI components for keyboard and screen reader compatibility, adding ARIA to custom widgets, auditing a page for WCAG AA conformance, or preparing…
kid-sid/claude-spellbook
A skill your agent uses when building, wiring, or debugging an Agentex agent — choosing agent type, configuring acp.py and manifest.yaml, using adk.messages or adk.state, or resolving…
kid-sid/claude-spellbook
A skill your agent uses when building production LLM applications — designing RAG pipelines, choosing vector databases, implementing agent orchestration, optimizing cost, or adding AI safety…
kid-sid/claude-spellbook
A skill your agent uses when building or refactoring Angular applications — choosing between signals, RxJS, and NgRx for state, configuring routing with guards and lazy loading, optimizing change…
kid-sid/claude-spellbook
A skill your agent uses when designing new REST endpoints, reviewing an existing API contract, adding pagination or filtering, planning a versioning strategy, or building a public or partner-facing…
kid-sid/claude-spellbook
A skill your agent uses when implementing login flows, issuing or validating JWTs, setting up OAuth2/OIDC with a provider, designing role-based or attribute-based access control, securing API…
Works with
Categories
A skill your agent uses when designing or debugging an event-driven system — choosing Kafka partitioning strategies, implementing the outbox pattern, handling dead-letter queues, ensuring idempotent…. Event Driven is an agent skill from kid-sid/claude-spellbook. Use when designing or debugging an event-driven system — choosing Kafka partitioning strategies, implementing the outbox pattern, handling dead-letter queues, ensuring idempotent consumers, or making event sourcing decisions.
Event Driven fits situations like: debugging an event-driven system — choosing Kafka partitioning strategies; implementing the outbox pattern; handling dead-letter queues; ensuring idempotent consumers.
Run `npx skills add kid-sid/claude-spellbook --skill event-driven -a claude-code`. Or copy the skill folder (skills/event-driven in kid-sid/claude-spellbook) into .claude/skills/event-driven in your project. Claude Code loads it when a task matches its description.
Run `npx skills add kid-sid/claude-spellbook --skill event-driven -a codex`. Or copy the skill folder (skills/event-driven in kid-sid/claude-spellbook) into .agents/skills/event-driven in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add kid-sid/claude-spellbook --skill event-driven -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/event-driven, .gemini/skills/event-driven, .github/skills/event-driven and .opencode/skills/event-driven in your project.
SKILL.md names no scripts, command-line tools or credentials: Event Driven is instructions for the agent only. Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Event Driven is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.6k tokens (SKILL.md is roughly 14k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Event Driven: Windmill Trigger Type Checklist (windmill-labs/windmill, 18k stars), Foundatio (FoundatioFx/Foundatio, 2.1k stars), Opensource Guide Coach (calf-ai/calfkit-sdk, 149 stars) and Create Environment (godatadriven/whirl, 205 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
kid-sid (a GitHub user) maintains it in kid-sid/claude-spellbook, which has 189 GitHub stars. The repository holds 52 skills in this directory. The repository was last updated on August 5, 2026.
Source: kid-sid/claude-spellbook on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.