Accessibility
affaan-m/ECC
Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels, accessibility traits and hints, focus management, contrast, target…
A skill your agent uses when working with Jotai X stores (createAtomStore), accessing state in components or callbacks, persisting state to cookies or localStorage
$ npx skills add udecode/kitcn --skill jotai-x -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install udecode/kitcn jotai-x --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/udecode/kitcn.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/jotai-x .claude/skills/jotai-x && 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 "jotai-x" agent skill from https://github.com/udecode/kitcn/tree/main/.agents/skills/jotai-x into .claude/skills/jotai-x/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jotai-x", 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/udecode/kitcn/tree/main/.agents/skills/jotai-xType 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 udecode/kitcn --skill jotai-x -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install udecode/kitcn jotai-x --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/udecode/kitcn.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/jotai-x .agents/skills/jotai-x && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "jotai-x" agent skill from https://github.com/udecode/kitcn/tree/main/.agents/skills/jotai-x into .agents/skills/jotai-x/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jotai-x", 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 udecode/kitcn --skill jotai-x -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install udecode/kitcn jotai-x --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/udecode/kitcn.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/jotai-x .cursor/skills/jotai-x && 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 "jotai-x" agent skill from https://github.com/udecode/kitcn/tree/main/.agents/skills/jotai-x into .cursor/skills/jotai-x/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jotai-x", 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/udecode/kitcn.git --path .agents/skills/jotai-x--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 udecode/kitcn --skill jotai-x -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install udecode/kitcn jotai-x --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/udecode/kitcn.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/jotai-x .gemini/skills/jotai-x && 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 "jotai-x" agent skill from https://github.com/udecode/kitcn/tree/main/.agents/skills/jotai-x into .gemini/skills/jotai-x/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jotai-x", 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 udecode/kitcn jotai-xInstalls 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 udecode/kitcn --skill jotai-x -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/udecode/kitcn.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/jotai-x .github/skills/jotai-x && 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 "jotai-x" agent skill from https://github.com/udecode/kitcn/tree/main/.agents/skills/jotai-x into .github/skills/jotai-x/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jotai-x", 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 udecode/kitcn --skill jotai-x -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install udecode/kitcn jotai-x --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/udecode/kitcn.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/jotai-x .opencode/skills/jotai-x && 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 "jotai-x" agent skill from https://github.com/udecode/kitcn/tree/main/.agents/skills/jotai-x into .opencode/skills/jotai-x/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "jotai-x", 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.
jotai-xA skill your agent uses when working with Jotai X stores (createAtomStore), accessing state in components or callbacks, persisting state to cookies or localStorage
Jotai X is an agent skill from udecode/kitcn. Use when working with Jotai X stores (createAtomStore), accessing state in components or callbacks, persisting state to cookies or localStorage
Its SKILL.md is about 3.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
The repository describes itself as: Convex + Better Auth + tRPC + Drizzle + TanStack Query + shadcn. The licence is Apache-2.0.
Read from SKILL.md and the folder at commit c6010f5. 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 typescript).
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.
Jotai X loads about 3.7k tokens when it runs. Until then it costs about 38 tokens; SKILL.md has 480 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 udecode/kitcn at commit c6010f5, republished under its Apache-2.0 licence (© udecode). 480 words, ~3,664 tokens.
.claude/skills/jotai-x/SKILL.md (or your agent's skills folder).Minimize subscriptions, maximize performance. Use hooks (useValue) only when you need reactivity. Use store methods (store.get, store.set) everywhere else.
createAtomStore)useAppValue vs store.get, useAppSet vs store.set// ✅ Subscribe with hooks ONLY when component needs to re-render on change
const count = useAppValue("count"); // Component re-renders when count changes
// ✅ Read without subscribing in callbacks/handlers
const handleClick = () => {
const count = store.get("count"); // Just reads current value, no subscription
console.log(count);
};
// ✅ Write with store.set in callbacks/handlers
const handleIncrement = () => {
store.set("count", (prev) => prev + 1);
};Reading State:
useAppValue('key')store.get('key')store.get('key')store.get('key') unless you need dependencyWriting State:
store.set('key', value)Getting both read + write:
useAppState or useAppSet - use combinations above| Scenario | Use | Don't Use |
|---|---|---|
| Component needs reactivity | useAppValue('key') | store.get('key') |
| Callback reads once | store.get('key') | useAppValue('key') |
| Event handler reads | store.get('key') | useAppValue('key') |
| Any write operation | store.set('key', val) | useAppSet('key') |
| Need both read + write | useAppValue + store.set | useAppState |
import { createAtomStore } from "jotai-x";
export const {
useChatStore, // Get store instance
useChatValue, // Subscribe to value (use sparingly!)
ChatProvider, // Provider component
} = createAtomStore(
{
count: 0,
name: "Alice",
items: [] as string[],
},
{
name: "chat", // Prefix for all hooks
}
);const store = useChatStore();
// Read without subscribing
store.get("count"); // Get single value
store.getCount(); // Alternative syntax
// Write
store.set("count", 5); // Set value
store.set("count", (c) => c + 1); // Update with function
store.setCount(5); // Alternative syntax
// Subscribe (rarely needed - prefer useAppValue)
const unsub = store.subscribe("count", (value) => {
console.log(value);
});// Subscribe to value (component re-renders on change)
const count = useChatValue("count");
// With selector
const firstItem = useChatValue(
"items",
{
selector: (items) => items[0],
},
[]
);
// With equality function
const items = useChatValue(
"items",
{
equalityFn: (a, b) => a.length === b.length,
},
[]
);import { createAtomStore } from "jotai-x";
// 1. Create store
export const { useChatStore, useChatValue, ChatProvider } = createAtomStore(
{
messages: [] as Message[],
input: "",
status: "idle" as "idle" | "loading",
},
{
name: "chat",
}
);
// 2. Custom hook for complex operations
export const useSendMessage = () => {
const store = useChatStore();
return async () => {
// ✅ Use store.get to read without subscribing
const input = store.get("input");
const messages = store.get("messages");
if (!input.trim()) return;
// ✅ Use store.set to write
store.set("status", "loading");
store.set("input", "");
try {
const response = await fetch("/api/chat", {
method: "POST",
body: JSON.stringify({ input, messages }),
});
const newMessage = await response.json();
// ✅ Functional update
store.set("messages", (prev) => [...prev, newMessage]);
store.set("status", "idle");
} catch (error) {
store.set("status", "idle");
console.error(error);
}
};
};
// 3. Component with minimal subscriptions
function ChatMessages() {
// ✅ Subscribe ONLY to what component needs to render
const messages = useChatValue("messages");
const status = useChatValue("status");
return (
<div>
{messages.map((msg) => (
<Message key={msg.id} {...msg} />
))}
{status === "loading" && <LoadingSpinner />}
</div>
);
}
// 4. Component with event handlers
function ChatInput() {
const store = useChatStore();
const sendMessage = useSendMessage();
// ✅ Subscribe to input for controlled input
const input = useChatValue("input");
return (
<form
onSubmit={(e) => {
e.preventDefault();
sendMessage();
}}
>
<input
value={input}
onChange={(e) => {
// ✅ Use store.set directly
store.set("input", e.target.value);
}}
/>
<button
type="submit"
onClick={() => {
// ✅ Can read current value without subscribing
if (store.get("status") === "loading") {
return; // Don't submit while loading
}
}}
>
Send
</button>
</form>
);
}// ❌ WRONG - Creates subscription for no reason
function Component() {
const count = useChatValue("count"); // Subscribes!
const handleClick = () => {
console.log(count); // Uses stale closure
};
}
// ✅ CORRECT - Read when needed
function Component() {
const store = useChatStore();
const handleClick = () => {
console.log(store.get("count")); // Always current
};
}// ❌ WRONG - Over-subscribing
const [count, setCount] = useChatState("count");
// ✅ CORRECT - Subscribe only if component needs reactivity
const count = useChatValue("count");
const store = useChatStore();
// Then use store.set('count', ...) to write// ❌ WRONG - Unnecessary hook call
const setCount = useChatSet("count");
setCount(5);
// ✅ CORRECT - Direct access
const store = useChatStore();
store.set("count", 5);// ❌ WRONG - Component subscribes to everything
function Component() {
const input = useChatValue("input");
const status = useChatValue("status");
const messages = useChatValue("messages");
const error = useChatValue("error");
// But only renders messages and status
return (
<div>
{messages.map((m) => (
<div key={m.id}>{m.text}</div>
))}
{status === "loading" && <Spinner />}
</div>
);
}
// ✅ CORRECT - Subscribe only to what you render
function Component() {
const messages = useChatValue("messages");
const status = useChatValue("status");
// Access input/error with store.get when needed
}| Excuse | Reality |
|---|---|
| "README shows useAppValue, so I should use it" | README shows all features. Use store.get/set for better performance. |
| "Hooks are the React way" | Hooks for reactivity. Store methods for one-time access. Both are React patterns. |
| "store.get/set is more advanced" | Actually simpler - direct access without subscription overhead. |
| "Using hooks everywhere is more consistent" | Consistency at the cost of performance. Each tool for its purpose. |
| "Official docs recommend useAppValue" | Docs show options. Choose based on whether you need subscription. |
| "I need the setter from useAppState" | Use store.set instead - works everywhere, not just in components. |
| "I'll optimize later, hooks for now" | Wrong pattern from start = tech debt. Use store.get/set from beginning. |
| "Getting store adds extra line of code" | One line enables all direct access. More efficient than multiple hooks. |
| "What if I need value multiple times?" | store.get is instant, no overhead. Call it as many times as needed. |
| "Hooks auto-subscribe, don't have to think" | Thinking prevents bugs. Explicit > implicit. Performance > convenience. |
If you see any of these patterns, reconsider:
useAppState anywhere (almost never needed)useAppSet anywhere (use store.set)useAppValue in a callback/event handler (use store.get)useAppValue calls in one component (over-subscribing)useAppValue but never using the returned value in JSX (just use store.get)All of these mean: Switch to store.get or store.set.
Bad pattern (unnecessary subscriptions):
function UserProfile() {
const firstName = useChatValue("firstName");
const lastName = useChatValue("lastName");
const email = useChatValue("email");
const age = useChatValue("age");
// Component re-renders on ANY change to firstName, lastName, email, OR age
return (
<div>
{firstName} {lastName}
</div>
);
}
// Subscribes to 4 atoms, only uses 2 in renderGood pattern (minimal subscriptions):
function UserProfile() {
// Only subscribe to what we render
const firstName = useChatValue("firstName");
const lastName = useChatValue("lastName");
// Access others with store.get when needed in callbacks
const store = useChatStore();
const handleSubmit = () => {
const email = store.get("email");
const age = store.get("age");
// ...
};
return (
<div>
{firstName} {lastName}
</div>
);
}
// Subscribes to 2 atoms, exactly what we render// Custom hook with derived state
export const useChatEmpty = () => {
// ✅ Subscribe only to values used in computation
const status = useChatValue("status");
const messages = useChatValue("messages");
const hasSubmitted = useChatValue("hasSubmitted");
return !hasSubmitted && messages.length === 0 && status === "ready";
};export const useSwitchChat = () => {
const store = useChatStore();
const currentChatId = useChatValue("chatId");
return (chatId: string) => {
if (chatId === currentChatId) return;
// ✅ Multiple writes with store.set
store.set("chatId", chatId);
store.set("newChatId", null);
store.set("status", "syncing");
store.get("actions").setMessages([]);
store.set("hasSubmitted", false);
};
};export const useRetry = () => {
const store = useChatStore();
// ✅ Subscribe only if we need reactivity for computation
const messages = useChatValue("messages");
return async (messageId?: string) => {
const currentIdx = messageId
? messages.findIndex((m) => m.id === messageId)
: messages.findLastIndex((m) => m.role === "assistant");
// ✅ Read values with store.get - no subscription needed
const chatId = store.get("chatId");
const actions = store.get("actions");
// Perform async operation...
await deleteMessages(chatId, messageId);
// ✅ Write with store.set
const newMessages = messages.slice(0, currentIdx);
actions.setMessages(newMessages);
actions.regenerate();
};
};Persist store values to cookies or localStorage by using atomWithCookie or atomWithLocalStorage directly in store definition.
| Storage | Use Case |
|---|---|
| Cookie | Server-side access needed, SSR hydration, small data |
| LocalStorage | Client-only, larger data, no SSR needed |
1. Store definition - Replace primitive with atomWithCookie:
import { atomWithCookie } from "@/lib/utils/atomWithCookie";
export const { useChatStore, useChatValue, ChatProvider } = createAtomStore(
{
isOpen: atomWithCookie("chat_isOpen", true), // ✅ Direct assignment
// ... other state
},
{ name: "chat" }
);2. Server-side hydration - Read cookie and pass to Provider:
// Layout.tsx (Server Component)
import { cookies } from "next/headers";
import { getCookieParser } from "@/lib/utils/getCookieParser";
export async function Layout({ children }) {
const cookieStore = await cookies();
const parser = getCookieParser(cookieStore);
const isOpen = parser.boolean("chat_isOpen") ?? true;
return <ChatProvider initialValues={{ isOpen }}>{children}</ChatProvider>;
}Cookie naming convention: prefix_key (e.g., chat_isOpen, chat_mode)
import { atomWithLocalStorage } from "@/lib/utils/atomWithLocalStorage";
export const { useAppStore, useAppValue, AppProvider } = createAtomStore(
{
theme: atomWithLocalStorage("app_theme", "light"),
// ... other state
},
{ name: "app" }
);No server hydration needed - localStorage is client-only.
// ❌ WRONG - Don't use extend option for persistence
createAtomStore(
{ isOpen: true },
{
name: "chat",
extend: (atoms) => ({ ...atoms, isOpen: someAtom }), // Unnecessary complexity
}
);
// ✅ CORRECT - Direct assignment
createAtomStore({ isOpen: atomWithCookie("chat_isOpen", true) }, { name: "chat" });
// ❌ WRONG - Forgetting server hydration with cookies
<ChatProvider initialValues={{}}> // Cookie value ignored on first render
// ✅ CORRECT - Pass server-read value
<ChatProvider initialValues={{ isOpen }}> // Hydrated from cookie© udecode, Apache-2.0. 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 .agents/skills/jotai-x of udecode/kitcn.
Open the folder on GitHubat commit c6010f5
Jotai X 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 |
|---|---|---|---|---|---|---|
| Jotai X this skilludecode/kitcn | 451 | — | ~3.7k | Automated safety check: Pass | Apache-2.0 | |
| Accessibilityaffaan-m/ECC | 276k | 1 repos | ~1.6k | Automated safety check: Pass | MIT | |
| Accessibilityaffaan-m/ECC | 276k | — | ~1.2k | Automated safety check: Pass | MIT | |
| Accessibilityaffaan-m/ECC | 276k | — | ~1k | Automated safety check: Pass | MIT | |
| Accessibilityelastic/kibana | 21k | — | ~338 | Automated safety check: Pass | Custom licence | |
| Accessible Notificationsthedaviddias/Front-End-Checklist | 74k | — | ~438 | Automated safety check: Pass | MIT |
affaan-m/ECC
Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels, accessibility traits and hints, focus management, contrast, target…
affaan-m/ECC
WCAG 2.2 レベル AA 標準を用いてインクルーシブなデジタルプロダクトを設計・実装・監査します。Web 用のセマンティック ARIA および Web・ネイティブプラットフォーム(iOS/Android)のアクセシビリティトレイトを生成するために使用します。
affaan-m/ECC
使用 WCAG 2.2 Level AA 标准设计、实施和审计包容性数字产品。运用此技能为 Web 生成语义 ARIA,并为 Web 和原生平台(iOS/Android)生成无障碍特性。
elastic/kibana
Accessibility guidance for Kibana. An agent skill from elastic/kibana.
thedaviddias/Front-End-Checklist
A skill your agent uses when reviewing templates, rendered HTML, or shared components related to Make notifications accessible.
thedaviddias/Front-End-Checklist
A skill your agent uses when reviewing templates, rendered HTML, or shared components related to Create accessible tooltips.
udecode/kitcn
Create a short annotated visual walkthrough from real final-state screenshots or rendered artifacts.
udecode/kitcn
Prevent feature creep when building software, apps, and AI-powered products.
udecode/kitcn
Repair an unreleased .changeset/.md file so it matches the real branch delta against main.
udecode/kitcn
Audit newer Convex npm releases against kitcn. An agent skill from udecode/kitcn.
udecode/kitcn
Run a scoped Linear backlog autonomously as a sequence of maximal safe parallel batches by composing orchestrator, autogoal, and task.
udecode/kitcn
Next.js routing with typed routes, PageProps, LayoutProps helpers, and nuqs for URL state.
A skill your agent uses when working with Jotai X stores (createAtomStore), accessing state in components or callbacks, persisting state to cookies or localStorage. Jotai X is an agent skill from udecode/kitcn.
Jotai X fits situations like: working with Jotai X stores (createAtomStore); accessing state in components; persisting state to cookies.
Run `npx skills add udecode/kitcn --skill jotai-x -a claude-code`. Or copy the skill folder (.agents/skills/jotai-x in udecode/kitcn) into .claude/skills/jotai-x in your project. Claude Code loads it when a task matches its description.
Run `npx skills add udecode/kitcn --skill jotai-x -a codex`. Or copy the skill folder (.agents/skills/jotai-x in udecode/kitcn) into .agents/skills/jotai-x 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 udecode/kitcn --skill jotai-x -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/jotai-x, .gemini/skills/jotai-x, .github/skills/jotai-x and .opencode/skills/jotai-x in your project.
SKILL.md names no scripts, command-line tools or credentials: Jotai X is instructions for the agent only.
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.
Jotai X is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.7k tokens (SKILL.md is roughly 15k 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 Jotai X: Accessibility (affaan-m/ECC, 276k stars), Accessibility (affaan-m/ECC, 276k stars), Accessibility (affaan-m/ECC, 276k stars) and Accessibility (elastic/kibana, 21k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
udecode (a GitHub organization) maintains it in udecode/kitcn, which has 451 GitHub stars. The repository holds 33 skills in this directory. The repository was last updated on October 1, 2026.
Source: udecode/kitcn on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.